diff --git a/AUTHORS b/AUTHORS
index 4f8475f..46b733a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -637,6 +637,7 @@
 Marc des Garets <marc.desgarets@googlemail.com>
 Marcin Wiacek <marcin@mwiacek.com>
 Marco Rodrigues <gothicx@gmail.com>
+Mariam Ali <alimariam@noogler.google.com>
 Mario Pistrich <m.pistrich@gmail.com>
 Mario Sanchez Prada <mario.prada@samsung.com>
 Mariusz Mlynski <marius.mlynski@gmail.com>
diff --git a/DEPS b/DEPS
index 4c6d782a..cdf83d7 100644
--- a/DEPS
+++ b/DEPS
@@ -195,11 +195,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '093de4eb2ca92dfb479aa5f431127816b53ff43a',
+  'skia_revision': '471235dba5caba46fe1599d458e7af0e7d82fe6e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '2b884e02be1a184ce9c40742fb80261e86779b08',
+  'v8_revision': '8640f363b890c6459a5b636cef24a164d80a5913',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -207,7 +207,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '709472c9dd0c413ceb944e06afb600d741e63720',
+  'angle_revision': '26d2e0461340a8268784d5a0ef440ba5c0b72d00',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -215,7 +215,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'f045cb21c570b9feb65b7e02c54d0b2cf096a513',
+  'pdfium_revision': 'fa9a15cb008b433d1c696fd779c025e301020a35',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -258,7 +258,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': 'ce6a663ce5774b2952c54c7b5630709f65f3a77e',
+  'catapult_revision': 'cf93e1de9eb8b7073397eb5aac874fd67e06b1a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -266,7 +266,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '1e1d958fbd8d80c451444089c094f3104a770a37',
+  'devtools_frontend_revision': 'bb22c1539f01c02985b0b116cebde2143c0e1b75',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -318,7 +318,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '1ea3a22f521ef0e0c7ed4ba9f41ac56b5157a7f0',
+  'dawn_revision': 'c0acb25318013bb10ee4fd6b3961316e76cf310a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -895,7 +895,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6c7b829e54738b0f532871b9f6dde15cf2c05373',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4fdf56254f586f8a541f2a364698d5a7706d1eb1',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -946,7 +946,7 @@
     Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'e46493b9148e0d1e63f55b5890bff503822616e5',
 
   'src/third_party/glslang/src':
-    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '5743eed4d16757402517a1068137f4bc1645ee87',
+    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'f881f08358b098b8bd1e3b402ab35b5177aa76b9',
 
   'src/third_party/google_toolbox_for_mac/src': {
       'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
@@ -1248,7 +1248,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9a482652ab182496ba1ea2d3f391b187f5ff80f7',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd14d99cd75b8ec9f83cc738b3162c3fff0b74ef1',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1537,7 +1537,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7eb25ea3b96d17cbcc67a9285b3f7bf14bbd9f39',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4b615359085761bfab0761dab9a655fd60737a2d',
     'condition': 'checkout_src_internal',
   },
 
@@ -2417,6 +2417,17 @@
       'dep_type': 'cipd',
   },
 
+  'src/third_party/android_deps/libs/androidx_webkit_webkit': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_webkit_webkit',
+              'version': 'version:1.3.0-rc01-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   'src/third_party/android_deps/libs/backport_util_concurrent_backport_util_concurrent': {
       'packages': [
           {
diff --git a/WATCHLISTS b/WATCHLISTS
index 8cc6a9b..02bfdad 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -378,9 +378,6 @@
     'blink_dom': {
       'filepath': 'third_party/blink/renderer/core/dom/'
     },
-    'blink_dom_events': {
-      'filepath': 'third_party/blink/renderer/core/dom/events/'
-    },
     'blink_dom_storage': {
       'filepath': 'third_party/blink/common/dom_storage/|' \
                   'third_party/blink/public/mojom/dom_storage/|' \
@@ -567,12 +564,6 @@
       'filepath': 'third_party/blink/web_tests/http/tests/serviceworker' \
                   '|third_party/blink/web_tests/external/wpt/service-workers'
     },
-    'blink_shadow_dom': {
-      'filepath': 'third_party/blink/renderer/core/dom/.*shadow' \
-                  '|third_party/blink/renderer/core/dom/.*slot' \
-                  '|third_party/blink/renderer/core/dom/.*insertion_point' \
-                  '|third_party/blink/renderer/core/dom/.*flat_tree'
-    },
     'blink_spellcheck' : {
       'filepath': 'third_party/blink/renderer/core/editing/spellcheck'
     },
@@ -2215,7 +2206,6 @@
     'blink_devtools': ['devtools-reviews+blink@chromium.org'],
     'blink_dom': ['blink-reviews-dom@chromium.org',
                   'eae+blinkwatch@chromium.org'],
-    'blink_dom_events': ['hayato+watch@chromium.org'],
     'blink_dom_storage': ['dmurph+watching-domstorage@chromium.org'],
     'blink_events': ['blink-reviews-events@chromium.org',
                      'dtapuska+blinkwatch@chromium.org',
@@ -2290,7 +2280,6 @@
                              'serviceworker-reviews@chromium.org',
                              'shimazu+serviceworker@chromium.org'],
     'blink_service_worker_tests': ['kenjibaheux+watch@chromium.org'],
-    'blink_shadow_dom': ['hayato+watch@chromium.org'],
     'blink_spellcheck' : ['timvolodine@chromium.org',
                           'xiaochengh+watch@chromium.org'],
     'blink_streams': ['ricea+watch@chromium.org'],
diff --git a/android_webview/tools/system_webview_shell/BUILD.gn b/android_webview/tools/system_webview_shell/BUILD.gn
index 815a005..c1026dba 100644
--- a/android_webview/tools/system_webview_shell/BUILD.gn
+++ b/android_webview/tools/system_webview_shell/BUILD.gn
@@ -55,6 +55,7 @@
     "//third_party/android_deps:androidx_activity_activity_java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
     "//third_party/android_deps:androidx_savedstate_savedstate_java",
+    "//third_party/android_deps:androidx_webkit_webkit_java",
     "//third_party/guava:guava_android_java",
   ]
 }
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/JankActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/JankActivity.java
index a508e440..50ef8c7 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/JankActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/JankActivity.java
@@ -9,7 +9,8 @@
 import android.os.Bundle;
 import android.webkit.CookieManager;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
+
+import androidx.webkit.WebViewClientCompat;
 
 /**
  * This activity is designed for Android Jank testing of WebView. It takes a URL as an argument, and
@@ -27,7 +28,7 @@
         WebView webView = (WebView) findViewById(R.id.webview);
         CookieManager.setAcceptFileSchemeCookies(true);
 
-        webView.setWebViewClient(new WebViewClient() {
+        webView.setWebViewClient(new WebViewClientCompat() {
             @SuppressWarnings("deprecation") // because we support api level 19 and up.
             @Override
             public boolean shouldOverrideUrlLoading(WebView webView, String url) {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryActivity.java
index 7128202..6a97516 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryActivity.java
@@ -10,7 +10,8 @@
 import android.webkit.CookieManager;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
+
+import androidx.webkit.WebViewClientCompat;
 
 /**
  * This activity is designed for Telemetry testing of WebView.
@@ -70,7 +71,7 @@
             settings.setUserAgentString(userAgentString);
         }
 
-        webView.setWebViewClient(new WebViewClient() {
+        webView.setWebViewClient(new WebViewClientCompat() {
             @SuppressWarnings("deprecation") // because we support api level 19 and up.
             @Override
             public boolean shouldOverrideUrlLoading(WebView view, String url) {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryMemoryPressureActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryMemoryPressureActivity.java
index 1ebd056c..b9a39d58 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryMemoryPressureActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/TelemetryMemoryPressureActivity.java
@@ -9,7 +9,8 @@
 import android.os.Bundle;
 import android.webkit.CookieManager;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
+
+import androidx.webkit.WebViewClientCompat;
 
 import org.chromium.base.Log;
 import org.chromium.base.MemoryPressureListener;
@@ -32,7 +33,7 @@
         CookieManager.setAcceptFileSchemeCookies(true);
         webview.getSettings().setJavaScriptEnabled(true);
 
-        webview.setWebViewClient(new WebViewClient() {
+        webview.setWebViewClient(new WebViewClientCompat() {
             @SuppressWarnings("deprecation") // because we support api level 19 and up.
             @Override
             public boolean shouldOverrideUrlLoading(WebView webView, String url) {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebPlatformTestsActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebPlatformTestsActivity.java
index 710a343..04f443f 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebPlatformTestsActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebPlatformTestsActivity.java
@@ -14,13 +14,13 @@
 import android.webkit.WebChromeClient;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
 import android.widget.Button;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.webkit.WebViewClientCompat;
 
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
@@ -65,7 +65,7 @@
             WebView childWebView = createChildLayoutAndGetNewWebView(parentWebView);
             WebSettings settings = childWebView.getSettings();
             setUpWebSettings(settings);
-            childWebView.setWebViewClient(new WebViewClient() {
+            childWebView.setWebViewClient(new WebViewClientCompat() {
                 @Override
                 public void onPageFinished(WebView childWebView, String url) {
                     if (DEBUG) Log.i(TAG, "onPageFinished");
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
index fa18899f..090bfc08 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -39,12 +39,9 @@
 import android.webkit.CookieManager;
 import android.webkit.GeolocationPermissions;
 import android.webkit.PermissionRequest;
-import android.webkit.TracingConfig;
-import android.webkit.TracingController;
 import android.webkit.WebChromeClient;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.TextView;
@@ -52,6 +49,11 @@
 
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.appcompat.widget.Toolbar;
+import androidx.webkit.TracingConfig;
+import androidx.webkit.TracingController;
+import androidx.webkit.WebSettingsCompat;
+import androidx.webkit.WebViewClientCompat;
+import androidx.webkit.WebViewFeature;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
@@ -360,7 +362,7 @@
         getSupportActionBar().setTitle(getResources().getString(R.string.title_activity_browser));
         getSupportActionBar().setSubtitle(mWebViewVersion);
 
-        webview.setWebViewClient(new WebViewClient() {
+        webview.setWebViewClient(new WebViewClientCompat() {
             @Override
             public void onPageStarted(WebView view, String url, Bitmap favicon) {
                 setUrlFail(false);
@@ -537,10 +539,10 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.main_menu, menu);
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+        if (!WebViewFeature.isFeatureSupported(WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE)) {
             menu.findItem(R.id.menu_enable_tracing).setEnabled(false);
         }
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+        if (!WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
             menu.findItem(R.id.menu_force_dark_off).setEnabled(false);
             menu.findItem(R.id.menu_force_dark_auto).setEnabled(false);
             menu.findItem(R.id.menu_force_dark_on).setEnabled(false);
@@ -550,19 +552,19 @@
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+        if (WebViewFeature.isFeatureSupported(WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE)) {
             menu.findItem(R.id.menu_enable_tracing).setChecked(mEnableTracing);
         }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-            int fdState = mWebView.getSettings().getForceDark();
-            switch (fdState) {
-                case WebSettings.FORCE_DARK_OFF:
+        if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
+            int forceDarkState = WebSettingsCompat.getForceDark(mWebView.getSettings());
+            switch (forceDarkState) {
+                case WebSettingsCompat.FORCE_DARK_OFF:
                     menu.findItem(R.id.menu_force_dark_off).setChecked(true);
                     break;
-                case WebSettings.FORCE_DARK_AUTO:
+                case WebSettingsCompat.FORCE_DARK_AUTO:
                     menu.findItem(R.id.menu_force_dark_auto).setChecked(true);
                     break;
-                case WebSettings.FORCE_DARK_ON:
+                case WebSettingsCompat.FORCE_DARK_ON:
                     menu.findItem(R.id.menu_force_dark_on).setChecked(true);
                     break;
             }
@@ -571,7 +573,6 @@
     }
 
     @Override
-    @SuppressLint("NewApi") // TracingController related methods require API level 28.
     public boolean onOptionsItemSelected(MenuItem item) {
         switch(item.getItemId()) {
             case R.id.menu_reset_webview:
@@ -592,7 +593,6 @@
                 mEnableTracing = !mEnableTracing;
                 item.setChecked(mEnableTracing);
 
-                // TODO(laisminchillo): replace this with AndroidX's TracingController
                 TracingController tracingController = TracingController.getInstance();
                 if (mEnableTracing) {
                     tracingController.start(
@@ -613,15 +613,18 @@
                 }
                 return true;
             case R.id.menu_force_dark_off:
-                mWebView.getSettings().setForceDark(WebSettings.FORCE_DARK_OFF);
+                WebSettingsCompat.setForceDark(
+                        mWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
                 item.setChecked(true);
                 return true;
             case R.id.menu_force_dark_auto:
-                mWebView.getSettings().setForceDark(WebSettings.FORCE_DARK_AUTO);
+                WebSettingsCompat.setForceDark(
+                        mWebView.getSettings(), WebSettingsCompat.FORCE_DARK_AUTO);
                 item.setChecked(true);
                 return true;
             case R.id.menu_force_dark_on:
-                mWebView.getSettings().setForceDark(WebSettings.FORCE_DARK_ON);
+                WebSettingsCompat.setForceDark(
+                        mWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
                 item.setChecked(true);
                 return true;
             case R.id.start_animation_activity:
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewCreateDestroyActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewCreateDestroyActivity.java
index 5076a542..7abbfcad 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewCreateDestroyActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewCreateDestroyActivity.java
@@ -11,9 +11,10 @@
 import android.view.ViewGroup;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
 import android.widget.RelativeLayout;
 
+import androidx.webkit.WebViewClientCompat;
+
 /**
  * This activity always has at most one live webview. Any previously exisisting
  * webview instance is destroyed first before creating a new one. This activity
@@ -62,7 +63,7 @@
         webSettings.setUseWideViewPort(true);
         webSettings.setLoadWithOverviewMode(true);
 
-        sWebView.setWebViewClient(new WebViewClient() {
+        sWebView.setWebViewClient(new WebViewClientCompat() {
             @SuppressWarnings("deprecation") // because we support api level 19 and up.
             @Override
             public boolean shouldOverrideUrlLoading(WebView view, String url) {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
index bf84d11..8b8c91e4 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
@@ -14,7 +14,8 @@
 import android.webkit.WebChromeClient;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
+
+import androidx.webkit.WebViewClientCompat;
 
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -43,7 +44,7 @@
         WebSettings settings = mWebView.getSettings();
         initializeSettings(settings);
 
-        mWebView.setWebViewClient(new WebViewClient() {
+        mWebView.setWebViewClient(new WebViewClientCompat() {
             @SuppressWarnings("deprecation") // because we support api level 19 and up.
             @Override
             public boolean shouldOverrideUrlLoading(WebView webView, String url) {
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java
index 8f0c26b8..5013472c 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewTracingActivity.java
@@ -4,16 +4,16 @@
 
 package org.chromium.webview_shell;
 
-import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.SystemClock;
-import android.webkit.TracingConfig;
-import android.webkit.TracingController;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.WebViewClient;
+
+import androidx.webkit.TracingConfig;
+import androidx.webkit.TracingController;
+import androidx.webkit.WebViewClientCompat;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -91,7 +91,6 @@
         loadUrl(url, enableTracing);
     }
 
-    @SuppressLint("NewApi") // TracingController related methods require API level 28.
     private void loadUrl(final String url, boolean enableTracing) {
         final Activity activity = this;
         WebView webView = new WebView(this);
@@ -100,8 +99,7 @@
         settings.setJavaScriptEnabled(true);
         final TracingController tracingController = TracingController.getInstance();
 
-        webView.setWebViewClient(new WebViewClient() {
-            @SuppressLint("NewApi") // TracingController related methods require API level 28.
+        webView.setWebViewClient(new WebViewClientCompat() {
             @Override
             public void onPageFinished(WebView view, String url) {
                 super.onPageFinished(view, url);
diff --git a/ash/accessibility/spoken_feedback_enabler.cc b/ash/accessibility/spoken_feedback_enabler.cc
index ed68fb1..8c2f350 100644
--- a/ash/accessibility/spoken_feedback_enabler.cc
+++ b/ash/accessibility/spoken_feedback_enabler.cc
@@ -32,7 +32,7 @@
 
 void SpokenFeedbackEnabler::OnTimer() {
   base::TimeTicks now = ui::EventTimeForNow();
-  double tick_count_f = (now - start_time_).FltDiv(kTimerDelay);
+  double tick_count_f = (now - start_time_) / kTimerDelay;
   int tick_count = roundf(tick_count_f);
 
   AccessibilityControllerImpl* controller =
diff --git a/ash/app_list/views/expand_arrow_view.cc b/ash/app_list/views/expand_arrow_view.cc
index 1b416f5..84517e7 100644
--- a/ash/app_list/views/expand_arrow_view.cc
+++ b/ash/app_list/views/expand_arrow_view.cc
@@ -323,15 +323,15 @@
     pulse_opacity_ =
         kPulseMinOpacity +
         (kPulseMaxOpacity - kPulseMinOpacity) *
-            (time - kPulseOpacityShowBeginTime)
-                .FltDiv(kPulseOpacityShowEndTime - kPulseOpacityShowBeginTime);
+            (time - kPulseOpacityShowBeginTime) /
+            (kPulseOpacityShowEndTime - kPulseOpacityShowBeginTime);
   } else if (time > kPulseOpacityHideBeginTime &&
              time <= kPulseOpacityHideEndTime) {
     pulse_opacity_ =
         kPulseMaxOpacity -
         (kPulseMaxOpacity - kPulseMinOpacity) *
-            (time - kPulseOpacityHideBeginTime)
-                .FltDiv(kPulseOpacityHideEndTime - kPulseOpacityHideBeginTime);
+            (time - kPulseOpacityHideBeginTime) /
+            (kPulseOpacityHideEndTime - kPulseOpacityHideBeginTime);
   }
 
   // Update pulse radius.
diff --git a/ash/metrics/demo_session_metrics_recorder.cc b/ash/metrics/demo_session_metrics_recorder.cc
index 36515a9..d4f7bf82 100644
--- a/ash/metrics/demo_session_metrics_recorder.cc
+++ b/ash/metrics/demo_session_metrics_recorder.cc
@@ -42,7 +42,7 @@
 // recorded samples for a full minute while the device is in between uses, we
 // would bias our measurements toward whatever app was used last.
 constexpr int kMaxPeriodsWithoutActivity =
-    base::TimeDelta::FromSeconds(15).FltDiv(kSamplePeriod);
+    base::TimeDelta::FromSeconds(15) / kSamplePeriod;
 
 // Maps a Chrome app ID to a DemoModeApp value for metrics.
 DemoModeApp GetAppFromAppId(const std::string& app_id) {
diff --git a/ash/public/cpp/holding_space/holding_space_controller.cc b/ash/public/cpp/holding_space/holding_space_controller.cc
index 8f844b0..eebe7d0 100644
--- a/ash/public/cpp/holding_space/holding_space_controller.cc
+++ b/ash/public/cpp/holding_space/holding_space_controller.cc
@@ -5,6 +5,7 @@
 #include "ash/public/cpp/holding_space/holding_space_controller.h"
 
 #include "ash/public/cpp/holding_space/holding_space_controller_observer.h"
+#include "ash/public/cpp/session/session_controller.h"
 #include "base/check.h"
 
 namespace ash {
@@ -18,6 +19,8 @@
 HoldingSpaceController::HoldingSpaceController() {
   CHECK(!g_instance);
   g_instance = this;
+
+  SessionController::Get()->AddObserver(this);
 }
 
 HoldingSpaceController::~HoldingSpaceController() {
@@ -25,6 +28,8 @@
 
   SetModel(nullptr);
   g_instance = nullptr;
+
+  SessionController::Get()->RemoveObserver(this);
 }
 
 // static
@@ -42,6 +47,13 @@
   observers_.RemoveObserver(observer);
 }
 
+void HoldingSpaceController::RegisterModelForUser(const AccountId& account_id,
+                                                  HoldingSpaceModel* model) {
+  models_by_account_id_[account_id] = model;
+  if (account_id == active_user_account_id_)
+    SetModel(model);
+}
+
 void HoldingSpaceController::SetModel(HoldingSpaceModel* model) {
   if (model_) {
     for (auto& observer : observers_)
@@ -56,4 +68,16 @@
   }
 }
 
+void HoldingSpaceController::OnActiveUserSessionChanged(
+    const AccountId& account_id) {
+  active_user_account_id_ = account_id;
+
+  auto model_it = models_by_account_id_.find(account_id);
+  if (model_it == models_by_account_id_.end()) {
+    SetModel(nullptr);
+    return;
+  }
+  SetModel(model_it->second);
+}
+
 }  // namespace ash
diff --git a/ash/public/cpp/holding_space/holding_space_controller.h b/ash/public/cpp/holding_space/holding_space_controller.h
index 8330cba..a5ab404 100644
--- a/ash/public/cpp/holding_space/holding_space_controller.h
+++ b/ash/public/cpp/holding_space/holding_space_controller.h
@@ -6,24 +6,27 @@
 #define ASH_PUBLIC_CPP_HOLDING_SPACE_HOLDING_SPACE_CONTROLLER_H_
 
 #include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/cpp/session/session_observer.h"
 #include "base/observer_list.h"
+#include "components/account_id/account_id.h"
 
 namespace ash {
 
 class HoldingSpaceControllerObserver;
 class HoldingSpaceModel;
 
-// Keeps track of the currentily active holding space model.
+// Keeps track of all registered holding space models per user account and makes
+// sure the current active model belongs to the current active user.
 // There is expected to exist at most one instance of this class at a time. In
 // production the instance is owned by ash::Shell. The instance can be retrieved
 // using HoldingSpaceController::Get().
-class ASH_PUBLIC_EXPORT HoldingSpaceController {
+class ASH_PUBLIC_EXPORT HoldingSpaceController : public SessionObserver {
  public:
   HoldingSpaceController();
   HoldingSpaceController(const HoldingSpaceController& other) = delete;
   HoldingSpaceController& operator=(const HoldingSpaceController& other) =
       delete;
-  ~HoldingSpaceController();
+  ~HoldingSpaceController() override;
 
   // Returns the global HoldingSpaceController instance. It's set in the
   // HoldingSpaceController constructor, and reset in the destructor. The
@@ -33,16 +36,28 @@
   void AddObserver(HoldingSpaceControllerObserver* observer);
   void RemoveObserver(HoldingSpaceControllerObserver* observer);
 
+  // Adds a model to it's corresponding user account id in a map.
+  void RegisterModelForUser(const AccountId& account_id,
+                            HoldingSpaceModel* model);
+
   // Sets the active model - the caller is expected to maintain the ownership.
   void SetModel(HoldingSpaceModel* model);
 
   HoldingSpaceModel* model() { return model_; }
 
+  // SessionObserver:
+  void OnActiveUserSessionChanged(const AccountId& account_id) override;
+
  private:
   // The currently active holding space model, set by SetModel(). The client
   // that sets the model is expected to maintain the model ownership.
   HoldingSpaceModel* model_ = nullptr;
 
+  // The currently active user account id.
+  AccountId active_user_account_id_;
+
+  std::map<const AccountId, HoldingSpaceModel*> models_by_account_id_;
+
   base::ObserverList<HoldingSpaceControllerObserver> observers_;
 };
 
diff --git a/ash/shell.cc b/ash/shell.cc
index 1471f67..b50d45f 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -858,6 +858,10 @@
   // Destroys the MessageCenter singleton, so must happen late.
   message_center_controller_.reset();
 
+  // HoldingSpaceController observes SessionController and must be
+  // destructed before it.
+  holding_space_controller_.reset();
+
   ash_color_provider_.reset();
 
   shell_delegate_.reset();
diff --git a/base/test/test_file_util.cc b/base/test/test_file_util.cc
index 8dafc58a..5b211c4 100644
--- a/base/test/test_file_util.cc
+++ b/base/test/test_file_util.cc
@@ -4,11 +4,72 @@
 
 #include "base/test/test_file_util.h"
 
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
+#include "base/threading/thread_restrictions.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
+namespace {
+
+constexpr FilePath::CharType kDirPrefix[] =
+    FILE_PATH_LITERAL("test_scoped_temp_dir");
+
+// Deletes all registered file paths upon test completion. There can only be
+// one instance at a time.
+class PathDeleterOnTestEnd : public testing::EmptyTestEventListener {
+ public:
+  PathDeleterOnTestEnd() {
+    DCHECK(!instance_);
+    instance_ = this;
+  }
+
+  ~PathDeleterOnTestEnd() override {
+    DCHECK_EQ(instance_, this);
+    instance_ = nullptr;
+  }
+
+  PathDeleterOnTestEnd(const PathDeleterOnTestEnd&) = delete;
+  PathDeleterOnTestEnd& operator=(const PathDeleterOnTestEnd&) = delete;
+
+  static PathDeleterOnTestEnd* GetInstance() { return instance_; }
+
+  void DeletePathRecursivelyUponTestEnd(const FilePath& path) {
+    file_paths_to_delete_.push_back(path);
+  }
+
+  // EmptyTestEventListener overrides.
+  void OnTestEnd(const testing::TestInfo& test_info) override {
+    if (file_paths_to_delete_.empty()) {
+      // Nothing to delete since the last test ended.
+      return;
+    }
+
+    ScopedAllowBlockingForTesting allow_blocking;
+    for (const FilePath& file_path : file_paths_to_delete_) {
+      if (!DieFileDie(file_path, /*recurse=*/true)) {
+        ADD_FAILURE() << "Failed to delete temporary directory for testing: "
+                      << file_path;
+      }
+    }
+    file_paths_to_delete_.clear();
+  }
+
+ private:
+  static PathDeleterOnTestEnd* instance_;
+  std::vector<FilePath> file_paths_to_delete_;
+};
+
+// static
+PathDeleterOnTestEnd* PathDeleterOnTestEnd::instance_ = nullptr;
+
+}  // namespace
+
 bool EvictFileFromSystemCacheWithRetry(const FilePath& path) {
   const int kCycles = 10;
   const TimeDelta kDelay = TestTimeouts::action_timeout() / kCycles;
@@ -20,4 +81,26 @@
   return false;
 }
 
+FilePath CreateUniqueTempDirectoryScopedToTest() {
+  ScopedAllowBlockingForTesting allow_blocking;
+  FilePath path;
+  if (!CreateNewTempDirectory(kDirPrefix, &path)) {
+    ADD_FAILURE() << "Failed to create unique temporary directory for testing.";
+    return FilePath();
+  }
+
+  if (!PathDeleterOnTestEnd::GetInstance()) {
+    // Append() transfers ownership of the listener. This means
+    // PathDeleterOnTestEnd::GetInstance() will return non-null until all tests
+    // are run and the test suite destroyed.
+    testing::UnitTest::GetInstance()->listeners().Append(
+        new PathDeleterOnTestEnd());
+    DCHECK(PathDeleterOnTestEnd::GetInstance());
+  }
+
+  PathDeleterOnTestEnd::GetInstance()->DeletePathRecursivelyUponTestEnd(path);
+
+  return path;
+}
+
 }  // namespace base
diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h
index f9951b0..17a7f69 100644
--- a/base/test/test_file_util.h
+++ b/base/test/test_file_util.h
@@ -37,6 +37,11 @@
 // success.
 bool DieFileDie(const FilePath& file, bool recurse);
 
+// Creates a a new unique directory and returns the generated path. The
+// directory will be automatically deleted when the test completes. Failure
+// upon creation or deletion will cause a test failure.
+FilePath CreateUniqueTempDirectoryScopedToTest();
+
 // Synchronize all the dirty pages from the page cache to disk (on POSIX
 // systems). The Windows analogy for this operation is to 'Flush file buffers'.
 // Note: This is currently implemented as a no-op on Windows.
diff --git a/base/threading/scoped_blocking_call_internal.cc b/base/threading/scoped_blocking_call_internal.cc
index 790a4bb..8a035e8 100644
--- a/base/threading/scoped_blocking_call_internal.cc
+++ b/base/threading/scoped_blocking_call_internal.cc
@@ -198,12 +198,12 @@
   // Begin attributing jank to the first interval in which it appeared, no
   // matter how far into the interval the jank began.
   const int jank_start_index =
-      (call_start - start_time_).IntDiv(kIOJankInterval);
+      ClampFloor((call_start - start_time_) / kIOJankInterval);
 
   // Round the jank duration so the total number of intervals marked janky is as
   // close as possible to the actual jank duration.
   const int num_janky_intervals =
-      ClampRound((call_end - call_start).FltDiv(kIOJankInterval));
+      ClampRound((call_end - call_start) / kIOJankInterval);
 
   AddJank(jank_start_index, num_janky_intervals);
 }
diff --git a/base/threading/scoped_blocking_call_internal.h b/base/threading/scoped_blocking_call_internal.h
index 722d72fd..73ba481 100644
--- a/base/threading/scoped_blocking_call_internal.h
+++ b/base/threading/scoped_blocking_call_internal.h
@@ -91,8 +91,7 @@
   static constexpr TimeDelta kIOJankInterval = TimeDelta::FromSeconds(1);
   static constexpr TimeDelta kMonitoringWindow = TimeDelta::FromMinutes(1);
   static constexpr TimeDelta kTimeDiscrepancyTimeout = kIOJankInterval * 10;
-  static constexpr int kNumIntervals =
-      kMonitoringWindow.FltDiv(kIOJankInterval);
+  static constexpr int kNumIntervals = kMonitoringWindow / kIOJankInterval;
 
  private:
   friend class base::RefCountedThreadSafe<IOJankMonitoringWindow>;
diff --git a/base/time/time.h b/base/time/time.h
index 8ac07f9..3b6f6c4 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -297,21 +297,11 @@
     return *this = (*this / a);
   }
 
-  constexpr int64_t operator/(TimeDelta a) const = delete;
-  constexpr int64_t IntDiv(TimeDelta a) const {
-    if (!is_inf() && !a.is_zero())
-      return delta_ / a.delta_;
-
-    // 0/0 and inf/inf (any combination of positive and negative) are invalid
-    // (they are almost certainly not intentional, and result in NaN, which
-    // turns into 0 if clamped to an integer; this makes introducing subtle bugs
-    // too easy).
-    CHECK((!is_zero() || !a.is_zero()) && (!is_inf() || !a.is_inf()));
-    return ((delta_ < 0) == (a.delta_ < 0))
-               ? std::numeric_limits<int64_t>::max()
-               : std::numeric_limits<int64_t>::min();
-  }
-  constexpr double FltDiv(TimeDelta a) const {
+  // This does floating-point division. For an integer result, either call
+  // IntDiv(), or (possibly clearer) use this operator with
+  // base::Clamp{Ceil,Floor,Round}() or base::saturated_cast() (for truncation).
+  // Note that converting to double here drops precision to 53 bits.
+  constexpr double operator/(TimeDelta a) const {
     // 0/0 and inf/inf (any combination of positive and negative) are invalid
     // (they are almost certainly not intentional, and result in NaN, which
     // turns into 0 if clamped to an integer; this makes introducing subtle bugs
@@ -320,6 +310,17 @@
 
     return ToDouble() / a.ToDouble();
   }
+  constexpr int64_t IntDiv(TimeDelta a) const {
+    if (!is_inf() && !a.is_zero())
+      return delta_ / a.delta_;
+
+    // For consistency, use the same edge case CHECKs and behavior as the code
+    // above.
+    CHECK((!is_zero() || !a.is_zero()) && (!is_inf() || !a.is_inf()));
+    return ((delta_ < 0) == (a.delta_ < 0))
+               ? std::numeric_limits<int64_t>::max()
+               : std::numeric_limits<int64_t>::min();
+  }
 
   constexpr TimeDelta operator%(TimeDelta a) const {
     return TimeDelta(a.is_inf() ? delta_ : (delta_ % a.delta_));
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index 8244c9a6..617616d 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -1777,10 +1777,10 @@
                 "");
   static_assert(TimeDelta::FromSeconds(-8) == kThreeSeconds - kElevenSeconds,
                 "");
+  static_assert(11.0 / 3.0 == kElevenSeconds / kThreeSeconds, "");
+  static_assert(3.0 / 11.0 == kThreeSeconds / kElevenSeconds, "");
   static_assert(3 == kElevenSeconds.IntDiv(kThreeSeconds), "");
   static_assert(0 == kThreeSeconds.IntDiv(kElevenSeconds), "");
-  static_assert(11.0 / 3.0 == kElevenSeconds.FltDiv(kThreeSeconds), "");
-  static_assert(3.0 / 11.0 == kThreeSeconds.FltDiv(kElevenSeconds), "");
   static_assert(TimeDelta::FromSeconds(2) == kElevenSeconds % kThreeSeconds,
                 "");
 }
@@ -1816,6 +1816,18 @@
   EXPECT_TRUE((kLargeDelta / 0.5).is_max());
   EXPECT_TRUE((kLargeDelta / -0.5).is_min());
 
+  static_assert(TimeDelta::Max() / TimeDelta::FromSeconds(10) ==
+                    std::numeric_limits<double>::infinity(),
+                "");
+  static_assert(TimeDelta::Max() / TimeDelta::FromSeconds(-10) ==
+                    -std::numeric_limits<double>::infinity(),
+                "");
+  static_assert(TimeDelta::Min() / TimeDelta::FromSeconds(10) ==
+                    -std::numeric_limits<double>::infinity(),
+                "");
+  static_assert(TimeDelta::Min() / TimeDelta::FromSeconds(-10) ==
+                    std::numeric_limits<double>::infinity(),
+                "");
   static_assert(TimeDelta::Max().IntDiv(TimeDelta::FromSeconds(10)) ==
                     std::numeric_limits<int64_t>::max(),
                 "");
@@ -1828,24 +1840,20 @@
   static_assert(TimeDelta::Min().IntDiv(TimeDelta::FromSeconds(-10)) ==
                     std::numeric_limits<int64_t>::max(),
                 "");
-  static_assert(TimeDelta::Max().FltDiv(TimeDelta::FromSeconds(10)) ==
-                    std::numeric_limits<double>::infinity(),
-                "");
-  static_assert(TimeDelta::Max().FltDiv(TimeDelta::FromSeconds(-10)) ==
-                    -std::numeric_limits<double>::infinity(),
-                "");
-  static_assert(TimeDelta::Min().FltDiv(TimeDelta::FromSeconds(10)) ==
-                    -std::numeric_limits<double>::infinity(),
-                "");
-  static_assert(TimeDelta::Min().FltDiv(TimeDelta::FromSeconds(-10)) ==
-                    std::numeric_limits<double>::infinity(),
-                "");
 
   // Division by zero.
   static_assert((TimeDelta::FromSeconds(1) / 0).is_max(), "");
   static_assert((TimeDelta::FromSeconds(-1) / 0).is_min(), "");
   static_assert((TimeDelta::Max() / 0).is_max(), "");
   static_assert((TimeDelta::Min() / 0).is_min(), "");
+  EXPECT_EQ(std::numeric_limits<double>::infinity(),
+            TimeDelta::FromSeconds(1) / TimeDelta());
+  EXPECT_EQ(-std::numeric_limits<double>::infinity(),
+            TimeDelta::FromSeconds(-1) / TimeDelta());
+  EXPECT_EQ(std::numeric_limits<double>::infinity(),
+            TimeDelta::Max() / TimeDelta());
+  EXPECT_EQ(-std::numeric_limits<double>::infinity(),
+            TimeDelta::Min() / TimeDelta());
   static_assert(TimeDelta::FromSeconds(1).IntDiv(TimeDelta()) ==
                     std::numeric_limits<int64_t>::max(),
                 "");
@@ -1858,24 +1866,16 @@
   static_assert(TimeDelta::Min().IntDiv(TimeDelta()) ==
                     std::numeric_limits<int64_t>::min(),
                 "");
-  EXPECT_EQ(std::numeric_limits<double>::infinity(),
-            TimeDelta::FromSeconds(1).FltDiv(TimeDelta()));
-  EXPECT_EQ(-std::numeric_limits<double>::infinity(),
-            TimeDelta::FromSeconds(-1).FltDiv(TimeDelta()));
-  EXPECT_EQ(std::numeric_limits<double>::infinity(),
-            TimeDelta::Max().FltDiv(TimeDelta()));
-  EXPECT_EQ(-std::numeric_limits<double>::infinity(),
-            TimeDelta::Min().FltDiv(TimeDelta()));
 
   // Division by infinity.
+  static_assert(kLargeDelta / TimeDelta::Min() == 0, "");
+  static_assert(kLargeDelta / TimeDelta::Max() == 0, "");
+  static_assert(kLargeNegative / TimeDelta::Min() == 0, "");
+  static_assert(kLargeNegative / TimeDelta::Max() == 0, "");
   static_assert(kLargeDelta.IntDiv(TimeDelta::Min()) == 0, "");
   static_assert(kLargeDelta.IntDiv(TimeDelta::Max()) == 0, "");
   static_assert(kLargeNegative.IntDiv(TimeDelta::Min()) == 0, "");
   static_assert(kLargeNegative.IntDiv(TimeDelta::Max()) == 0, "");
-  static_assert(kLargeDelta.FltDiv(TimeDelta::Min()) == 0, "");
-  static_assert(kLargeDelta.FltDiv(TimeDelta::Max()) == 0, "");
-  static_assert(kLargeNegative.FltDiv(TimeDelta::Min()) == 0, "");
-  static_assert(kLargeNegative.FltDiv(TimeDelta::Max()) == 0, "");
 
   static_assert(TimeDelta::FromSeconds(10) % TimeDelta::Min() ==
                     TimeDelta::FromSeconds(10),
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 7485b99..0f4c280 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20200803.2.1
+0.20200803.3.1
diff --git a/cc/animation/keyframe_model.cc b/cc/animation/keyframe_model.cc
index 7006f23a..86a515d 100644
--- a/cc/animation/keyframe_model.cc
+++ b/cc/animation/keyframe_model.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/memory/ptr_util.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -317,7 +318,7 @@
   else if (iteration_time == curve_->Duration())
     iteration = ceil(iteration_start_ + iterations_ - 1);
   else
-    iteration = static_cast<int>(scaled_active_time.IntDiv(curve_->Duration()));
+    iteration = base::ClampFloor(scaled_active_time / curve_->Duration());
 
   // Check if we are running the keyframe model in reverse direction for the
   // current iteration
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index b772d3e..ab1f745 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -320,6 +320,7 @@
     "//chrome/browser/optimization_guide/android:java",
     "//chrome/browser/paint_preview/android:java",
     "//chrome/browser/password_check:public_java",
+    "//chrome/browser/password_manager/android:java",
     "//chrome/browser/performance_hints/android:java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/privacy:java",
@@ -405,6 +406,7 @@
     "//components/page_info/android:java",
     "//components/paint_preview/browser/android:java",
     "//components/paint_preview/player/android:java",
+    "//components/password_manager/core/browser:password_manager_java_enums",
     "//components/payments/content/android:java",
     "//components/payments/mojom:mojom_java",
     "//components/permissions/android:java",
@@ -531,7 +533,6 @@
     "//components/ntp_snippets:ntp_snippets_java_enums_srcjar",
     "//components/ntp_tiles:ntp_tiles_enums_java",
     "//components/offline_pages/core:offline_page_model_enums_java",
-    "//components/password_manager/core/browser:password_manager_java_enums_srcjar",
     "//components/payments/content/android:method_strings_generated_srcjar",
     "//components/search_engines:search_engine_type_java",
     "//components/ui_metrics:ui_metrics_enums_java",
@@ -975,6 +976,7 @@
     "//chrome/browser/offline_pages/android:java",
     "//chrome/browser/paint_preview/android:java",
     "//chrome/browser/password_check:public_java",
+    "//chrome/browser/password_manager/android:java",
     "//chrome/browser/password_manager/android_test_helpers:test_support_java",
     "//chrome/browser/performance_hints/android:java",
     "//chrome/browser/preferences:java",
@@ -1062,6 +1064,7 @@
     "//components/page_info/android:java",
     "//components/page_info/android:page_info_action_enum_java",
     "//components/paint_preview/player/android:javatests",
+    "//components/password_manager/core/browser:password_manager_java_enums",
     "//components/payments/content/android:java",
     "//components/payments/mojom:mojom_java",
     "//components/permissions/android:java",
diff --git a/chrome/android/DEPS b/chrome/android/DEPS
index 3657388..df84c8f4 100644
--- a/chrome/android/DEPS
+++ b/chrome/android/DEPS
@@ -4,6 +4,7 @@
   "+chrome/browser/flags/android",
   "+chrome/browser/fullscreen/android",
   "+chrome/browser/notifications",
+  "+chrome/browser/password_manager/android",
   "+chrome/browser/preferences/android/java",
   "+chrome/browser/safety_check/android",
   "+chrome/browser/settings/android",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index f19b742..85a366a8 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -331,7 +331,7 @@
   "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessorUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/tiles/TileSuggestionProcessorUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/voice/VoiceRecognitionHandlerTest.java",
-  "javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java",
+  "javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoViewTest.java",
   "javatests/src/org/chromium/chrome/browser/page_info/CookieControlsViewTest.java",
   "javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java",
   "javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java
index 9828736..92014fa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java
@@ -5,7 +5,6 @@
 package org.chromium.chrome.browser.password_manager;
 
 import android.app.Activity;
-import android.os.Bundle;
 
 import com.google.android.gms.common.ConnectionResult;
 
@@ -13,10 +12,8 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.password_manager.settings.PasswordSettings;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.settings.SettingsLauncher;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
@@ -31,11 +28,6 @@
  * Bridge between Java and native PasswordManager code.
  */
 public class PasswordManagerLauncher {
-    // Key for the argument with which PasswordsSettings will be launched. The value for
-    // this argument should be part of the ManagePasswordsReferrer enum, which contains
-    // all points of entry to the passwords settings.
-    public static final String MANAGE_PASSWORDS_REFERRER = "manage-passwords-referrer";
-
     private static final String GOOGLE_ACCOUNT_PWM_UI = "google-password-manager";
 
     // Name of the parameter for the google-password-manager feature, used to override the default
@@ -56,8 +48,6 @@
      */
     public static void showPasswordSettings(
             Activity activity, @ManagePasswordsReferrer int referrer) {
-        RecordHistogram.recordEnumeratedHistogram("PasswordManager.ManagePasswordsReferrer",
-                referrer, ManagePasswordsReferrer.MAX_VALUE + 1);
         if (isSyncingPasswordsWithoutCustomPassphrase()) {
             RecordHistogram.recordEnumeratedHistogram(
                     "PasswordManager.ManagePasswordsReferrerSignedInAndSyncing", referrer,
@@ -71,10 +61,7 @@
             }
         }
 
-        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-        Bundle fragmentArgs = new Bundle();
-        fragmentArgs.putInt(MANAGE_PASSWORDS_REFERRER, referrer);
-        settingsLauncher.launchSettingsActivity(activity, PasswordSettings.class, fragmentArgs);
+        PasswordManagerHelper.showPasswordSettings(activity, referrer, new SettingsLauncherImpl());
     }
 
     @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
index 4f2edfb..e633cb1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
@@ -35,6 +35,7 @@
 import org.chromium.chrome.browser.password_check.PasswordCheckPreference;
 import org.chromium.chrome.browser.password_check.PasswordCheckReferrer;
 import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
+import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
 import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -148,10 +149,10 @@
         setHasOptionsMenu(true); // Password Export might be optional but Search is always present.
 
         Bundle extras = getArguments();
-        assert extras.containsKey(PasswordManagerLauncher.MANAGE_PASSWORDS_REFERRER)
+        assert extras.containsKey(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER)
             : "PasswordSettings must be launched with a manage-passwords-referrer fragment"
                 + "argument, but none was provided.";
-        mManagePasswordsReferrer = extras.getInt(PasswordManagerLauncher.MANAGE_PASSWORDS_REFERRER);
+        mManagePasswordsReferrer = extras.getInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER);
 
         if (savedInstanceState == null) return;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
index 5074e24..8dc7159 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
@@ -34,6 +34,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.Restriction;
@@ -187,6 +188,7 @@
     @Feature({"StatusBar"})
     @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP_MR1)
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
+    @DisabledTest(message = "https://crbug.com/1111997")
     public void testStatusBarColorCertificateError() throws ExecutionException, TimeoutException {
         final String pageWithThemeColor = mEmbeddedTestServerRule.getServer().getURL(
                 "/chrome/test/data/android/theme_color_test.html");
@@ -228,6 +230,7 @@
      */
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1111997")
     public void testToolbarVisibleCertificateError() throws ExecutionException, TimeoutException {
         final String pageWithoutCertError =
                 mEmbeddedTestServerRule.getServer().getURL("/chrome/test/data/android/about.html");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
index db7a400f..4ea57e4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsTest.java
@@ -28,6 +28,7 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
@@ -143,6 +144,7 @@
      */
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1111906")
     public void jsToTwaConnected() throws TimeoutException {
         DigitalGoodsFactory.setDigitalGoodsForTesting(createFixedDigitalGoods());
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoViewTest.java
similarity index 81%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java
rename to chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoViewTest.java
index 5bdfb018..abd9690 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoViewTest.java
@@ -17,32 +17,32 @@
 import org.chromium.chrome.browser.vr.VrModuleProvider;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.components.page_info.ConnectionInfoPopup;
+import org.chromium.components.page_info.ConnectionInfoView;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 /**
- * Tests for ConnectionInfoPopup.
+ * Tests for ConnectionInfoView.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class ConnectionInfoPopupTest {
+public class ConnectionInfoViewTest {
     @Rule
     public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
             new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
-     * Tests that ConnectionInfoPopup can be instantiated and shown.
+     * Tests that ConnectionInfoView can be instantiated and shown.
      */
     @Test
     @MediumTest
-    @Feature({"ConnectionInfoPopup"})
+    @Feature({"ConnectionInfoView"})
     public void testShow() throws InterruptedException {
         mActivityTestRule.startMainActivityOnBlankPage();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             ChromeActivity context = mActivityTestRule.getActivity();
             WebContents webContents = context.getActivityTab().getWebContents();
-            ConnectionInfoPopup.show(context, webContents, context.getModalDialogManager(),
+            ConnectionInfoView.show(context, webContents, context.getModalDialogManager(),
                     VrModuleProvider.getDelegate());
         });
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
index 3fdd49b..cf4f1fc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -260,7 +260,22 @@
     }
 
     /**
-     * Tests the new PageInfo UI on a secure website.
+     * Tests the connection info page of the new PageInfo UI.
+     */
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
+    public void testShowConnectionInfoSubpage() throws IOException {
+        setThirdPartyCookieBlocking(true);
+        loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(mPath));
+        View dialog = (View) getPageInfoView().getParent();
+        onView(withId(R.id.page_info_connection_row)).perform(click());
+        mRenderTestRule.render(dialog, "PageInfo_ConnectionInfoSubpage");
+    }
+
+    /**
+     * Tests the cookies page of the new PageInfo UI.
      */
     @Test
     @MediumTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
index 00f4174..f252824 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
@@ -102,7 +102,7 @@
 import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
 import org.chromium.chrome.browser.password_check.PasswordCheckPreference;
 import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
+import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.SettingsActivity;
@@ -553,7 +553,7 @@
 
     private SettingsActivity startPasswordSettingsFromMainSettings() {
         Bundle fragmentArgs = new Bundle();
-        fragmentArgs.putInt(PasswordManagerLauncher.MANAGE_PASSWORDS_REFERRER,
+        fragmentArgs.putInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER,
                 ManagePasswordsReferrer.CHROME_SETTINGS);
         return mSettingsActivityTestRule.startSettingsActivity(fragmentArgs);
     }
@@ -562,7 +562,7 @@
         Bundle fragmentArgs = new Bundle();
         // The passwords accessory sheet is one of the places that can launch password settings
         // directly (without passing through main settings).
-        fragmentArgs.putInt(PasswordManagerLauncher.MANAGE_PASSWORDS_REFERRER,
+        fragmentArgs.putInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER,
                 ManagePasswordsReferrer.PASSWORDS_ACCESSORY_SHEET);
         return mSettingsActivityTestRule.startSettingsActivity(fragmentArgs);
     }
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp
index 6b88c412..3a0f82e 100644
--- a/chrome/app/profiles_strings.grdp
+++ b/chrome/app/profiles_strings.grdp
@@ -671,5 +671,11 @@
     subtitle">
       Sign in to Sync your bookmarks, passwords, history and more on all your devices
     </message>
+    <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_SIGNIN_BUTTON_LABEL" desc="Label for a button that prompts user to sign in">
+      Turn on sync...
+    </message>
+    <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_NOT_NOW_BUTTON_LABEL" desc="Label for a button to decline a prompt to sign in">
+      Not now
+    </message>
   </if>
 </grit-part>
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_NOT_NOW_BUTTON_LABEL.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_NOT_NOW_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..dbafc20
--- /dev/null
+++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_NOT_NOW_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+13515c8d130dfbb0f76d35c43ffb5f8b660d3632
\ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_SIGNIN_BUTTON_LABEL.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_SIGNIN_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..dbafc20
--- /dev/null
+++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_SIGNIN_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+13515c8d130dfbb0f76d35c43ffb5f8b660d3632
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index b990e1da1e..c276c6b2 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1289,10 +1289,8 @@
     "prerender/isolated/isolated_prerender_url_loader_interceptor.h",
     "prerender/isolated/prefetched_mainframe_response_container.cc",
     "prerender/isolated/prefetched_mainframe_response_container.h",
-    "prerender/prerende_manager_delegate.h",
     "prerender/prerender_contents.cc",
     "prerender/prerender_contents.h",
-    "prerender/prerender_contents_delegate.h",
     "prerender/prerender_field_trial.cc",
     "prerender/prerender_field_trial.h",
     "prerender/prerender_handle.cc",
@@ -2793,6 +2791,8 @@
       "optimization_guide/android/optimization_guide_bridge.h",
       "page_load_metrics/observers/android_page_load_metrics_observer.cc",
       "page_load_metrics/observers/android_page_load_metrics_observer.h",
+      "password_check/android/password_check_bridge.cc",
+      "password_check/android/password_check_bridge.h",
       "password_manager/android/account_chooser_dialog_android.cc",
       "password_manager/android/account_chooser_dialog_android.h",
       "password_manager/android/auto_signin_first_run_dialog_android.cc",
@@ -2928,7 +2928,7 @@
       "//chrome/browser/offline_pages/prefetch/notifications",
       "//chrome/browser/optimization_guide/android:jni_headers",
       "//chrome/browser/password_check/android",
-      "//chrome/browser/password_check/android/internal",
+      "//chrome/browser/password_check/android/internal:jni_headers",
       "//chrome/browser/payments/android:jni_headers",
       "//chrome/browser/privacy:jni_headers",
       "//chrome/browser/safety_check/android",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 6719541..3ed8ded 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -399,6 +399,9 @@
   "+storage/browser",
   "+storage/common",
 
+  # chrome/browser/ui/views/ is an implementation, not a public interface.
+  # Parent directories should not depend on it directly.
+  # TODO(crbug.com/1112591): Remove the exceptions below.
   "-chrome/browser/ui/views",
   "+chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h",
   "+chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 2318944..8e61dc4 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2732,11 +2732,6 @@
      ENABLE_DISABLE_VALUE_TYPE(switches::kEnableDeviceDiscoveryNotifications,
                                switches::kDisableDeviceDiscoveryNotifications)},
 #endif  // BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
-#if defined(OS_WIN)
-    {"enable-cloud-print-xps", flag_descriptions::kCloudPrintXpsName,
-     flag_descriptions::kCloudPrintXpsDescription, kOsWin,
-     SINGLE_VALUE_TYPE(switches::kEnableCloudPrintXps)},
-#endif  // OS_WIN
 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
     {"enable-webgl2-compute-context",
      flag_descriptions::kWebGL2ComputeContextName,
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.cc b/chrome/browser/apps/platform_apps/shortcut_manager.cc
index 058cb1d..411237d 100644
--- a/chrome/browser/apps/platform_apps/shortcut_manager.cc
+++ b/chrome/browser/apps/platform_apps/shortcut_manager.cc
@@ -60,14 +60,14 @@
                            creation_locations, profile, app, base::DoNothing());
 }
 
-// Used to disable shortcut deletion syscall to prevent tests from flaking.
-bool kSuppressDeleteAllShortcutsForTesting = false;
+// Used to disable shortcut syscalls to prevent tests from flaking.
+bool g_suppress_shortcuts_for_testing = false;
 
 }  // namespace
 
 // static
-void AppShortcutManager::SuppressDeleteAllShortcutsForTesting() {
-  kSuppressDeleteAllShortcutsForTesting = true;
+void AppShortcutManager::SuppressShortcutsForTesting() {
+  g_suppress_shortcuts_for_testing = true;
 }
 
 // static
@@ -119,8 +119,10 @@
   // Bookmark apps are handled in
   // web_app::AppShortcutManager::OnWebAppInstalled() and
   // web_app::AppShortcutManager::OnWebAppManifestUpdated().
-  if (!extension->is_app() || extension->from_bookmark())
+  if (!extension->is_app() || extension->from_bookmark() ||
+      g_suppress_shortcuts_for_testing) {
     return;
+  }
 
   // If the app is being updated, update any existing shortcuts but do not
   // create new ones. If it is being installed, automatically create a
@@ -139,14 +141,13 @@
     extensions::UninstallReason reason) {
   // Bookmark apps are handled in
   // web_app::AppShortcutManager::OnWebAppUninstalled()
-  if (!extension->from_bookmark())
+  if (!extension->from_bookmark() && !g_suppress_shortcuts_for_testing)
     web_app::DeleteAllShortcuts(profile_, extension);
 }
 
 void AppShortcutManager::OnProfileWillBeRemoved(
     const base::FilePath& profile_path) {
-  if (profile_path != profile_->GetPath() ||
-      kSuppressDeleteAllShortcutsForTesting) {
+  if (profile_path != profile_->GetPath() || g_suppress_shortcuts_for_testing) {
     return;
   }
 
@@ -157,10 +158,12 @@
 }
 
 void AppShortcutManager::UpdateShortcutsForAllAppsNow() {
-  web_app::UpdateShortcutsForAllApps(
-      profile_,
-      base::BindOnce(&AppShortcutManager::SetCurrentAppShortcutsVersion,
-                     weak_ptr_factory_.GetWeakPtr()));
+  if (!g_suppress_shortcuts_for_testing) {
+    web_app::UpdateShortcutsForAllApps(
+        profile_,
+        base::BindOnce(&AppShortcutManager::SetCurrentAppShortcutsVersion,
+                       weak_ptr_factory_.GetWeakPtr()));
+  }
 }
 
 void AppShortcutManager::SetCurrentAppShortcutsVersion() {
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.h b/chrome/browser/apps/platform_apps/shortcut_manager.h
index a3bd6d3..2f408e5 100644
--- a/chrome/browser/apps/platform_apps/shortcut_manager.h
+++ b/chrome/browser/apps/platform_apps/shortcut_manager.h
@@ -51,7 +51,7 @@
   // ProfileAttributesStorage::Observer.
   void OnProfileWillBeRemoved(const base::FilePath& profile_path) override;
 
-  static void SuppressDeleteAllShortcutsForTesting();
+  static void SuppressShortcutsForTesting();
 
  private:
   void UpdateShortcutsForAllAppsNow();
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 3b58ff4..24ee219 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -101,6 +101,7 @@
     "//chromeos/attestation",
     "//chromeos/audio",
     "//chromeos/components/account_manager",
+    "//chromeos/components/camera_app_ui",
     "//chromeos/components/cdm_factory_daemon:cdm_factory_daemon_browser",
     "//chromeos/components/drivefs",
     "//chromeos/components/drivefs/mojom",
@@ -2579,6 +2580,8 @@
     "usb/cros_usb_detector.h",
     "virtual_machines/virtual_machines_util.cc",
     "virtual_machines/virtual_machines_util.h",
+    "web_applications/chrome_camera_app_ui_delegate.cc",
+    "web_applications/chrome_camera_app_ui_delegate.h",
     "web_applications/chrome_help_app_ui_delegate.cc",
     "web_applications/chrome_help_app_ui_delegate.h",
     "web_applications/chrome_media_app_ui_delegate.cc",
@@ -3216,7 +3219,6 @@
     "login/saml/mock_lock_handler.h",
     "login/saml/password_expiry_notification_unittest.cc",
     "login/saml/saml_offline_signin_limiter_unittest.cc",
-    "login/screens/multidevice_setup_screen_unittest.cc",
     "login/screens/network_screen_unittest.cc",
     "login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc",
     "login/screens/update_required_screen_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing_session.cc b/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing_session.cc
index e065a6c..b98a762 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing_session.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_app_performance_tracing_session.cc
@@ -133,7 +133,7 @@
 
   if (detect_idles_) {
     const uint64_t display_frames_passed =
-        base::ClampRound<uint64_t>(frame_delta.FltDiv(kTargetFrameTime));
+        base::ClampRound<uint64_t>(frame_delta / kTargetFrameTime);
     if (display_frames_passed >= kIdleThresholdFrames) {
       // Idle is detected, try the next time.
       Stop();
@@ -175,7 +175,7 @@
     // fractional part of target frame interval |kTargetFrameTime| and is less
     // or equal half of it.
     const uint64_t display_frames_passed =
-        base::ClampRound<uint64_t>(frame_delta.FltDiv(kTargetFrameTime));
+        base::ClampRound<uint64_t>(frame_delta / kTargetFrameTime);
     // Calculate difference from the ideal commit time, that should happen with
     // equal delay for each display frame.
     const base::TimeDelta vsync_error =
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
index 12768dff..1a9e62b 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_test_utils.h"
@@ -62,9 +63,9 @@
   base::Optional<AccessCode> first_code = gen.Generate(timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(first_code, timestamp));
 
-  int range =
-      (config.code_validity().IntDiv(Authenticator::kAccessCodeGranularity)) -
-      1;
+  int range = base::ClampFloor(config.code_validity() /
+                               Authenticator::kAccessCodeGranularity) -
+              1;
   for (int i = 0; i < range; ++i) {
     timestamp += Authenticator::kAccessCodeGranularity;
     base::Optional<AccessCode> code = gen.Generate(timestamp);
@@ -209,8 +210,8 @@
   EXPECT_FALSE(validated_code);
 
   // In valid period.
-  int range =
-      config.code_validity().IntDiv(Authenticator::kAccessCodeGranularity);
+  int range = base::ClampFloor(config.code_validity() /
+                               Authenticator::kAccessCodeGranularity);
   for (int i = 0; i < range; ++i) {
     validated_code = validator.Validate(
         generated_code->code(),
@@ -247,8 +248,8 @@
   EXPECT_FALSE(validated_code);
 
   // In valid period.
-  int range =
-      config.code_validity().IntDiv(Authenticator::kAccessCodeGranularity);
+  int range = base::ClampFloor(config.code_validity() /
+                               Authenticator::kAccessCodeGranularity);
   for (int i = 0; i < range; ++i) {
     validated_code = authenticator.Validate(
         generated_code->code(),
@@ -282,8 +283,8 @@
   ASSERT_NO_FATAL_FAILURE(Verify(generated_code, generation_timestamp));
 
   // Both validators accept the code in valid period.
-  int range =
-      kDefaultCodeValidity.IntDiv(Authenticator::kAccessCodeGranularity);
+  int range = base::ClampFloor(kDefaultCodeValidity /
+                               Authenticator::kAccessCodeGranularity);
   base::Time timestamp;
   base::Optional<AccessCode> validated_code_no_tolerance;
   base::Optional<AccessCode> validated_code_with_tolerance;
diff --git a/chrome/browser/chromeos/input_method/emoji_suggester.cc b/chrome/browser/chromeos/input_method/emoji_suggester.cc
index 4064082f..726f269e 100644
--- a/chrome/browser/chromeos/input_method/emoji_suggester.cc
+++ b/chrome/browser/chromeos/input_method/emoji_suggester.cc
@@ -7,6 +7,7 @@
 #include "base/files/file_util.h"
 #include "base/i18n/number_formatting.h"
 #include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -75,6 +76,15 @@
                           last_pos_to_search - space_before_last_word);
 }
 
+void RecordTimeToAccept(base::TimeDelta delta) {
+  UMA_HISTOGRAM_MEDIUM_TIMES("InputMethod.Assistive.TimeToAccept.Emoji", delta);
+}
+
+void RecordTimeToDismiss(base::TimeDelta delta) {
+  UMA_HISTOGRAM_MEDIUM_TIMES("InputMethod.Assistive.TimeToDismiss.Emoji",
+                             delta);
+}
+
 }  // namespace
 
 EmojiSuggester::EmojiSuggester(SuggestionHandlerInterface* suggestion_handler,
@@ -232,6 +242,7 @@
   IncrementPrefValueTilCapped(kEmojiSuggesterShowSettingCount,
                               kEmojiSuggesterShowSettingMaxCount);
   ShowSuggestionWindowWithIndices(false);
+  session_start_ = base::TimeTicks::Now();
 
   buttons_.clear();
   for (size_t i = 0; i < candidates_.size(); i++) {
@@ -266,8 +277,10 @@
 
   if (!error.empty()) {
     LOG(ERROR) << "Failed to accept suggestion. " << error;
+    return false;
   }
 
+  RecordTimeToAccept(base::TimeTicks::Now() - session_start_);
   suggestion_shown_ = false;
   RecordAcceptanceIndex(index);
   return true;
@@ -275,14 +288,16 @@
 
 void EmojiSuggester::DismissSuggestion() {
   std::string error;
-  suggestion_shown_ = false;
   properties_.visible = false;
   properties_.announce_string = kDismissEmojiSuggestionMessage;
   suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties_,
                                                     &error);
   if (!error.empty()) {
     LOG(ERROR) << "Failed to dismiss suggestion. " << error;
+    return;
   }
+  suggestion_shown_ = false;
+  RecordTimeToDismiss(base::TimeTicks::Now() - session_start_);
 }
 
 void EmojiSuggester::SetButtonHighlighted(
diff --git a/chrome/browser/chromeos/input_method/emoji_suggester.h b/chrome/browser/chromeos/input_method/emoji_suggester.h
index c46863b..6980920 100644
--- a/chrome/browser/chromeos/input_method/emoji_suggester.h
+++ b/chrome/browser/chromeos/input_method/emoji_suggester.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/time/time.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine_base.h"
 #include "chrome/browser/chromeos/input_method/suggester.h"
 #include "chrome/browser/chromeos/input_method/suggestion_enums.h"
@@ -80,6 +81,8 @@
   // The map holding one-word-mapping to emojis.
   std::map<std::string, std::vector<base::string16>> emoji_map_;
 
+  base::TimeTicks session_start_;
+
   // Pointer for callback, must be the last declared in the file.
   base::WeakPtrFactory<EmojiSuggester> weak_factory_{this};
 };
diff --git a/chrome/browser/chromeos/input_method/emoji_suggester_unittest.cc b/chrome/browser/chromeos/input_method/emoji_suggester_unittest.cc
index 57a622e..d219d48c 100644
--- a/chrome/browser/chromeos/input_method/emoji_suggester_unittest.cc
+++ b/chrome/browser/chromeos/input_method/emoji_suggester_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/input_method/emoji_suggester.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 #include "chrome/test/base/testing_profile.h"
@@ -362,4 +363,27 @@
   engine_->VerifyShowSettingLink(false);
 }
 
+TEST_F(EmojiSuggesterTest, RecordsTimeToAccept) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToAccept.Emoji",
+                                    0);
+  EXPECT_TRUE(emoji_suggester_->Suggest(base::UTF8ToUTF16("happy ")));
+  // Press "Down" to choose and accept a candidate.
+  Press("Down");
+  Press("Enter");
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToAccept.Emoji",
+                                    1);
+}
+
+TEST_F(EmojiSuggesterTest, RecordsTimeToDismiss) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToDismiss.Emoji",
+                                    0);
+  EXPECT_TRUE(emoji_suggester_->Suggest(base::UTF8ToUTF16("happy ")));
+  // Press "Esc" to dismiss.
+  Press("Esc");
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToDismiss.Emoji",
+                                    1);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc
index 3858100..d9e1638 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc
@@ -509,6 +509,29 @@
 }
 
 IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineTest,
+                       DismissEmojiSuggestionWhenUsersContinueTyping) {
+  base::HistogramTester histogram_tester;
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToDismiss.Emoji",
+                                    0);
+  engine_.Enable(kEngineIdUs);
+  chromeos::TextInputTestHelper helper(GetBrowserInputMethod());
+  SetUpTextInput(helper);
+  const base::string16 prefix_text = base::UTF8ToUTF16("happy ");
+  const base::string16 expected_result_text = base::UTF8ToUTF16("happy a");
+
+  helper.GetTextInputClient()->InsertText(prefix_text);
+  helper.WaitForSurroundingTextChanged(prefix_text);
+  // Types something random to dismiss emoji
+  helper.GetTextInputClient()->InsertText(base::UTF8ToUTF16("a"));
+  helper.WaitForSurroundingTextChanged(expected_result_text);
+
+  histogram_tester.ExpectTotalCount("InputMethod.Assistive.TimeToDismiss.Emoji",
+                                    1);
+
+  SetFocus(nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineTest,
                        EmojiSuggestionDisabledReasonkEnterpriseSettingsOff) {
   base::HistogramTester histogram_tester;
   prefs_->SetBoolean(chromeos::prefs::kEmojiSuggestionEnterpriseAllowed, false);
diff --git a/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc b/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc
index 1be7dbc2..f0d1a17 100644
--- a/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc
+++ b/chrome/browser/chromeos/login/arc_terms_of_service_browsertest.cc
@@ -724,7 +724,6 @@
 IN_PROC_BROWSER_TEST_F(PublicAccountArcTermsOfServiceScreenTest,
                        SkippedForPublicAccount) {
   StartPublicSession();
-  ShowArcTosScreen();
 
   chromeos::test::WaitForPrimaryUserSessionStart();
   histogram_tester_.ExpectTotalCount(
diff --git a/chrome/browser/chromeos/login/screens/gaia_screen.cc b/chrome/browser/chromeos/login/screens/gaia_screen.cc
index aca9d1a..cc8c70e 100644
--- a/chrome/browser/chromeos/login/screens/gaia_screen.cc
+++ b/chrome/browser/chromeos/login/screens/gaia_screen.cc
@@ -4,12 +4,39 @@
 
 #include "chrome/browser/chromeos/login/screens/gaia_screen.h"
 
+#include "chrome/browser/chromeos/login/screen_manager.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
+#include "components/account_id/account_id.h"
 
 namespace chromeos {
 
+GaiaScreen::GaiaScreen()
+    : BaseScreen(GaiaView::kScreenId, OobeScreenPriority::DEFAULT) {}
+
+// static
+GaiaScreen* GaiaScreen::Get(ScreenManager* manager) {
+  return static_cast<GaiaScreen*>(manager->GetScreen(GaiaView::kScreenId));
+}
+
 void GaiaScreen::MaybePreloadAuthExtension() {
   view_->MaybePreloadAuthExtension();
 }
 
+void GaiaScreen::LoadOnline(const AccountId& account) {
+  view_->LoadGaiaAsync(account);
+}
+
+void GaiaScreen::LoadOffline(const AccountId& account) {
+  view_->LoadOfflineGaia(account);
+}
+
+void GaiaScreen::ShowImpl() {
+  view_->Show();
+}
+
+void GaiaScreen::HideImpl() {
+  view_->LoadGaiaAsync(EmptyAccountId());
+  view_->Hide();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/gaia_screen.h b/chrome/browser/chromeos/login/screens/gaia_screen.h
index 680af80..847df74 100644
--- a/chrome/browser/chromeos/login/screens/gaia_screen.h
+++ b/chrome/browser/chromeos/login/screens/gaia_screen.h
@@ -8,25 +8,35 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "chrome/browser/chromeos/login/screens/base_screen.h"
 
 namespace chromeos {
 
 class GaiaView;
+class ScreenManager;
 
 // This class represents GAIA screen: login screen that is responsible for
 // GAIA-based sign-in.
-class GaiaScreen {
+class GaiaScreen : public BaseScreen {
  public:
-  GaiaScreen() = default;
-  virtual ~GaiaScreen() = default;
+  GaiaScreen();
+  ~GaiaScreen() override = default;
+
+  static GaiaScreen* Get(ScreenManager* manager);
 
   void set_view(GaiaView* view) { view_ = view; }
 
   void MaybePreloadAuthExtension();
+  // Loads online Gaia into the webview.
+  void LoadOnline(const AccountId& account);
+  // Loads offline version of Gaia.
+  void LoadOffline(const AccountId& account);
 
  private:
+  void ShowImpl() override;
+  void HideImpl() override;
+
   GaiaView* view_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(GaiaScreen);
diff --git a/chrome/browser/chromeos/login/screens/multidevice_setup_screen.cc b/chrome/browser/chromeos/login/screens/multidevice_setup_screen.cc
index 1fc9600..8963f8111 100644
--- a/chrome/browser/chromeos/login/screens/multidevice_setup_screen.cc
+++ b/chrome/browser/chromeos/login/screens/multidevice_setup_screen.cc
@@ -24,9 +24,19 @@
 
 }  // namespace
 
+// static
+std::string MultiDeviceSetupScreen::GetResultString(Result result) {
+  switch (result) {
+    case Result::NEXT:
+      return "Next";
+    case Result::NOT_APPLICABLE:
+      return BaseScreen::kNotApplicable;
+  }
+}
+
 MultiDeviceSetupScreen::MultiDeviceSetupScreen(
     MultiDeviceSetupScreenView* view,
-    const base::RepeatingClosure& exit_callback)
+    const ScreenExitCallback& exit_callback)
     : BaseScreen(MultiDeviceSetupScreenView::kScreenId,
                  OobeScreenPriority::DEFAULT),
       view_(view),
@@ -39,32 +49,40 @@
   view_->Bind(nullptr);
 }
 
-void MultiDeviceSetupScreen::ShowImpl() {
+void MultiDeviceSetupScreen::TryInitSetupClient() {
+  if (!setup_client_) {
+    setup_client_ =
+        multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
+            ProfileManager::GetActiveUserProfile());
+  }
+}
+
+bool MultiDeviceSetupScreen::MaybeSkip(WizardContext* /*context*/) {
   // Only attempt the setup flow for non-guest users.
   if (chrome_user_manager_util::IsPublicSessionOrEphemeralLogin()) {
-    ExitScreen();
-    return;
+    exit_callback_.Run(Result::NOT_APPLICABLE);
+    return true;
   }
 
-  multidevice_setup::MultiDeviceSetupClient* client =
-      multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
-          ProfileManager::GetActiveUserProfile());
-
-  if (!client) {
-    ExitScreen();
-    return;
-  }
-
+  TryInitSetupClient();
   // If there is no eligible multi-device host phone or if there is a phone and
   // it has already been set, skip the setup flow.
-  if (client->GetHostStatus().first !=
+  if (!setup_client_) {
+    exit_callback_.Run(Result::NOT_APPLICABLE);
+    return true;
+  }
+  if (setup_client_->GetHostStatus().first !=
       multidevice_setup::mojom::HostStatus::kEligibleHostExistsButNoHostSet) {
     VLOG(1) << "Skipping MultiDevice setup screen; host status: "
-            << client->GetHostStatus().first;
-    ExitScreen();
-    return;
+            << setup_client_->GetHostStatus().first;
+    exit_callback_.Run(Result::NOT_APPLICABLE);
+    return true;
   }
 
+  return false;
+}
+
+void MultiDeviceSetupScreen::ShowImpl() {
   view_->Show();
 
   // Record that user was presented with setup flow to prevent spam
@@ -84,11 +102,11 @@
   if (action_id == kAcceptedSetupUserAction) {
     RecordMultiDeviceSetupOOBEUserChoiceHistogram(
         MultiDeviceSetupOOBEUserChoice::kAccepted);
-    ExitScreen();
+    exit_callback_.Run(Result::NEXT);
   } else if (action_id == kDeclinedSetupUserAction) {
     RecordMultiDeviceSetupOOBEUserChoiceHistogram(
         MultiDeviceSetupOOBEUserChoice::kDeclined);
-    ExitScreen();
+    exit_callback_.Run(Result::NEXT);
   } else {
     BaseScreen::OnUserAction(action_id);
     NOTREACHED();
@@ -100,8 +118,4 @@
   UMA_HISTOGRAM_ENUMERATION("MultiDeviceSetup.OOBE.UserChoice", value);
 }
 
-void MultiDeviceSetupScreen::ExitScreen() {
-  exit_callback_.Run();
-}
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/multidevice_setup_screen.h b/chrome/browser/chromeos/login/screens/multidevice_setup_screen.h
index 707165b2..2a2a7eb 100644
--- a/chrome/browser/chromeos/login/screens/multidevice_setup_screen.h
+++ b/chrome/browser/chromeos/login/screens/multidevice_setup_screen.h
@@ -7,22 +7,50 @@
 
 #include <string>
 
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 
 namespace chromeos {
 
+namespace multidevice_setup {
+
+class MultiDeviceSetupClient;
+
+}  // namespace multidevice_setup
+
 class MultiDeviceSetupScreenView;
 
 class MultiDeviceSetupScreen : public BaseScreen {
  public:
+  enum class Result { NEXT, NOT_APPLICABLE };
+
+  static std::string GetResultString(Result result);
+
+  using ScreenExitCallback = base::RepeatingCallback<void(Result result)>;
   MultiDeviceSetupScreen(MultiDeviceSetupScreenView* view,
-                         const base::RepeatingClosure& exit_callback);
+                         const ScreenExitCallback& exit_callback);
   ~MultiDeviceSetupScreen() override;
 
+  void AddExitCallbackForTesting(const ScreenExitCallback& testing_callback) {
+    exit_callback_ = base::BindRepeating(
+        [](const ScreenExitCallback& original_callback,
+           const ScreenExitCallback& testing_callback, Result result) {
+          original_callback.Run(result);
+          testing_callback.Run(result);
+        },
+        exit_callback_, testing_callback);
+  }
+
+  void set_multidevice_setup_client_for_testing(
+      multidevice_setup::MultiDeviceSetupClient* client) {
+    setup_client_ = client;
+  }
+
  protected:
   // BaseScreen:
+  bool MaybeSkip(WizardContext* context) override;
   void ShowImpl() override;
   void HideImpl() override;
   void OnUserAction(const std::string& action_id) override;
@@ -40,14 +68,16 @@
     kMaxValue = kDeclined
   };
 
+  // Inits |setup_client_| if it was not initialized before.
+  void TryInitSetupClient();
+
   static void RecordMultiDeviceSetupOOBEUserChoiceHistogram(
       MultiDeviceSetupOOBEUserChoice value);
 
-  // Exits the screen.
-  void ExitScreen();
+  multidevice_setup::MultiDeviceSetupClient* setup_client_ = nullptr;
 
   MultiDeviceSetupScreenView* view_;
-  base::RepeatingClosure exit_callback_;
+  ScreenExitCallback exit_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupScreen);
 };
diff --git a/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc
new file mode 100644
index 0000000..fff1201f
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc
@@ -0,0 +1,173 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/screens/multidevice_setup_screen.h"
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/screen_manager.h"
+#include "chrome/browser/chromeos/login/test/js_checker.h"
+#include "chrome/browser/chromeos/login/test/login_manager_mixin.h"
+#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
+#include "chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.h"
+#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
+#include "content/public/test/browser_test.h"
+
+namespace chromeos {
+
+class MultiDeviceSetupScreenTest : public OobeBaseTest {
+ public:
+  MultiDeviceSetupScreenTest() {
+    // To reuse existing wizard controller in the flow.
+    feature_list_.InitAndEnableFeature(
+        chromeos::features::kOobeScreensPriority);
+  }
+  ~MultiDeviceSetupScreenTest() override = default;
+
+  void SetUpOnMainThread() override {
+    MultiDeviceSetupScreen* screen = static_cast<MultiDeviceSetupScreen*>(
+        WizardController::default_controller()->screen_manager()->GetScreen(
+            MultiDeviceSetupScreenView::kScreenId));
+    screen->AddExitCallbackForTesting(base::BindRepeating(
+        &MultiDeviceSetupScreenTest::HandleScreenExit, base::Unretained(this)));
+
+    fake_multidevice_setup_client_ =
+        std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
+    screen->set_multidevice_setup_client_for_testing(
+        fake_multidevice_setup_client_.get());
+    OobeBaseTest::SetUpOnMainThread();
+  }
+
+  void SimulateHostStatusChange() {
+    multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice
+        host_status_with_device = multidevice_setup::MultiDeviceSetupClient::
+            GenerateDefaultHostStatusWithDevice();
+    host_status_with_device.first =
+        multidevice_setup::mojom::HostStatus::kEligibleHostExistsButNoHostSet;
+    fake_multidevice_setup_client_->SetHostStatusWithDevice(
+        host_status_with_device);
+  }
+
+  void ShowMultiDeviceSetupScreen() {
+    login_manager_mixin_.LoginAsNewRegularUser();
+    OobeScreenExitWaiter(GaiaView::kScreenId).Wait();
+    if (!screen_exited_) {
+      LoginDisplayHost::default_host()->StartWizard(
+          MultiDeviceSetupScreenView::kScreenId);
+    }
+  }
+
+  void FinishDeviceSetup() {
+    test::OobeJS().Evaluate(
+        R"($('multidevice-setup-impl')
+          .$['multideviceSetup']
+          .fire('setup-exited', {didUserCompleteSetup: true});)");
+  }
+
+  void CancelDeviceSetup() {
+    test::OobeJS().Evaluate(
+        R"($('multidevice-setup-impl')
+          .$['multideviceSetup']
+          .fire('setup-exited', {didUserCompleteSetup: false});)");
+  }
+
+  void WaitForScreenShown() {
+    OobeScreenWaiter(MultiDeviceSetupScreenView::kScreenId).Wait();
+  }
+
+  void WaitForScreenExit() {
+    if (screen_exited_)
+      return;
+    base::RunLoop run_loop;
+    screen_exit_callback_ = run_loop.QuitClosure();
+    run_loop.Run();
+  }
+
+  void CheckUserChoice(bool Accepted) {
+    histogram_tester_.ExpectBucketCount<
+        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
+        "MultiDeviceSetup.OOBE.UserChoice",
+        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kAccepted,
+        Accepted);
+    histogram_tester_.ExpectBucketCount<
+        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
+        "MultiDeviceSetup.OOBE.UserChoice",
+        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kDeclined,
+        !Accepted);
+  }
+
+  base::Optional<MultiDeviceSetupScreen::Result> screen_result_;
+  base::HistogramTester histogram_tester_;
+
+ private:
+  void HandleScreenExit(MultiDeviceSetupScreen::Result result) {
+    ASSERT_FALSE(screen_exited_);
+    screen_exited_ = true;
+    screen_result_ = result;
+    if (screen_exit_callback_)
+      std::move(screen_exit_callback_).Run();
+  }
+
+  bool screen_exited_ = false;
+  base::RepeatingClosure screen_exit_callback_;
+
+  base::test::ScopedFeatureList feature_list_;
+  std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient>
+      fake_multidevice_setup_client_;
+
+  LoginManagerMixin login_manager_mixin_{&mixin_host_};
+};
+
+IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, Accepted) {
+  SimulateHostStatusChange();
+  ShowMultiDeviceSetupScreen();
+  WaitForScreenShown();
+
+  FinishDeviceSetup();
+
+  WaitForScreenExit();
+  EXPECT_EQ(screen_result_.value(), MultiDeviceSetupScreen::Result::NEXT);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTimeByExitReason.Multidevice-setup.Next", 1);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTime.Multidevice-setup", 1);
+  CheckUserChoice(true);
+}
+
+IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, Declined) {
+  SimulateHostStatusChange();
+  ShowMultiDeviceSetupScreen();
+  WaitForScreenShown();
+
+  CancelDeviceSetup();
+
+  WaitForScreenExit();
+  EXPECT_EQ(screen_result_.value(), MultiDeviceSetupScreen::Result::NEXT);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTimeByExitReason.Multidevice-setup.Next", 1);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTime.Multidevice-setup", 1);
+  CheckUserChoice(false);
+}
+
+IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, Skipped) {
+  ShowMultiDeviceSetupScreen();
+
+  WaitForScreenExit();
+  EXPECT_EQ(screen_result_.value(),
+            MultiDeviceSetupScreen::Result::NOT_APPLICABLE);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTimeByExitReason.Multidevice-setup.Next", 0);
+  histogram_tester_.ExpectTotalCount(
+      "OOBE.StepCompletionTime.Multidevice-setup", 0);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/multidevice_setup_screen_unittest.cc b/chrome/browser/chromeos/login/screens/multidevice_setup_screen_unittest.cc
deleted file mode 100644
index 35fab77..0000000
--- a/chrome/browser/chromeos/login/screens/multidevice_setup_screen_unittest.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/login/screens/multidevice_setup_screen.h"
-
-#include <memory>
-
-#include "base/bind_helpers.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "chrome/browser/ui/webui/chromeos/login/multidevice_setup_screen_handler.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-
-namespace {
-
-class FakeMultiDeviceSetupScreenView : public MultiDeviceSetupScreenView {
- public:
-  FakeMultiDeviceSetupScreenView() = default;
-  ~FakeMultiDeviceSetupScreenView() override = default;
-
-  // MultiDeviceSetupScreenView:
-  void Bind(MultiDeviceSetupScreen* screen) override {}
-  void Show() override {}
-  void Hide() override {}
-};
-
-}  // namespace
-
-class MultiDeviceSetupScreenTest : public testing::Test {
- public:
-  MultiDeviceSetupScreenTest() = default;
-  ~MultiDeviceSetupScreenTest() override = default;
-
-  // testing::Test:
-  void SetUp() override {
-    multi_device_setup_screen_ = std::make_unique<MultiDeviceSetupScreen>(
-        &fake_multi_device_setup_screen_view_, base::DoNothing());
-  }
-
-  void TearDown() override {}
-
-  std::unique_ptr<MultiDeviceSetupScreen> multi_device_setup_screen_;
-
-  void VerifyUserChoicePaths() {
-    histogram_tester_.ExpectTotalCount("MultiDeviceSetup.OOBE.UserChoice", 0);
-
-    multi_device_setup_screen_->OnUserAction("setup-accepted");
-
-    histogram_tester_.ExpectBucketCount<
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
-        "MultiDeviceSetup.OOBE.UserChoice",
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kAccepted, 1);
-    histogram_tester_.ExpectBucketCount<
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
-        "MultiDeviceSetup.OOBE.UserChoice",
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kDeclined, 0);
-
-    multi_device_setup_screen_->OnUserAction("setup-declined");
-
-    histogram_tester_.ExpectBucketCount<
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
-        "MultiDeviceSetup.OOBE.UserChoice",
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kAccepted, 1);
-    histogram_tester_.ExpectBucketCount<
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice>(
-        "MultiDeviceSetup.OOBE.UserChoice",
-        MultiDeviceSetupScreen::MultiDeviceSetupOOBEUserChoice::kDeclined, 1);
-  }
-
- private:
-  base::HistogramTester histogram_tester_;
-
-  // Accessory objects needed by MultiDeviceSetupScreen
-  FakeMultiDeviceSetupScreenView fake_multi_device_setup_screen_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupScreenTest);
-};
-
-TEST_F(MultiDeviceSetupScreenTest, VerifyUserChoicePaths) {
-  VerifyUserChoicePaths();
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/update_required_screen.cc b/chrome/browser/chromeos/login/screens/update_required_screen.cc
index 2c7ac3bd..20e7ae1 100644
--- a/chrome/browser/chromeos/login/screens/update_required_screen.cc
+++ b/chrome/browser/chromeos/login/screens/update_required_screen.cc
@@ -50,11 +50,13 @@
 }
 
 UpdateRequiredScreen::UpdateRequiredScreen(UpdateRequiredView* view,
-                                           ErrorScreen* error_screen)
+                                           ErrorScreen* error_screen,
+                                           base::RepeatingClosure exit_callback)
     : BaseScreen(UpdateRequiredView::kScreenId,
                  OobeScreenPriority::SCREEN_UPDATE_REQUIRED),
       view_(view),
       error_screen_(error_screen),
+      exit_callback_(std::move(exit_callback)),
       histogram_helper_(
           std::make_unique<ErrorScreensHistogramHelper>("UpdateRequired")),
       version_updater_(std::make_unique<VersionUpdater>(this)),
@@ -376,6 +378,11 @@
     view_->SetUIState(UpdateRequiredView::UPDATE_ERROR);
 }
 
+void UpdateRequiredScreen::Exit() {
+  DCHECK(!is_hidden());
+  exit_callback_.Run();
+}
+
 VersionUpdater* UpdateRequiredScreen::GetVersionUpdaterForTesting() {
   return version_updater_.get();
 }
diff --git a/chrome/browser/chromeos/login/screens/update_required_screen.h b/chrome/browser/chromeos/login/screens/update_required_screen.h
index 961fb111..e4fa4870 100644
--- a/chrome/browser/chromeos/login/screens/update_required_screen.h
+++ b/chrome/browser/chromeos/login/screens/update_required_screen.h
@@ -35,7 +35,9 @@
  public:
   static UpdateRequiredScreen* Get(ScreenManager* manager);
 
-  UpdateRequiredScreen(UpdateRequiredView* view, ErrorScreen* error_screen);
+  UpdateRequiredScreen(UpdateRequiredView* view,
+                       ErrorScreen* error_screen,
+                       base::RepeatingClosure exit_callback);
   ~UpdateRequiredScreen() override;
 
   // Called when the being destroyed. This should call Unbind() on the
@@ -55,6 +57,9 @@
       const VersionUpdater::UpdateInfo& update_info) override;
   void FinishExitUpdate(VersionUpdater::Result result) override;
 
+  // Exit the screen.
+  void Exit();
+
   VersionUpdater* GetVersionUpdaterForTesting();
 
   // Set a base clock (used to set current time) for testing EOL.
@@ -103,6 +108,7 @@
 
   UpdateRequiredView* view_ = nullptr;
   ErrorScreen* error_screen_;
+  base::RepeatingClosure exit_callback_;
   std::unique_ptr<ErrorScreensHistogramHelper> histogram_helper_;
 
   // Whether the screen is shown.
diff --git a/chrome/browser/chromeos/login/screens/update_required_screen_unittest.cc b/chrome/browser/chromeos/login/screens/update_required_screen_unittest.cc
index 122ce75..8801e6b 100644
--- a/chrome/browser/chromeos/login/screens/update_required_screen_unittest.cc
+++ b/chrome/browser/chromeos/login/screens/update_required_screen_unittest.cc
@@ -71,7 +71,7 @@
         .WillRepeatedly(Return(false));
 
     update_required_screen_ = std::make_unique<UpdateRequiredScreen>(
-        fake_view_.get(), mock_error_screen_.get());
+        fake_view_.get(), mock_error_screen_.get(), base::DoNothing());
 
     update_required_screen_->GetVersionUpdaterForTesting()
         ->set_wait_for_reboot_time_for_testing(base::TimeDelta::FromSeconds(0));
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc b/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
index a970beb..538c133 100644
--- a/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/chromeos/login/session/chrome_session_manager.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
+#include "chrome/browser/chromeos/login/test/device_state_mixin.h"
 #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h"
 #include "chrome/browser/chromeos/login/test/login_manager_mixin.h"
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
@@ -68,8 +69,7 @@
 
 class ChromeSessionManagerTest : public LoginManagerTest {
  public:
-  ChromeSessionManagerTest()
-      : LoginManagerTest(), fake_gaia_{&mixin_host_, embedded_test_server()} {}
+  ChromeSessionManagerTest() = default;
   ~ChromeSessionManagerTest() override {}
 
   // LoginManagerTest:
@@ -79,16 +79,10 @@
     command_line->AppendSwitch(switches::kOobeSkipPostLogin);
   }
 
-  void StartSignInScreen() {
-    WizardController* wizard_controller =
-        WizardController::default_controller();
-    ASSERT_TRUE(wizard_controller);
-    wizard_controller->SkipToLoginForTesting();
-    OobeScreenWaiter(GaiaView::kScreenId).Wait();
-  }
-
  protected:
-  FakeGaiaMixin fake_gaia_;
+  FakeGaiaMixin fake_gaia_{&mixin_host_, embedded_test_server()};
+  DeviceStateMixin device_state_{
+      &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_UNOWNED};
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeSessionManagerTest);
@@ -105,7 +99,7 @@
   fake_gaia_.SetupFakeGaiaForLoginManager();
   fake_gaia_.fake_gaia()->SetFakeMergeSessionParams(
       FakeGaiaMixin::kFakeUserEmail, "fake_sid", "fake_lsid");
-  StartSignInScreen();
+  OobeScreenWaiter(GaiaView::kScreenId).Wait();
 
   LoginDisplayHost::default_host()
       ->GetOobeUI()
@@ -189,7 +183,7 @@
     fake_gaia_.SetupFakeGaiaForLoginManager();
     fake_gaia_.fake_gaia()->SetFakeMergeSessionParams(
         FakeGaiaMixin::kFakeUserEmail, "fake_sid", "fake_lsid");
-    StartSignInScreen();
+    OobeScreenWaiter(GaiaView::kScreenId).Wait();
 
     LoginDisplayHost::default_host()
         ->GetOobeUI()
diff --git a/chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.cc b/chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.cc
index 605f91e..6a7cce6 100644
--- a/chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.cc
+++ b/chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
 
@@ -35,7 +36,7 @@
   run_loop_->Run();
   run_loop_.reset();
 
-  DCHECK_EQ(State::DONE, state_);
+  ASSERT_EQ(State::DONE, state_);
 
   oobe_ui_observer_.RemoveAll();
 }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
index 2825755..88a1fbb 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/kiosk_launch_controller.h"
+#include "chrome/browser/chromeos/login/screens/gaia_screen.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/webui_accelerator_mapping.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -117,11 +118,6 @@
   connector->ScheduleServiceInitialization(
       kPolicyServiceInitializationDelayMilliseconds);
 
-  // Inform wizard controller that login screen has started.
-  // TODO(crbug.com/1064271): Move this to OnStartSignInScreen().
-  if (WizardController::default_controller())
-    WizardController::default_controller()->LoginScreenStarted();
-
   // Run UI-specific logic.
   OnStartSignInScreen();
 
@@ -309,23 +305,22 @@
 
 void LoginDisplayHostCommon::ShowGaiaDialogCommon(
     const AccountId& prefilled_account) {
-  DCHECK(GetOobeUI());
-
   if (prefilled_account.is_valid()) {
-    // Make sure gaia displays |account| if requested.
-    if (!GetLoginDisplay()->delegate()->IsSigninInProgress()) {
-      GetOobeUI()->GetView<GaiaScreenHandler>()->ShowGaiaAsync(
-          prefilled_account);
-    }
     LoadWallpaper(prefilled_account);
-  } else {
-    if (GetOobeUI()->current_screen() != GaiaView::kScreenId) {
-      GetOobeUI()->GetView<GaiaScreenHandler>()->ShowGaiaAsync(
-          EmptyAccountId());
+    if (GetLoginDisplay()->delegate()->IsSigninInProgress()) {
+      return;
     }
+  } else {
     LoadSigninWallpaper();
   }
+
+  DCHECK(GetWizardController());
+  GaiaScreen* gaia_screen =
+      GaiaScreen::Get(GetWizardController()->screen_manager());
+  gaia_screen->LoadOnline(prefilled_account);
+  StartWizard(GaiaView::kScreenId);
 }
+
 void LoginDisplayHostCommon::Cleanup() {
   ProfileHelper::Get()->ClearSigninProfile(base::DoNothing());
   registrar_.RemoveAll();
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
index 03c9fe2..4117e63 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/chromeos/login/mojo_system_info_dispatcher.h"
 #include "chrome/browser/chromeos/login/reauth_stats.h"
 #include "chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h"
+#include "chrome/browser/chromeos/login/screens/gaia_screen.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
 #include "chrome/browser/chromeos/login/ui/login_display_mojo.h"
 #include "chrome/browser/chromeos/login/user_board_view_mojo.h"
@@ -118,7 +119,9 @@
   // And if the dialog shows login screen.
   if (was_zero_users && user_count_ != 0 && dialog_ && dialog_->IsVisible() &&
       (!wizard_controller_->is_initialized() ||
-       wizard_controller_->login_screen_started())) {
+       (wizard_controller_->current_screen() &&
+        wizard_controller_->current_screen()->screen_id() ==
+            GaiaView::kScreenId))) {
     HideOobeDialog();
   }
 }
@@ -253,8 +256,21 @@
   if (signin_screen_started_) {
     // If we already have a signin screen instance, just reset the state of the
     // oobe dialog.
+
+    // Try to switch to Gaia screen.
+    StartWizard(GaiaView::kScreenId);
+
+    if (wizard_controller_->current_screen() &&
+        wizard_controller_->current_screen()->screen_id() !=
+            GaiaView::kScreenId) {
+      // Switching might fail due to the screen priorities. Do no hide the
+      // dialog in that case.
+      return;
+    }
+
+    // Maybe hide dialog if there are existing users. It also reloads Gaia.
     HideOobeDialog();
-    GetOobeUI()->GetView<GaiaScreenHandler>()->ShowGaiaAsync(EmptyAccountId());
+
     return;
   }
 
@@ -318,7 +334,9 @@
   const bool no_users =
       !login_display_->IsSigninInProgress() && user_count_ == 0;
   if (no_users || GetOobeUI()->current_screen() == GaiaView::kScreenId) {
-    GetOobeUI()->GetView<GaiaScreenHandler>()->ShowGaiaAsync(EmptyAccountId());
+    GaiaScreen* gaia_screen =
+        GaiaScreen::Get(GetWizardController()->screen_manager());
+    gaia_screen->LoadOnline(EmptyAccountId());
     if (no_users)
       return;
   }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
index f9623ff1..a3cf90c 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -573,7 +573,7 @@
   // Keep parameters to restore if renderer crashes.
   restore_path_ = RESTORE_WIZARD;
   first_screen_ = first_screen;
-  is_showing_login_ = false;
+  is_showing_login_ = (first_screen == GaiaView::kScreenId);
 
   VLOG(1) << "Login WebUI >> wizard";
 
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 2674080f..678eb9b 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -66,6 +66,7 @@
 #include "chrome/browser/chromeos/login/screens/family_link_notice_screen.h"
 #include "chrome/browser/chromeos/login/screens/fingerprint_setup_screen.h"
 #include "chrome/browser/chromeos/login/screens/gaia_password_changed_screen.h"
+#include "chrome/browser/chromeos/login/screens/gaia_screen.h"
 #include "chrome/browser/chromeos/login/screens/gesture_navigation_screen.h"
 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
 #include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h"
@@ -565,7 +566,9 @@
                           weak_factory_.GetWeakPtr())));
   append(std::make_unique<UpdateRequiredScreen>(
       oobe_ui->GetView<UpdateRequiredScreenHandler>(),
-      oobe_ui->GetErrorScreen()));
+      oobe_ui->GetErrorScreen(),
+      base::BindRepeating(&WizardController::OnUpdateRequiredScreenExit,
+                          weak_factory_.GetWeakPtr())));
   append(std::make_unique<AssistantOptInFlowScreen>(
       oobe_ui->GetView<AssistantOptInFlowScreenHandler>(),
       base::BindRepeating(&WizardController::OnAssistantOptInFlowScreenExit,
@@ -594,6 +597,9 @@
       oobe_ui->GetView<PackagedLicenseScreenHandler>(),
       base::BindRepeating(&WizardController::OnPackagedLicenseScreenExit,
                           weak_factory_.GetWeakPtr())));
+  auto gaia_screen = std::make_unique<GaiaScreen>();
+  gaia_screen->set_view(oobe_ui->GetView<GaiaScreenHandler>());
+  append(std::move(gaia_screen));
 
   append(std::make_unique<TpmErrorScreen>(
       oobe_ui->GetView<TpmErrorScreenHandler>()));
@@ -631,10 +637,6 @@
     ShowLoginScreen();
 }
 
-void WizardController::LoginScreenStarted() {
-  SetCurrentScreen(nullptr);
-}
-
 void WizardController::ShowLoginScreen() {
   // This may be triggered by multiply asynchronous events from the JS side.
   if (login_screen_started_)
@@ -811,6 +813,8 @@
 
 void WizardController::SkipToLoginForTesting() {
   VLOG(1) << "SkipToLoginForTesting.";
+  if (current_screen_ && current_screen_->screen_id() == GaiaView::kScreenId)
+    return;
   wizard_context_->skip_non_forced_enrollment_for_tests = true;
   StartupUtils::MarkEulaAccepted();
 
@@ -1256,8 +1260,10 @@
   ShowMultiDeviceSetupScreen();
 }
 
-void WizardController::OnMultiDeviceSetupScreenExit() {
-  OnScreenExit(MultiDeviceSetupScreenView::kScreenId, kDefaultExitReason);
+void WizardController::OnMultiDeviceSetupScreenExit(
+    MultiDeviceSetupScreen::Result result) {
+  OnScreenExit(MultiDeviceSetupScreenView::kScreenId,
+               MultiDeviceSetupScreen::GetResultString(result));
 
   ShowGestureNavigationScreen();
 }
@@ -1289,11 +1295,17 @@
 }
 
 void WizardController::OnDeviceModificationCanceled() {
+  current_screen_->Hide();
+  current_screen_ = nullptr;
   if (previous_screen_) {
-    SetCurrentScreen(previous_screen_);
-  } else {
-    ShowPackagedLicenseScreen();
+    if (previous_screen_ == GetScreen(GaiaView::kScreenId)) {
+      ShowLoginScreen();
+    } else {
+      SetCurrentScreen(previous_screen_);
+    }
+    return;
   }
+  ShowPackagedLicenseScreen();
 }
 
 void WizardController::OnSupervisionTransitionScreenExit() {
@@ -1302,6 +1314,12 @@
   OnOobeFlowFinished();
 }
 
+void WizardController::OnUpdateRequiredScreenExit() {
+  current_screen_->Hide();
+  current_screen_ = nullptr;
+  ShowLoginScreen();
+}
+
 void WizardController::OnPackagedLicenseScreenExit(
     PackagedLicenseScreen::Result result) {
   OnScreenExit(PackagedLicenseView::kScreenId,
@@ -1622,7 +1640,8 @@
   } else if (screen_id == TpmErrorView::kScreenId ||
              screen_id == GaiaPasswordChangedView::kScreenId ||
              screen_id == ActiveDirectoryPasswordChangeView::kScreenId ||
-             screen_id == FamilyLinkNoticeView::kScreenId) {
+             screen_id == FamilyLinkNoticeView::kScreenId ||
+             screen_id == GaiaView::kScreenId) {
     SetCurrentScreen(GetScreen(screen_id));
   } else {
     if (is_out_of_box_) {
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h
index edef8d0..df34ffaa 100644
--- a/chrome/browser/chromeos/login/wizard_controller.h
+++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -36,6 +36,7 @@
 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
 #include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h"
 #include "chrome/browser/chromeos/login/screens/marketing_opt_in_screen.h"
+#include "chrome/browser/chromeos/login/screens/multidevice_setup_screen.h"
 #include "chrome/browser/chromeos/login/screens/network_screen.h"
 #include "chrome/browser/chromeos/login/screens/packaged_license_screen.h"
 #include "chrome/browser/chromeos/login/screens/recommend_apps_screen.h"
@@ -173,9 +174,6 @@
   void SetSharedURLLoaderFactoryForTesting(
       scoped_refptr<network::SharedURLLoaderFactory> factory);
 
-  // Resets |current_screen_| when login screen has started.
-  void LoginScreenStarted();
-
   // Configure and show GAIA password changed screen.
   void ShowGaiaPasswordChangedScreen(const AccountId& account_id,
                                      bool has_error);
@@ -267,12 +265,13 @@
   void OnRecommendAppsScreenExit(RecommendAppsScreen::Result result);
   void OnAppDownloadingScreenExit();
   void OnAssistantOptInFlowScreenExit(AssistantOptInFlowScreen::Result result);
-  void OnMultiDeviceSetupScreenExit();
+  void OnMultiDeviceSetupScreenExit(MultiDeviceSetupScreen::Result result);
   void OnGestureNavigationScreenExit(GestureNavigationScreen::Result result);
   void OnMarketingOptInScreenExit(MarketingOptInScreen::Result result);
   void OnResetScreenExit();
   void OnDeviceModificationCanceled();
   void OnSupervisionTransitionScreenExit();
+  void OnUpdateRequiredScreenExit();
   void OnOobeFlowFinished();
   void OnPackagedLicenseScreenExit(PackagedLicenseScreen::Result result);
   void OnActiveDirectoryPasswordChangeScreenExit();
diff --git a/chrome/browser/chromeos/policy/minimum_version_policy_handler_delegate_impl.cc b/chrome/browser/chromeos/policy/minimum_version_policy_handler_delegate_impl.cc
index d7f8943c..39d7648 100644
--- a/chrome/browser/chromeos/policy/minimum_version_policy_handler_delegate_impl.cc
+++ b/chrome/browser/chromeos/policy/minimum_version_policy_handler_delegate_impl.cc
@@ -86,11 +86,11 @@
       WizardController::default_controller();
   if (!wizard_controller)
     return;
-  chromeos::BaseScreen* screen = wizard_controller->current_screen();
-  if (screen &&
-      screen->screen_id() == chromeos::UpdateRequiredView::kScreenId) {
-    chromeos::LoginDisplayHost::default_host()->StartSignInScreen();
-  }
+  chromeos::UpdateRequiredScreen* screen =
+      chromeos::UpdateRequiredScreen::Get(wizard_controller->screen_manager());
+  if (screen->is_hidden())
+    return;
+  screen->Exit();
 }
 
 base::Version MinimumVersionPolicyHandlerDelegateImpl::GetCurrentVersion()
diff --git a/chrome/browser/chromeos/power/ml/recent_events_counter.cc b/chrome/browser/chromeos/power/ml/recent_events_counter.cc
index 677386c..16f3df49 100644
--- a/chrome/browser/chromeos/power/ml/recent_events_counter.cc
+++ b/chrome/browser/chromeos/power/ml/recent_events_counter.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "base/check_op.h"
+#include "base/numerics/safe_conversions.h"
 
 namespace chromeos {
 namespace power {
@@ -83,7 +84,8 @@
 int RecentEventsCounter::GetBucketIndex(base::TimeDelta timestamp) const {
   DCHECK_GE(timestamp, base::TimeDelta());
 
-  const int index = (timestamp % duration_).IntDiv(bucket_duration_);
+  const int index =
+      base::ClampFloor((timestamp % duration_) / bucket_duration_);
   DCHECK_GE(index, 0);
   DCHECK_LT(index, num_buckets_);
   return index;
diff --git a/chrome/browser/chromeos/system/device_disabling_browsertest.cc b/chrome/browser/chromeos/system/device_disabling_browsertest.cc
index bd672d71..d290cf9 100644
--- a/chrome/browser/chromeos/system/device_disabling_browsertest.cc
+++ b/chrome/browser/chromeos/system/device_disabling_browsertest.cc
@@ -214,6 +214,28 @@
   test::CreateOobeScreenWaiter("device-disabled")->Wait();
 }
 
+class DeviceDisablingWithUsersTest : public DeviceDisablingTest {
+ public:
+  DeviceDisablingWithUsersTest() { login_manager_.AppendRegularUsers(2); }
+
+ private:
+  LoginManagerMixin login_manager_{&mixin_host_};
+};
+
+// Checks that OOBE dialog is not hidden when the device disabled screen is
+// shown and "StartSignInScreen" is called.
+IN_PROC_BROWSER_TEST_F(DeviceDisablingWithUsersTest, DialogNotHidden) {
+  EXPECT_TRUE(ash::LoginScreenTestApi::ClickAddUserButton());
+  EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+  OobeScreenWaiter(GaiaView::kScreenId).Wait();
+  MarkDisabledAndWaitForPolicyFetch();
+  OobeScreenWaiter(DeviceDisabledScreenView::kScreenId).Wait();
+  LoginDisplayHost::default_host()->StartSignInScreen();
+
+  // Dialog should not be hidden.
+  EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+}
+
 // Sets the device disabled policy before the browser is started.
 class PresetPolicyDeviceDisablingTest : public DeviceDisablingTest {
  public:
diff --git a/chrome/browser/chromeos/web_applications/OWNERS b/chrome/browser/chromeos/web_applications/OWNERS
index 6e18da2..0c26b7e 100644
--- a/chrome/browser/chromeos/web_applications/OWNERS
+++ b/chrome/browser/chromeos/web_applications/OWNERS
@@ -3,6 +3,7 @@
 bugsnash@chromium.org
 ortuno@chromium.org
 
+per-file chrome_camera_app*=file://chromeos/components/camera_app_ui/OWNERS
 per-file chrome_help_app*=carpenterr@chromium.org
 per-file terminal_source*=calamity@chromium.org
 per-file terminal_source*=joelhockey@chromium.org
diff --git a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
new file mode 100644
index 0000000..3818678
--- /dev/null
+++ b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
@@ -0,0 +1,7 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h"
+
+ChromeCameraAppUIDelegate::ChromeCameraAppUIDelegate() = default;
diff --git a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h
new file mode 100644
index 0000000..1d05895
--- /dev/null
+++ b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_WEB_APPLICATIONS_CHROME_CAMERA_APP_UI_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_WEB_APPLICATIONS_CHROME_CAMERA_APP_UI_DELEGATE_H_
+
+#include "chromeos/components/camera_app_ui/camera_app_ui_delegate.h"
+
+/**
+ * Implementation of the CameraAppUIDelegate interface. Provides the camera app
+ * code in chromeos/ with functions that only exist in chrome/.
+ */
+class ChromeCameraAppUIDelegate : public CameraAppUIDelegate {
+ public:
+  ChromeCameraAppUIDelegate();
+
+  ChromeCameraAppUIDelegate(const ChromeCameraAppUIDelegate&) = delete;
+  ChromeCameraAppUIDelegate& operator=(const ChromeCameraAppUIDelegate&) =
+      delete;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_WEB_APPLICATIONS_CHROME_CAMERA_APP_UI_DELEGATE_H_
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index eb9ead26..4da81dc 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -142,6 +142,7 @@
 #include "services/device/public/mojom/wake_lock.mojom.h"
 #include "services/device/public/mojom/wake_lock_provider.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/page_transition_types.h"
 
@@ -3450,9 +3451,8 @@
   // resolve referrer_policy() into a concrete policy.
   auto policy_for_comparison = referrer_policy();
   if (policy_for_comparison == network::mojom::ReferrerPolicy::kDefault) {
-    policy_for_comparison =
-        content::Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-            content::Referrer::GetDefaultReferrerPolicy());
+    policy_for_comparison = blink::NetToMojoReferrerPolicy(
+        content::Referrer::GetDefaultReferrerPolicy());
   }
 
   switch (policy_for_comparison) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index e144396..818c8f6 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1243,11 +1243,6 @@
     "expiry_milestone": 86
   },
   {
-    "name": "enable-cloud-print-xps",
-    "owners": [ "//printing/OWNERS" ],
-    "expiry_milestone": 79
-  },
-  {
     "name": "enable-command-line-on-non-rooted-devices",
     "owners": [ "chrome-android-app" ],
     // This flag is used for debugging on Android; it causes Android Chromium
diff --git a/chrome/browser/importer/profile_writer_unittest.cc b/chrome/browser/importer/profile_writer_unittest.cc
index 61a567d..790f4cc 100644
--- a/chrome/browser/importer/profile_writer_unittest.cc
+++ b/chrome/browser/importer/profile_writer_unittest.cc
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/media/history/media_history_store_unittest.cc b/chrome/browser/media/history/media_history_store_unittest.cc
index 3026d2d2..0e53edf 100644
--- a/chrome/browser/media/history/media_history_store_unittest.cc
+++ b/chrome/browser/media/history/media_history_store_unittest.cc
@@ -272,6 +272,8 @@
   base::ScopedTempDir temp_dir_;
 
  protected:
+  // |features_| must outlive |task_environment_| to avoid TSAN issues.
+  base::test::ScopedFeatureList features_;
   content::BrowserTaskEnvironment task_environment_;
 
  private:
@@ -945,9 +947,6 @@
     run_loop.Run();
     return out;
   }
-
- private:
-  base::test::ScopedFeatureList features_;
 };
 
 INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/nearby_sharing/fake_nearby_connection.cc b/chrome/browser/nearby_sharing/fake_nearby_connection.cc
index 36bc464..a826874 100644
--- a/chrome/browser/nearby_sharing/fake_nearby_connection.cc
+++ b/chrome/browser/nearby_sharing/fake_nearby_connection.cc
@@ -5,7 +5,10 @@
 #include "chrome/browser/nearby_sharing/fake_nearby_connection.h"
 
 FakeNearbyConnection::FakeNearbyConnection() = default;
-FakeNearbyConnection::~FakeNearbyConnection() = default;
+FakeNearbyConnection::~FakeNearbyConnection() {
+  if (!closed_)
+    Close();
+}
 
 void FakeNearbyConnection::Read(ReadCallback callback) {
   DCHECK(!closed_);
diff --git a/chrome/browser/nearby_sharing/incoming_frames_reader.cc b/chrome/browser/nearby_sharing/incoming_frames_reader.cc
index 9f4f4ae..583e674 100644
--- a/chrome/browser/nearby_sharing/incoming_frames_reader.cc
+++ b/chrome/browser/nearby_sharing/incoming_frames_reader.cc
@@ -44,6 +44,27 @@
 IncomingFramesReader::~IncomingFramesReader() = default;
 
 void IncomingFramesReader::ReadFrame(
+    base::OnceCallback<void(base::Optional<sharing::mojom::V1FramePtr>)>
+        callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!callback_);
+  DCHECK(!is_process_stopped_);
+
+  callback_ = std::move(callback);
+  frame_type_ = base::nullopt;
+
+  // Check in cache for frame.
+  base::Optional<sharing::mojom::V1FramePtr> cached_frame =
+      GetCachedFrame(frame_type_);
+  if (cached_frame) {
+    Done(std::move(cached_frame));
+    return;
+  }
+
+  ReadNextFrame();
+}
+
+void IncomingFramesReader::ReadFrame(
     sharing::mojom::V1Frame::Tag frame_type,
     base::OnceCallback<void(base::Optional<sharing::mojom::V1FramePtr>)>
         callback,
@@ -64,14 +85,11 @@
   base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::BindOnce(timeout_callback_.callback()), timeout);
 
-  // Check in cache for frame of type |frame_type|.
-  auto iter = cached_frames_.find(frame_type);
-  if (iter != cached_frames_.end()) {
-    NS_LOG(VERBOSE) << __func__ << ": Successfully read cached frame of type "
-                    << frame_type;
-    sharing::mojom::V1FramePtr frame = std::move(iter->second);
-    cached_frames_.erase(iter);
-    Done(std::move(frame));
+  // Check in cache for frame.
+  base::Optional<sharing::mojom::V1FramePtr> cached_frame =
+      GetCachedFrame(frame_type_);
+  if (cached_frame) {
+    Done(std::move(cached_frame));
     return;
   }
 
@@ -113,8 +131,7 @@
   }
 
   if (!bytes) {
-    NS_LOG(WARNING) << __func__ << ": Failed to read frame of type "
-                    << frame_type_;
+    NS_LOG(WARNING) << __func__ << ": Failed to read frame";
     Done(base::nullopt);
     return;
   }
@@ -138,9 +155,9 @@
 
   sharing::mojom::V1FramePtr v1_frame(std::move(frame->get_v1()));
   sharing::mojom::V1Frame::Tag v1_frame_type = v1_frame->which();
-  if (frame_type_ != v1_frame_type) {
+  if (frame_type_ && *frame_type_ != v1_frame_type) {
     NS_LOG(WARNING) << __func__ << ": Failed to read frame of type "
-                    << frame_type_ << ", but got frame of type "
+                    << *frame_type_ << ", but got frame of type "
                     << v1_frame_type << ". Cached for later.";
     cached_frames_.insert({v1_frame_type, std::move(v1_frame)});
     ReadNextFrame();
@@ -156,6 +173,7 @@
     base::Optional<sharing::mojom::V1FramePtr> frame) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  frame_type_ = base::nullopt;
   timeout_callback_.Cancel();
   if (callback_) {
     std::move(callback_).Run(std::move(frame));
@@ -165,3 +183,21 @@
 void IncomingFramesReader::OnConnectionClosed() {
   connection_ = nullptr;
 }
+
+base::Optional<sharing::mojom::V1FramePtr> IncomingFramesReader::GetCachedFrame(
+    base::Optional<sharing::mojom::V1Frame::Tag> frame_type) {
+  NS_LOG(VERBOSE) << __func__ << ": Fetching cached frame";
+  if (frame_type)
+    NS_LOG(VERBOSE) << __func__ << ": Requested frame type - " << *frame_type;
+
+  auto iter =
+      frame_type ? cached_frames_.find(*frame_type) : cached_frames_.begin();
+
+  if (iter == cached_frames_.end())
+    return base::nullopt;
+
+  NS_LOG(VERBOSE) << __func__ << ": Successfully read cached frame";
+  sharing::mojom::V1FramePtr frame = std::move(iter->second);
+  cached_frames_.erase(iter);
+  return frame;
+}
diff --git a/chrome/browser/nearby_sharing/incoming_frames_reader.h b/chrome/browser/nearby_sharing/incoming_frames_reader.h
index b9505b71..5a11497 100644
--- a/chrome/browser/nearby_sharing/incoming_frames_reader.h
+++ b/chrome/browser/nearby_sharing/incoming_frames_reader.h
@@ -28,12 +28,22 @@
                        NearbyConnection* connection);
   ~IncomingFramesReader() override;
 
+  // Reads an incoming frame from |connection|. |callback| is called
+  // with the frame read from connection or nullopt if connection socket is
+  // closed.
+  //
+  // Note: Callers are expected wait for |callback| to be run before scheduling
+  // subsequent calls to ReadFrame(..).
+  void ReadFrame(
+      base::OnceCallback<void(base::Optional<sharing::mojom::V1FramePtr>)>
+          callback);
+
   // Reads a frame of type |frame_type| from |connection|. |callback| is called
   // with the frame read from connection or nullopt if connection socket is
   // closed or |timeout| units of time has passed.
   //
   // Note: Callers are expected wait for |callback| to be run before scheduling
-  // subsequent calls.
+  // subsequent calls to ReadFrame(..).
   void ReadFrame(
       sharing::mojom::V1Frame::Tag frame_type,
       base::OnceCallback<void(base::Optional<sharing::mojom::V1FramePtr>)>
@@ -52,11 +62,13 @@
   void OnTimeout();
   void Done(base::Optional<sharing::mojom::V1FramePtr> frame);
   void OnConnectionClosed();
+  base::Optional<sharing::mojom::V1FramePtr> GetCachedFrame(
+      base::Optional<sharing::mojom::V1Frame::Tag> frame_type);
 
   NearbyProcessManager* process_manager_;
   Profile* profile_;
   NearbyConnection* connection_;
-  sharing::mojom::V1Frame::Tag frame_type_;
+  base::Optional<sharing::mojom::V1Frame::Tag> frame_type_;
   base::OnceCallback<void(base::Optional<sharing::mojom::V1FramePtr>)>
       callback_;
   base::CancelableOnceClosure timeout_callback_;
diff --git a/chrome/browser/nearby_sharing/incoming_frames_reader_unittest.cc b/chrome/browser/nearby_sharing/incoming_frames_reader_unittest.cc
index 33d6709..5b10fa36 100644
--- a/chrome/browser/nearby_sharing/incoming_frames_reader_unittest.cc
+++ b/chrome/browser/nearby_sharing/incoming_frames_reader_unittest.cc
@@ -53,6 +53,12 @@
   EXPECT_TRUE((*frame)->is_introduction());
 }
 
+void ExpectCancelFrame(
+    const base::Optional<sharing::mojom::V1FramePtr>& frame) {
+  ASSERT_TRUE(frame);
+  EXPECT_TRUE((*frame)->is_cancel_frame());
+}
+
 }  // namespace
 
 class IncomingFramesReaderTest : public testing::Test {
@@ -102,6 +108,34 @@
   run_loop.Run();
 }
 
+TEST_F(IncomingFramesReaderTest, ReadAnyFrameSuccessful) {
+  std::vector<uint8_t> introduction_frame = GetIntroductionFrame();
+  connection().AppendReadableData(introduction_frame);
+
+  EXPECT_CALL(decoder(),
+              DecodeFrame(testing::Eq(introduction_frame), testing::_))
+      .WillOnce(testing::Invoke(
+          [&](const std::vector<uint8_t>& data,
+              MockNearbySharingDecoder::DecodeFrameCallback callback) {
+            sharing::mojom::V1FramePtr mojo_v1frame =
+                sharing::mojom::V1Frame::New();
+            mojo_v1frame->set_introduction(
+                sharing::mojom::IntroductionFrame::New());
+
+            sharing::mojom::FramePtr mojo_frame = sharing::mojom::Frame::New();
+            mojo_frame->set_v1(std::move(mojo_v1frame));
+            std::move(callback).Run(std::move(mojo_frame));
+          }));
+
+  base::RunLoop run_loop;
+  frames_reader().ReadFrame(base::BindLambdaForTesting(
+      [&](base::Optional<sharing::mojom::V1FramePtr> frame) {
+        ExpectIntroductionFrame(frame);
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
 TEST_F(IncomingFramesReaderTest, ReadSuccessful) {
   std::vector<uint8_t> introduction_frame = GetIntroductionFrame();
   connection().AppendReadableData(introduction_frame);
@@ -179,6 +213,61 @@
   run_loop_introduction.Run();
 }
 
+TEST_F(IncomingFramesReaderTest, JumbledFramesOrdering_ReadFromCache) {
+  std::vector<uint8_t> cancel_frame = GetCancelFrame();
+  connection().AppendReadableData(cancel_frame);
+
+  std::vector<uint8_t> introduction_frame = GetIntroductionFrame();
+  connection().AppendReadableData(introduction_frame);
+
+  EXPECT_CALL(decoder(), DecodeFrame(testing::_, testing::_))
+      .WillOnce(testing::Invoke(
+          [&](const std::vector<uint8_t>& data,
+              MockNearbySharingDecoder::DecodeFrameCallback callback) {
+            EXPECT_EQ(cancel_frame, data);
+            sharing::mojom::V1FramePtr mojo_v1frame =
+                sharing::mojom::V1Frame::New();
+            mojo_v1frame->set_cancel_frame(sharing::mojom::CancelFrame::New());
+
+            sharing::mojom::FramePtr mojo_frame = sharing::mojom::Frame::New();
+            mojo_frame->set_v1(std::move(mojo_v1frame));
+            std::move(callback).Run(std::move(mojo_frame));
+          }))
+      .WillOnce(testing::Invoke(
+          [&](const std::vector<uint8_t>& data,
+              MockNearbySharingDecoder::DecodeFrameCallback callback) {
+            EXPECT_EQ(introduction_frame, data);
+            sharing::mojom::V1FramePtr mojo_v1frame =
+                sharing::mojom::V1Frame::New();
+            mojo_v1frame->set_introduction(
+                sharing::mojom::IntroductionFrame::New());
+
+            sharing::mojom::FramePtr mojo_frame = sharing::mojom::Frame::New();
+            mojo_frame->set_v1(std::move(mojo_v1frame));
+            std::move(callback).Run(std::move(mojo_frame));
+          }));
+
+  base::RunLoop run_loop_introduction;
+  frames_reader().ReadFrame(
+      sharing::mojom::V1Frame::Tag::INTRODUCTION,
+      base::BindLambdaForTesting(
+          [&](base::Optional<sharing::mojom::V1FramePtr> frame) {
+            ExpectIntroductionFrame(frame);
+            run_loop_introduction.Quit();
+          }),
+      kTimeout);
+  run_loop_introduction.Run();
+
+  // Reading any frame should return CancelFrame.
+  base::RunLoop run_loop_cancel;
+  frames_reader().ReadFrame(base::BindLambdaForTesting(
+      [&](base::Optional<sharing::mojom::V1FramePtr> frame) {
+        ExpectCancelFrame(frame);
+        run_loop_cancel.Quit();
+      }));
+  run_loop_cancel.Run();
+}
+
 TEST_F(IncomingFramesReaderTest, ReadAfterConnectionClosed) {
   EXPECT_CALL(decoder(), DecodeFrame(testing::_, testing::_)).Times(0);
 
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
index 4f88f9d..0d1da02 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -890,7 +890,49 @@
       &NearbySharingServiceImpl::OnIncomingConnectionDisconnected,
       weak_ptr_factory_.GetWeakPtr(), share_target));
 
-  // TODO(himanshujaju) - start reader thread.
+  frames_reader->ReadFrame(base::BindOnce(
+      &NearbySharingServiceImpl::OnFrameRead, weak_ptr_factory_.GetWeakPtr(),
+      std::move(frames_reader), std::move(share_target)));
+}
+
+void NearbySharingServiceImpl::OnFrameRead(
+    std::unique_ptr<IncomingFramesReader> frames_reader,
+    ShareTarget share_target,
+    base::Optional<sharing::mojom::V1FramePtr> frame) {
+  if (!frame) {
+    // This is the case when the connection has been closed since we wait
+    // indefinitely for incoming frames.
+    return;
+  }
+
+  sharing::mojom::V1FramePtr v1_frame = std::move(*frame);
+  switch (v1_frame->which()) {
+    case sharing::mojom::V1Frame::Tag::CANCEL_FRAME:
+      NS_LOG(VERBOSE) << __func__
+                      << ": Read the cancel frame, closing connection";
+      Cancel(share_target, base::DoNothing());
+      break;
+
+    case sharing::mojom::V1Frame::Tag::CERTIFICATE_INFO:
+      HandleCertificateInfoFrame(v1_frame->get_certificate_info());
+      break;
+
+    default:
+      NS_LOG(VERBOSE) << __func__ << ": Discarding unknown frame of type";
+      break;
+  }
+
+  frames_reader->ReadFrame(base::BindOnce(
+      &NearbySharingServiceImpl::OnFrameRead, weak_ptr_factory_.GetWeakPtr(),
+      std::move(frames_reader), std::move(share_target)));
+}
+
+void NearbySharingServiceImpl::HandleCertificateInfoFrame(
+    const sharing::mojom::CertificateInfoFramePtr& certificate_frame) {
+  DCHECK(certificate_frame);
+
+  // TODO(himanshujaju) - Convert all certificates to PublicShare proto and add
+  // to certificate manager
 }
 
 void NearbySharingServiceImpl::OnIncomingConnectionDisconnected(
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
index bf5aa3a..858865c 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -150,6 +150,12 @@
       base::Optional<std::string> token,
       std::unique_ptr<IncomingFramesReader> frames_reader,
       base::Optional<sharing::mojom::V1FramePtr> frame);
+  void OnFrameRead(std::unique_ptr<IncomingFramesReader> frames_reader,
+                   ShareTarget share_target,
+                   base::Optional<sharing::mojom::V1FramePtr> frame);
+  void HandleCertificateInfoFrame(
+      const sharing::mojom::CertificateInfoFramePtr& certificate_frame);
+
   void OnIncomingConnectionDisconnected(const ShareTarget& share_target);
   void UnregisterShareTarget(const ShareTarget& share_target);
   bool IsOutOfStorage(const ShareTarget& share_target);
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
index 6c5bb0a..b5169dd 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
@@ -12,6 +12,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/bind_test_util.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
 #include "chrome/browser/nearby_sharing/fake_nearby_connection.h"
 #include "chrome/browser/nearby_sharing/fake_nearby_connections_manager.h"
@@ -142,6 +144,7 @@
 class NearbySharingServiceImplTest : public testing::Test {
  public:
   NearbySharingServiceImplTest() {
+    scoped_feature_list_.InitAndEnableFeature(features::kNearbySharing);
     RegisterNearbySharingPrefs(prefs_.registry());
   }
 
@@ -216,6 +219,7 @@
   }
 
  protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   ui::ScopedSetIdleState idle_state_{ui::IDLE_STATE_IDLE};
   TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
@@ -766,6 +770,9 @@
 
   service_->OnIncomingConnection("endpoint_id", {}, &connection);
   run_loop.Run();
+
+  // To avoid UAF in OnIncomingTransferUpdate().
+  service_->UnregisterReceiveSurface(&callback);
 }
 
 TEST_F(NearbySharingServiceImplTest,
@@ -823,4 +830,7 @@
 
   service_->OnIncomingConnection("endpoint_id", {}, &connection);
   run_loop.Run();
+
+  // To avoid UAF in OnIncomingTransferUpdate().
+  service_->UnregisterReceiveSurface(&callback);
 }
diff --git a/chrome/browser/net/cert_verify_proc_browsertest.cc b/chrome/browser/net/cert_verify_proc_browsertest.cc
index c6c65b0..479b23a 100644
--- a/chrome/browser/net/cert_verify_proc_browsertest.cc
+++ b/chrome/browser/net/cert_verify_proc_browsertest.cc
@@ -43,7 +43,7 @@
     // Try for up to 5 seconds to read the netlog file.
     constexpr auto kMaxWaitTime = base::TimeDelta::FromSeconds(5);
     constexpr auto kWaitInterval = base::TimeDelta::FromMilliseconds(50);
-    int tries_left = kMaxWaitTime.FltDiv(kWaitInterval);
+    int tries_left = kMaxWaitTime / kWaitInterval;
 
     base::Optional<base::Value> parsed_net_log;
     while (true) {
diff --git a/chrome/browser/password_check/android/BUILD.gn b/chrome/browser/password_check/android/BUILD.gn
index 237d2a5..683dce8e 100644
--- a/chrome/browser/password_check/android/BUILD.gn
+++ b/chrome/browser/password_check/android/BUILD.gn
@@ -12,6 +12,17 @@
   deps = [ "//components/password_manager/core/browser" ]
 }
 
+java_cpp_enum("password_check_enums_srcjar") {
+  sources = [ "password_check_ui_status.h" ]
+}
+
+# Wrap the java_cpp_enum in android_library so it can be used by both
+# chrome_java and modules.
+android_library("password_check_java_enums") {
+  deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ]
+  srcjar_deps = [ ":password_check_enums_srcjar" ]
+}
+
 source_set("unit_tests") {
   testonly = true
   sources = [ "bulk_leak_check_controller_android_unittest.cc" ]
@@ -25,6 +36,7 @@
 android_library("public_java") {
   deps = [
     ":java_resources",
+    ":password_check_java_enums",
     ":public_ui_java",
     "internal:public_ui_factory_java",
     "//base:base_java",
@@ -63,6 +75,7 @@
     "internal:public_ui_factory_java",
     "//base:base_java",
     "//base:base_junit_test_support",
+    "//chrome/browser/password_check/android:password_check_java_enums",
     "//chrome/browser/password_check/android:public_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/junit",
@@ -89,6 +102,7 @@
     "//chrome/android:chrome_test_java",
     "//chrome/android:chrome_test_util_java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/password_check/android:password_check_java_enums",
     "//chrome/browser/password_check/android/internal:public_factory_java",
     "//chrome/browser/settings:test_support_java",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/password_check/android/internal/BUILD.gn b/chrome/browser/password_check/android/internal/BUILD.gn
index 65998f8..fb4cb70 100644
--- a/chrome/browser/password_check/android/internal/BUILD.gn
+++ b/chrome/browser/password_check/android/internal/BUILD.gn
@@ -58,6 +58,7 @@
     "//base:jni_java",
     "//chrome/android:chrome_app_java_resources",
     "//chrome/android:chrome_java",
+    "//chrome/browser/password_check/android:password_check_java_enums",
     "//chrome/browser/password_check/android:public_ui_java",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/settings:java",
@@ -86,24 +87,14 @@
 }
 
 generate_jni("jni_headers") {
-  visibility = [ ":*" ]
+  visibility = [ "//chrome/browser" ]
   sources = [ "java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java" ]
 }
 
-source_set("internal") {
-  deps = [
-    ":jni_headers",
-    "//base:base",
-  ]
-  sources = [
-    "password_check_bridge.cc",
-    "password_check_bridge.h",
-  ]
-}
-
 android_resources("java_resources") {
   deps = [ ":java_strings_grd" ]
   sources = [
+    "java/res/drawable/ic_autofill_assistant_white_24dp.xml",
     "java/res/layout/password_check_compromised_credential_item.xml",
     "java/res/layout/password_check_compromised_credential_with_script_item.xml",
     "java/res/layout/password_check_header_item.xml",
diff --git a/chrome/browser/password_check/android/internal/java/res/drawable/ic_autofill_assistant_white_24dp.xml b/chrome/browser/password_check/android/internal/java/res/drawable/ic_autofill_assistant_white_24dp.xml
new file mode 100644
index 0000000..c4e3af5
--- /dev/null
+++ b/chrome/browser/password_check/android/internal/java/res/drawable/ic_autofill_assistant_white_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:targetApi="21"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="192"
+    android:viewportHeight="192">
+  <path
+      android:pathData="M172,60m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0"
+      android:fillColor="@color/default_text_color_inverse" />
+  <path
+      android:pathData="M136,88m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"
+      android:fillColor="@color/default_text_color_inverse" />
+  <path
+      android:pathData="M136,148m-28,0a28,28 0,1 1,56 0a28,28 0,1 1,-56 0"
+      android:fillColor="@color/default_text_color_inverse" />
+  <path
+      android:pathData="M56,64m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"
+      android:fillColor="@color/default_text_color_inverse" />
+</vector>
diff --git a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml
index 31005bb..4982258 100644
--- a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml
+++ b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml
@@ -47,6 +47,8 @@
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             android:text="@string/password_check_credential_row_change_button_with_script_caption"
+            android:drawablePadding="3dp"
+            android:drawableStart="@drawable/ic_autofill_assistant_white_24dp"
             style="@style/FilledButton.Flat" />
 
          <TextView
@@ -62,7 +64,8 @@
             android:layout_marginTop="@dimen/compromised_credential_row_button_margin_top"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
-            android:text="@string/password_check_credential_row_change_button_caption"  />
+            android:text="@string/password_check_credential_row_change_button_caption"
+            style="@style/TextButton"/>
 
     </LinearLayout>
 
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java
index 4a6a88e..965dbb2 100644
--- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java
+++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.password_check;
 
+import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
 
 /**
@@ -37,12 +38,18 @@
          * @param count The total number of saved passwords.
          */
         void onSavedPasswordsFetched(int count);
+
+        /**
+         * Called when the password check status changes, e.g. from idle to running.
+         * @param status The current status of the password check.
+         */
+        void onPasswordCheckStatusChanged(@PasswordCheckUIStatus int status);
     }
 
     PasswordCheckBridge(PasswordCheckObserver passwordCheckObserver) {
         // Initialized its native counterpart. This will also start fetching the compromised
         // credentials stored in the database by the last check.
-        mNativePasswordCheckBridge = PasswordCheckBridgeJni.get().create();
+        mNativePasswordCheckBridge = PasswordCheckBridgeJni.get().create(this);
         mPasswordCheckObserver = passwordCheckObserver;
     }
 
@@ -61,6 +68,11 @@
         mPasswordCheckObserver.onSavedPasswordsFetched(count);
     }
 
+    @CalledByNative
+    void onPasswordCheckStatusChanged(@PasswordCheckUIStatus int state) {
+        mPasswordCheckObserver.onPasswordCheckStatusChanged(state);
+    }
+
     private static void insertCredential(CompromisedCredential[] credentials, int index,
             String originUrl, String username, String password, boolean phished,
             boolean hasScript) {
@@ -123,7 +135,7 @@
      */
     @NativeMethods
     interface Natives {
-        long create();
+        long create(PasswordCheckBridge passwordCheckBridge);
         void startCheck(long nativePasswordCheckBridge);
         void stopCheck(long nativePasswordCheckBridge);
         int getCompromisedCredentialsCount(long nativePasswordCheckBridge);
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckImpl.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckImpl.java
index 1fa378a..779a9e8d 100644
--- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckImpl.java
+++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckImpl.java
@@ -26,7 +26,7 @@
         mCompromisedCredentialsFetched = false;
         mSavedPasswordsFetched = false;
         mPasswordCheckBridge = new PasswordCheckBridge(this);
-        mObserverList = new ObserverList<Observer>();
+        mObserverList = new ObserverList<>();
     }
 
     @Override
@@ -65,6 +65,13 @@
     }
 
     @Override
+    public void onPasswordCheckStatusChanged(int status) {
+        for (Observer obs : mObserverList) {
+            obs.onPasswordCheckStatusChanged(status);
+        }
+    }
+
+    @Override
     public void removeCredential(CompromisedCredential credential) {
         // TODO(crbug.com/1106726): Call native method through bridge.
     }
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java
index 2b14dda..fe63908b3 100644
--- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java
+++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java
@@ -9,7 +9,6 @@
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
 
-import org.chromium.chrome.browser.password_check.PasswordCheck.CheckStatus;
 import org.chromium.ui.modelutil.ListModel;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -47,7 +46,7 @@
         }
     }
 
-    void onPasswordCheckStatusChanged(@CheckStatus int status) {
+    void onPasswordCheckStatusChanged(@PasswordCheckUIStatus int status) {
         ListModel<ListItem> items = mModel.get(ITEMS);
         if (items.size() == 0) {
             items.add(new ListItem(PasswordCheckProperties.ItemType.HEADER,
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
index 2d06f4e..93d40fb 100644
--- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
+++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
@@ -16,7 +16,6 @@
 import android.widget.ImageButton;
 import android.widget.TextView;
 
-import org.chromium.chrome.browser.password_check.PasswordCheck.CheckStatus;
 import org.chromium.chrome.browser.password_check.PasswordCheckProperties.ItemType;
 import org.chromium.chrome.browser.password_check.internal.R;
 import org.chromium.components.browser_ui.widget.listmenu.BasicListMenu;
@@ -155,10 +154,10 @@
     private static void bindHeaderView(PropertyModel model, View view, PropertyKey key) {
         if (key == CHECK_STATUS) {
             // TODO(crbug.com/1101256): Set text and illustration based on status.
-            @CheckStatus
+            @PasswordCheckUIStatus
             int status = model.get(CHECK_STATUS);
             ImageButton restartButton = view.findViewById(R.id.check_status_restart_button);
-            if (status != CheckStatus.RUNNING) {
+            if (status != PasswordCheckUIStatus.RUNNING) {
                 restartButton.setVisibility(View.VISIBLE);
                 restartButton.setClickable(true);
                 restartButton.setOnClickListener(unusedView
diff --git a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheck.java b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheck.java
index ed3bf0a8..b1c3bda 100644
--- a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheck.java
+++ b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheck.java
@@ -6,38 +6,12 @@
 
 import android.content.Context;
 
-import androidx.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * This component allows to check for compromised passwords. It provides a settings page which shows
  * the compromised passwords and exposes actions that will help the users to make safer their
  * credentials.
  */
 public interface PasswordCheck extends PasswordCheckComponentUi.Delegate {
-    @IntDef({CheckStatus.SUCCESS, CheckStatus.RUNNING, CheckStatus.ERROR_OFFLINE,
-            CheckStatus.ERROR_NO_PASSWORDS, CheckStatus.ERROR_SIGNED_OUT,
-            CheckStatus.ERROR_QUOTA_LIMIT, CheckStatus.ERROR_UNKNOWN})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CheckStatus {
-        /** The check was completed without errors. */
-        int SUCCESS = 1;
-        /** The check is still running. */
-        int RUNNING = 2;
-        /** The check cannot run because the user is offline. */
-        int ERROR_OFFLINE = 3;
-        /** The check cannot run because the user has no passwords on this device. */
-        int ERROR_NO_PASSWORDS = 4;
-        /** The check is cannot run because the user is signed-out. */
-        int ERROR_SIGNED_OUT = 5;
-        /** The check is cannot run because the user has exceeded their quota. */
-        int ERROR_QUOTA_LIMIT = 6;
-        /** The check is cannot run for unknown reasons. */
-        int ERROR_UNKNOWN = 6;
-    }
-
     /** Observes events and state changes of the password check. */
     interface Observer {
         /**
@@ -56,7 +30,7 @@
          * Gets invoked once the password check stops running.
          * @param status A {@link CheckStatus} enum value.
          */
-        void onPasswordCheckStateChanged(@CheckStatus int status);
+        void onPasswordCheckStatusChanged(@PasswordCheckUIStatus int status);
     }
 
     /**
diff --git a/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java b/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java
index 6856c7c..f75fd9f 100644
--- a/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java
+++ b/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java
@@ -43,7 +43,6 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.password_check.PasswordCheck.CheckStatus;
 import org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties;
 import org.chromium.chrome.browser.password_check.internal.R;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
@@ -101,7 +100,7 @@
     @MediumTest
     public void testDisplaysHeaderAndCredential() {
         runOnUiThreadBlocking(() -> {
-            mModel.get(ITEMS).add(buildHeader(CheckStatus.SUCCESS));
+            mModel.get(ITEMS).add(buildHeader(PasswordCheckUIStatus.IDLE));
             mModel.get(ITEMS).add(buildCredentialItem(ANA));
         });
         pollUiThread(() -> Criteria.checkThat(getPasswordCheckViewList().getChildCount(), is(2)));
@@ -121,7 +120,8 @@
     @Test
     @MediumTest
     public void testStatusDisplaysRestartAction() {
-        runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(CheckStatus.SUCCESS)); });
+        runOnUiThreadBlocking(
+                () -> { mModel.get(ITEMS).add(buildHeader(PasswordCheckUIStatus.IDLE)); });
         pollUiThread(() -> Criteria.checkThat(getPasswordCheckViewList().getChildCount(), is(1)));
         assertThat(getActionButton().getVisibility(), is(View.VISIBLE));
     }
@@ -129,7 +129,8 @@
     @Test
     @MediumTest
     public void testStatusNotDisplaysRestartAction() {
-        runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(CheckStatus.RUNNING)); });
+        runOnUiThreadBlocking(
+                () -> { mModel.get(ITEMS).add(buildHeader(PasswordCheckUIStatus.RUNNING)); });
         pollUiThread(() -> Criteria.checkThat(getPasswordCheckViewList().getChildCount(), is(1)));
         assertThat(getActionButton().getVisibility(), is(View.GONE));
     }
@@ -225,7 +226,7 @@
         verify(mMockHandler).onRemove(eq(ANA));
     }
 
-    private MVCListAdapter.ListItem buildHeader(@CheckStatus int status) {
+    private MVCListAdapter.ListItem buildHeader(@PasswordCheckUIStatus int status) {
         return new MVCListAdapter.ListItem(PasswordCheckProperties.ItemType.HEADER,
                 new PropertyModel.Builder(HeaderProperties.ALL_KEYS)
                         .with(CHECK_STATUS, status)
diff --git a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java
index 8bbbecc..4e3749c 100644
--- a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java
+++ b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java
@@ -10,11 +10,11 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 
-import static org.chromium.chrome.browser.password_check.PasswordCheck.CheckStatus.SUCCESS;
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.COMPROMISED_CREDENTIAL;
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.CREDENTIAL_HANDLER;
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS;
 import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.ITEMS;
+import static org.chromium.chrome.browser.password_check.PasswordCheckUIStatus.IDLE;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -60,11 +60,11 @@
 
     @Test
     public void testCreatesHeaderAndEntryForCredentials() {
-        mMediator.onPasswordCheckStatusChanged(SUCCESS);
+        mMediator.onPasswordCheckStatusChanged(IDLE);
         mMediator.onCompromisedCredentialsAvailable(Collections.singletonList(ANA));
         ListModel<MVCListAdapter.ListItem> itemList = mModel.get(ITEMS);
         assertThat(itemList.get(0).type, is(ItemType.HEADER));
-        assertThat(itemList.get(0).model.get(CHECK_STATUS), is(SUCCESS));
+        assertThat(itemList.get(0).model.get(CHECK_STATUS), is(IDLE));
         assertThat(itemList.get(1).type, is(ItemType.COMPROMISED_CREDENTIAL));
         assertThat(itemList.get(1).model.get(COMPROMISED_CREDENTIAL), is(ANA));
         assertThat(itemList.get(1).model.get(CREDENTIAL_HANDLER), is(mMediator));
diff --git a/chrome/browser/password_check/android/internal/password_check_bridge.cc b/chrome/browser/password_check/android/password_check_bridge.cc
similarity index 61%
rename from chrome/browser/password_check/android/internal/password_check_bridge.cc
rename to chrome/browser/password_check/android/password_check_bridge.cc
index 083524d..d0ae7c4 100644
--- a/chrome/browser/password_check/android/internal/password_check_bridge.cc
+++ b/chrome/browser/password_check/android/password_check_bridge.cc
@@ -2,17 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/password_check/android/internal/password_check_bridge.h"
+#include "chrome/browser/password_check/android/password_check_bridge.h"
 
 #include <jni.h>
 
 #include "chrome/browser/password_check/android/internal/jni_headers/PasswordCheckBridge_jni.h"
 
-static jlong JNI_PasswordCheckBridge_Create(JNIEnv* env) {
-  return reinterpret_cast<intptr_t>(new PasswordCheckBridge());
+static jlong JNI_PasswordCheckBridge_Create(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& java_bridge) {
+  return reinterpret_cast<intptr_t>(new PasswordCheckBridge(java_bridge));
 }
 
-PasswordCheckBridge::PasswordCheckBridge() = default;
+PasswordCheckBridge::PasswordCheckBridge(
+    const base::android::JavaParamRef<jobject>& java_bridge)
+    : java_bridge_(java_bridge) {}
 PasswordCheckBridge::~PasswordCheckBridge() = default;
 
 void PasswordCheckBridge::StartCheck(JNIEnv* env) {
@@ -42,3 +46,10 @@
 void PasswordCheckBridge::Destroy(JNIEnv* env) {
   delete this;
 }
+
+void PasswordCheckBridge::OnPasswordCheckStatusChanged(
+    password_manager::PasswordCheckUIStatus status) {
+  Java_PasswordCheckBridge_onPasswordCheckStatusChanged(
+      base::android::AttachCurrentThread(), java_bridge_,
+      static_cast<int>(status));
+}
diff --git a/chrome/browser/password_check/android/internal/password_check_bridge.h b/chrome/browser/password_check/android/password_check_bridge.h
similarity index 65%
rename from chrome/browser/password_check/android/internal/password_check_bridge.h
rename to chrome/browser/password_check/android/password_check_bridge.h
index f111288..7d706038 100644
--- a/chrome/browser/password_check/android/internal/password_check_bridge.h
+++ b/chrome/browser/password_check/android/password_check_bridge.h
@@ -2,17 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_PASSWORD_CHECK_ANDROID_INTERNAL_PASSWORD_CHECK_BRIDGE_H_
-#define CHROME_BROWSER_PASSWORD_CHECK_ANDROID_INTERNAL_PASSWORD_CHECK_BRIDGE_H_
+#ifndef CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_BRIDGE_H_
+#define CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_BRIDGE_H_
 
 #include <jni.h>
 #include "base/android/scoped_java_ref.h"
+#include "chrome/browser/password_check/android/password_check_ui_status.h"
 
 // C++ counterpart of |PasswordCheckBridge.java|. Used to mediate the
 // communication between the UI and the password check logic.
 class PasswordCheckBridge {
  public:
-  PasswordCheckBridge();
+  explicit PasswordCheckBridge(
+      const base::android::JavaParamRef<jobject>& java_bridge);
   PasswordCheckBridge(const PasswordCheckBridge&) = delete;
   PasswordCheckBridge& operator=(const PasswordCheckBridge&) = delete;
 
@@ -36,8 +38,15 @@
   // Called by Java when the bridge is no longer needed. Destructs itself.
   void Destroy(JNIEnv* env);
 
+  // Called by the check manager when the status of the check changes.
+  void OnPasswordCheckStatusChanged(
+      password_manager::PasswordCheckUIStatus status);
+
  private:
   ~PasswordCheckBridge();
+
+  // The corresponding java object.
+  base::android::ScopedJavaGlobalRef<jobject> java_bridge_;
 };
 
-#endif  // CHROME_BROWSER_PASSWORD_CHECK_ANDROID_INTERNAL_PASSWORD_CHECK_BRIDGE_H_
+#endif  // CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_BRIDGE_H_
diff --git a/chrome/browser/password_check/android/password_check_ui_status.h b/chrome/browser/password_check/android/password_check_ui_status.h
new file mode 100644
index 0000000..25d93e5
--- /dev/null
+++ b/chrome/browser/password_check/android/password_check_ui_status.h
@@ -0,0 +1,29 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_UI_STATUS_H_
+#define CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_UI_STATUS_H_
+
+namespace password_manager {
+
+// Enumerates the possible states of the password check, in a way that can be
+// used to display information in the password check header.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.password_check
+enum class PasswordCheckUIStatus {
+  kIdle,
+  kRunning,
+  kCanceled,
+  kErrorOffline,
+  kErrorNoPasswords,
+  kErrorSignedOut,
+  kErrorQuotaLimit,
+  kErrorQuotaLimitAccountCheck,
+  kErrorUnknown,
+};
+
+}  // namespace password_manager
+
+#endif  // CHROME_BROWSER_PASSWORD_CHECK_ANDROID_PASSWORD_CHECK_UI_STATUS_H_
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn
new file mode 100644
index 0000000..8abe1e4
--- /dev/null
+++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+android_library("java") {
+  deps = [
+    "//base:base_java",
+    "//chrome/browser/settings:java",
+    "//components/password_manager/core/browser:password_manager_java_enums",
+  ]
+  sources = [ "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java" ]
+}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java
new file mode 100644
index 0000000..ac5ae0c9
--- /dev/null
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java
@@ -0,0 +1,39 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.password_manager;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.settings.SettingsLauncher;
+
+/** A helper class for showing PasswordSettings. */
+public class PasswordManagerHelper {
+    // Key for the argument with which PasswordsSettings will be launched. The value for
+    // this argument should be part of the ManagePasswordsReferrer enum, which contains
+    // all points of entry to the passwords settings.
+    public static final String MANAGE_PASSWORDS_REFERRER = "manage-passwords-referrer";
+
+    // |PasswordSettings| full class name to open the fragment. Will be changed to
+    // |PasswordSettings.class.getName()| once it's modularized.
+    private static final String PASSWORD_SETTINGS_CLASS =
+            "org.chromium.chrome.browser.password_manager.settings.PasswordSettings";
+
+    /**
+     * Launches the password settings in or the Google Password Manager if available.
+     * @param context used to show the UI to manage passwords.
+     */
+    public static void showPasswordSettings(Context context, @ManagePasswordsReferrer int referrer,
+            SettingsLauncher settingsLauncher) {
+        RecordHistogram.recordEnumeratedHistogram("PasswordManager.ManagePasswordsReferrer",
+                referrer, ManagePasswordsReferrer.MAX_VALUE + 1);
+
+        Bundle fragmentArgs = new Bundle();
+        fragmentArgs.putInt(MANAGE_PASSWORDS_REFERRER, referrer);
+        context.startActivity(settingsLauncher.createSettingsActivityIntent(
+                context, PASSWORD_SETTINGS_CLASS, fragmentArgs));
+    }
+}
diff --git a/chrome/browser/prerender/chrome_prerender_contents_delegate.h b/chrome/browser/prerender/chrome_prerender_contents_delegate.h
index fe90149a..c2b2965 100644
--- a/chrome/browser/prerender/chrome_prerender_contents_delegate.h
+++ b/chrome/browser/prerender/chrome_prerender_contents_delegate.h
@@ -4,7 +4,7 @@
 #ifndef CHROME_BROWSER_PRERENDER_CHROME_PRERENDER_CONTENTS_DELEGATE_H_
 #define CHROME_BROWSER_PRERENDER_CHROME_PRERENDER_CONTENTS_DELEGATE_H_
 
-#include "chrome/browser/prerender/prerender_contents_delegate.h"
+#include "components/prerender/browser/prerender_contents_delegate.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 
diff --git a/chrome/browser/prerender/chrome_prerender_manager_delegate.cc b/chrome/browser/prerender/chrome_prerender_manager_delegate.cc
index 6dcaf67..9c0c501 100644
--- a/chrome/browser/prerender/chrome_prerender_manager_delegate.cc
+++ b/chrome/browser/prerender/chrome_prerender_manager_delegate.cc
@@ -8,12 +8,12 @@
 #include "chrome/browser/predictors/loading_predictor.h"
 #include "chrome/browser/predictors/loading_predictor_factory.h"
 #include "chrome/browser/prerender/chrome_prerender_contents_delegate.h"
-#include "chrome/browser/prerender/prerender_manager_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/common/chrome_features.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
+#include "components/prerender/browser/prerender_manager_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -52,4 +52,65 @@
 ChromePrerenderManagerDelegate::GetPrerenderContentsDelegate() {
   return std::make_unique<ChromePrerenderContentsDelegate>();
 }
+
+bool ChromePrerenderManagerDelegate::IsPredictionEnabled(Origin origin) {
+  return GetPredictionStatusForOrigin(origin) ==
+         chrome_browser_net::NetworkPredictionStatus::ENABLED;
+}
+
+bool ChromePrerenderManagerDelegate::IsPredictionDisabledDueToNetwork(
+    Origin origin) {
+  return GetPredictionStatusForOrigin(origin) ==
+         chrome_browser_net::NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK;
+}
+
+bool ChromePrerenderManagerDelegate::IsPredictionEnabled() {
+  return GetPredictionStatus() ==
+         chrome_browser_net::NetworkPredictionStatus::ENABLED;
+}
+
+std::string ChromePrerenderManagerDelegate::GetReasonForDisablingPrediction() {
+  std::string disabled_note;
+  if (GetPredictionStatus() ==
+      chrome_browser_net::NetworkPredictionStatus::DISABLED_ALWAYS)
+    disabled_note = "Disabled by user setting";
+  if (GetPredictionStatus() ==
+      chrome_browser_net::NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK)
+    disabled_note = "Disabled on cellular connection by default";
+  return disabled_note;
+}
+
+chrome_browser_net::NetworkPredictionStatus
+ChromePrerenderManagerDelegate::GetPredictionStatus() const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
+}
+
+chrome_browser_net::NetworkPredictionStatus
+ChromePrerenderManagerDelegate::GetPredictionStatusForOrigin(
+    Origin origin) const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // <link rel=prerender> origins ignore the network state and the privacy
+  // settings. Web developers should be able prefetch with all possible privacy
+  // settings and with all possible network types. This would avoid web devs
+  // coming up with creative ways to prefetch in cases they are not allowed to
+  // do so.
+  if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN ||
+      origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) {
+    return chrome_browser_net::NetworkPredictionStatus::ENABLED;
+  }
+
+  // Prerendering forced for cellular networks still prevents navigation with
+  // the DISABLED_ALWAYS selected via privacy settings.
+  chrome_browser_net::NetworkPredictionStatus prediction_status =
+      chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
+  if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER &&
+      prediction_status == chrome_browser_net::NetworkPredictionStatus::
+                               DISABLED_DUE_TO_NETWORK) {
+    return chrome_browser_net::NetworkPredictionStatus::ENABLED;
+  }
+  return prediction_status;
+}
+
 }  // namespace prerender
diff --git a/chrome/browser/prerender/chrome_prerender_manager_delegate.h b/chrome/browser/prerender/chrome_prerender_manager_delegate.h
index a0114f2..6d8f2af 100644
--- a/chrome/browser/prerender/chrome_prerender_manager_delegate.h
+++ b/chrome/browser/prerender/chrome_prerender_manager_delegate.h
@@ -5,7 +5,8 @@
 #ifndef CHROME_BROWSER_PRERENDER_CHROME_PRERENDER_MANAGER_DELEGATE_H_
 #define CHROME_BROWSER_PRERENDER_CHROME_PRERENDER_MANAGER_DELEGATE_H_
 
-#include "chrome/browser/prerender/prerender_manager_delegate.h"
+#include "chrome/browser/net/prediction_options.h"
+#include "components/prerender/browser/prerender_manager_delegate.h"
 
 class Profile;
 
@@ -25,8 +26,15 @@
   void MaybePreconnect(const GURL& url) override;
   std::unique_ptr<PrerenderContentsDelegate> GetPrerenderContentsDelegate()
       override;
+  bool IsPredictionEnabled(Origin origin) override;
+  bool IsPredictionEnabled() override;
+  bool IsPredictionDisabledDueToNetwork(Origin origin) override;
+  std::string GetReasonForDisablingPrediction() override;
 
  private:
+  chrome_browser_net::NetworkPredictionStatus GetPredictionStatus() const;
+  chrome_browser_net::NetworkPredictionStatus GetPredictionStatusForOrigin(
+      Origin origin) const;
   Profile* profile_;
 };
 
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index f265b722..e72823ad 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -15,8 +15,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
 #include "build/build_config.h"
-#include "chrome/browser/prerender/prerender_contents_delegate.h"
 #include "chrome/browser/prerender/prerender_manager.h"
+#include "components/prerender/browser/prerender_contents_delegate.h"
 #include "components/prerender/common/prerender_final_status.h"
 #include "components/prerender/common/prerender_util.h"
 #include "components/prerender/common/render_frame_prerender_messages.mojom.h"
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index 516e2b92..8e4c653 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -18,7 +18,7 @@
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "base/values.h"
-#include "chrome/browser/prerender/prerender_contents_delegate.h"
+#include "components/prerender/browser/prerender_contents_delegate.h"
 #include "components/prerender/common/prerender_canceler.mojom.h"
 #include "components/prerender/common/prerender_final_status.h"
 #include "components/prerender/common/prerender_origin.h"
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 806b345..48a0a8b 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -31,18 +31,13 @@
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
-#include "chrome/browser/net/prediction_options.h"
-#include "chrome/browser/predictors/loading_predictor.h"
-#include "chrome/browser/predictors/loading_predictor_factory.h"
 #include "chrome/browser/prerender/prerender_contents.h"
 #include "chrome/browser/prerender/prerender_field_trial.h"
 #include "chrome/browser/prerender/prerender_handle.h"
-#include "chrome/browser/prerender/prerender_manager_delegate.h"
-#include "chrome/browser/prerender/prerender_tab_helper.h"
-#include "chrome/browser/profiles/profile.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/prerender/browser/prerender_histograms.h"
 #include "components/prerender/browser/prerender_history.h"
+#include "components/prerender/browser/prerender_manager_delegate.h"
 #include "components/prerender/browser/prerender_util.h"
 #include "components/prerender/common/prerender_final_status.h"
 #include "components/prerender/common/prerender_types.mojom.h"
@@ -62,7 +57,6 @@
 #include "third_party/blink/public/common/prerender/prerender_rel_type.h"
 #include "ui/gfx/geometry/rect.h"
 
-using chrome_browser_net::NetworkPredictionStatus;
 using content::BrowserThread;
 using content::RenderViewHost;
 using content::SessionStorageNamespace;
@@ -139,9 +133,9 @@
 };
 
 PrerenderManager::PrerenderManager(
-    Profile* profile,
+    content::BrowserContext* browser_context,
     std::unique_ptr<PrerenderManagerDelegate> delegate)
-    : profile_(profile),
+    : browser_context_(browser_context),
       delegate_(std::move(delegate)),
       prerender_contents_factory_(PrerenderContents::CreateFactory()),
       prerender_history_(std::make_unique<PrerenderHistory>(kHistoryLength)),
@@ -168,7 +162,7 @@
 void PrerenderManager::Shutdown() {
   DestroyAllContents(FINAL_STATUS_PROFILE_DESTROYED);
   on_close_web_contents_deleters_.clear();
-  profile_ = nullptr;
+  browser_context_ = nullptr;
 
   DCHECK(active_prerenders_.empty());
 }
@@ -410,14 +404,9 @@
   auto dict_value = std::make_unique<base::DictionaryValue>();
   dict_value->Set("history", prerender_history_->CopyEntriesAsValue());
   dict_value->Set("active", GetActivePrerendersAsValue());
-  dict_value->SetBoolean(
-      "enabled", GetPredictionStatus() == NetworkPredictionStatus::ENABLED);
-  std::string disabled_note;
-  if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_ALWAYS)
-    disabled_note = "Disabled by user setting";
-  if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK)
-    disabled_note = "Disabled on cellular connection by default";
-  dict_value->SetString("disabled_note", disabled_note);
+  dict_value->SetBoolean("enabled", delegate_->IsPredictionEnabled());
+  dict_value->SetString("disabled_note",
+                        delegate_->GetReasonForDisablingPrediction());
   // If prerender is disabled via a flag this method is not even called.
   std::string enabled_note;
   dict_value->SetString("enabled_note", enabled_note);
@@ -554,11 +543,9 @@
     return nullptr;
   }
 
-  NetworkPredictionStatus prerendering_status =
-      GetPredictionStatusForOrigin(origin);
-  if (prerendering_status != NetworkPredictionStatus::ENABLED) {
+  if (!delegate_->IsPredictionEnabled(origin)) {
     FinalStatus final_status =
-        prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK
+        delegate_->IsPredictionDisabledDueToNetwork(origin)
             ? FINAL_STATUS_CELLULAR_NETWORK
             : FINAL_STATUS_PRERENDERING_DISABLED;
     SkipPrerenderContentsAndMaybePreconnect(url, origin, final_status);
@@ -596,8 +583,8 @@
   // TODO(ppi): Check whether there are usually enough render processes
   // available on Android. If not, kill an existing renderers so that we can
   // create a new one.
-  if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost(profile_,
-                                                                    url) &&
+  if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost(
+          browser_context_, url) &&
       !content::RenderProcessHost::run_renderer_in_process()) {
     SkipPrerenderContentsAndMaybePreconnect(url, origin,
                                             FINAL_STATUS_TOO_MANY_PROCESSES);
@@ -794,8 +781,8 @@
     Origin origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents(
-      delegate_->GetPrerenderContentsDelegate(), this, profile_, url, referrer,
-      initiator_origin, origin));
+      delegate_->GetPrerenderContentsDelegate(), this, browser_context_, url,
+      referrer, initiator_origin, origin));
 }
 
 void PrerenderManager::SortActivePrerenders() {
@@ -987,49 +974,13 @@
                                                   int64_t prerender_bytes) {
   if (!IsNoStatePrefetchEnabled())
     return;
-  int64_t recent_profile_bytes =
-      profile_network_bytes_ - last_recorded_profile_network_bytes_;
-  last_recorded_profile_network_bytes_ = profile_network_bytes_;
-  DCHECK_GE(recent_profile_bytes, 0);
+  int64_t recent_browser_context_bytes =
+      browser_context_network_bytes_ -
+      last_recorded_browser_context_network_bytes_;
+  last_recorded_browser_context_network_bytes_ = browser_context_network_bytes_;
+  DCHECK_GE(recent_browser_context_bytes, 0);
   histograms_->RecordNetworkBytesConsumed(origin, prerender_bytes,
-                                          recent_profile_bytes);
-}
-
-NetworkPredictionStatus PrerenderManager::GetPredictionStatus() const {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  return chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
-}
-
-NetworkPredictionStatus PrerenderManager::GetPredictionStatusForOrigin(
-    Origin origin) const {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  // <link rel=prerender> origins ignore the network state and the privacy
-  // settings. Web developers should be able prefetch with all possible privacy
-  // settings and with all possible network types. This would avoid web devs
-  // coming up with creative ways to prefetch in cases they are not allowed to
-  // do so.
-  if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN ||
-      origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) {
-    return NetworkPredictionStatus::ENABLED;
-  }
-
-  // Prerendering forced for cellular networks still prevents navigation with
-  // the DISABLED_ALWAYS selected via privacy settings.
-  NetworkPredictionStatus prediction_status =
-      chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
-  if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER &&
-      prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) {
-    return NetworkPredictionStatus::ENABLED;
-  }
-  return prediction_status;
-}
-
-void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64_t bytes) {
-  DCHECK_GE(bytes, 0);
-  if (GetPredictionStatus() == NetworkPredictionStatus::ENABLED &&
-      IsNoStatePrefetchEnabled())
-    profile_network_bytes_ += bytes;
+                                          recent_browser_context_bytes);
 }
 
 void PrerenderManager::AddPrerenderProcessHost(
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 8192185..b471e5b 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -19,18 +19,16 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/prerender/prerender_contents.h"
-#include "chrome/browser/prerender/prerender_manager_delegate.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prerender/browser/prerender_config.h"
 #include "components/prerender/browser/prerender_histograms.h"
+#include "components/prerender/browser/prerender_manager_delegate.h"
 #include "components/prerender/common/prerender_final_status.h"
 #include "components/prerender/common/prerender_origin.h"
 #include "content/public/browser/render_process_host_observer.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
-class Profile;
-
 namespace base {
 class DictionaryValue;
 class ListValue;
@@ -43,6 +41,7 @@
 
 namespace content {
 class WebContents;
+class BrowserContext;
 }
 
 namespace gfx {
@@ -92,8 +91,8 @@
     CLEAR_MAX = 0x1 << 2
   };
 
-  // Owned by a Profile object for the lifetime of the profile.
-  PrerenderManager(Profile* profile,
+  // Owned by a BrowserContext object for the lifetime of the browser_context.
+  PrerenderManager(content::BrowserContext* browser_context,
                    std::unique_ptr<PrerenderManagerDelegate> delegate);
   ~PrerenderManager() override;
 
@@ -244,8 +243,6 @@
   // provided URL.
   void RecordNavigation(const GURL& url);
 
-  Profile* profile() const { return profile_; }
-
   // Return current time and ticks with ability to mock the clock out for
   // testing.
   base::Time GetCurrentTime() const;
@@ -266,10 +263,6 @@
   // recorded.
   void RecordNetworkBytesConsumed(Origin origin, int64_t prerender_bytes);
 
-  // Add to the running tally of bytes transferred over the network for this
-  // profile if prerendering is currently enabled.
-  void AddProfileNetworkBytesIfEnabled(int64_t bytes);
-
   // Registers a new ProcessHost performing a prerender. Called by
   // PrerenderContents.
   void AddPrerenderProcessHost(content::RenderProcessHost* process_host);
@@ -388,15 +381,6 @@
   // Time window for which we record old navigations, in milliseconds.
   static const int kNavigationRecordWindowMs = 5000;
 
-  // Returns whether prerendering is currently enabled or the reason why it is
-  // disabled.
-  chrome_browser_net::NetworkPredictionStatus GetPredictionStatus() const;
-
-  // Returns whether prerendering is currently enabled or the reason why it is
-  // disabled after taking into account the origin of the request.
-  chrome_browser_net::NetworkPredictionStatus GetPredictionStatusForOrigin(
-      Origin origin) const;
-
   // Adds a prerender for |url| from |referrer|. The |origin| specifies how the
   // prerender was added. If |bounds| is empty, then
   // PrerenderContents::StartPrerendering will instead use a default from
@@ -512,8 +496,8 @@
   // The configuration.
   Config config_;
 
-  // The profile that owns this PrerenderManager.
-  Profile* profile_;
+  // The browser_context that owns this PrerenderManager.
+  content::BrowserContext* browser_context_;
 
   // The delegate that allows content embedder to override the logic in this
   // class.
@@ -525,7 +509,7 @@
   // Prerenders awaiting deletion.
   PrerenderDataVector to_delete_prerenders_;
 
-  // List of recent navigations in this profile, sorted by ascending
+  // List of recent navigations in this browser_context, sorted by ascending
   // |navigate_time_|.
   std::vector<NavigationRecord> navigations_;
 
@@ -552,12 +536,12 @@
 
   const std::unique_ptr<PrerenderHistograms> histograms_;
 
-  // The number of bytes transferred over the network for the profile this
-  // PrerenderManager is attached to.
-  int64_t profile_network_bytes_ = 0;
+  // The number of bytes transferred over the network for the browser_context
+  // this PrerenderManager is attached to.
+  int64_t browser_context_network_bytes_ = 0;
 
-  // The value of profile_network_bytes_ that was last recorded.
-  int64_t last_recorded_profile_network_bytes_ = 0;
+  // The value of browser_context_network_bytes_ that was last recorded.
+  int64_t last_recorded_browser_context_network_bytes_ = 0;
 
   // Set of process hosts being prerendered.
   using PrerenderProcessSet = std::set<content::RenderProcessHost*>;
diff --git a/chrome/browser/prerender/prerender_manager_delegate.h b/chrome/browser/prerender/prerender_manager_delegate.h
deleted file mode 100644
index e11c0d5..0000000
--- a/chrome/browser/prerender/prerender_manager_delegate.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_DELEGATE_H_
-#define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_DELEGATE_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "chrome/browser/prerender/prerender_contents_delegate.h"
-#include "url/gurl.h"
-
-namespace content_settings {
-class CookieSettings;
-}
-
-namespace prerender {
-
-// PrerenderManagerDelegate allows content embedders to override
-// PrerenderManager logic.
-class PrerenderManagerDelegate {
- public:
-  virtual ~PrerenderManagerDelegate() = default;
-
-  // Checks whether third party cookies should be blocked.
-  virtual scoped_refptr<content_settings::CookieSettings>
-  GetCookieSettings() = 0;
-
-  // Perform preconnect, if feasible.
-  virtual void MaybePreconnect(const GURL& url) = 0;
-
-  // Get the prerender contents delegate.
-  virtual std::unique_ptr<PrerenderContentsDelegate>
-  GetPrerenderContentsDelegate() = 0;
-};
-
-}  // namespace prerender
-
-#endif  // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_DELEGATE_H_
diff --git a/chrome/browser/prerender/prerender_test_utils.h b/chrome/browser/prerender/prerender_test_utils.h
index 5f6a0bd..3a9cb80 100644
--- a/chrome/browser/prerender/prerender_test_utils.h
+++ b/chrome/browser/prerender/prerender_test_utils.h
@@ -22,10 +22,10 @@
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #include "chrome/browser/prerender/chrome_prerender_contents_delegate.h"
 #include "chrome/browser/prerender/prerender_contents.h"
-#include "chrome/browser/prerender/prerender_contents_delegate.h"
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "components/prerender/browser/prerender_contents_delegate.h"
 #include "components/safe_browsing/core/db/test_database_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_widget_host_observer.h"
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 24acd7d..6d406f3 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -232,7 +232,7 @@
     // Shortcut deletion delays tests shutdown on Win-7 and results in time out.
     // See crbug.com/1073451.
 #if defined(OS_WIN)
-    AppShortcutManager::SuppressDeleteAllShortcutsForTesting();
+    AppShortcutManager::SuppressShortcutsForTesting();
 #endif
     InProcessBrowserTest::SetUp();
   }
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index bcc5063..9e2aa95b 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -711,8 +711,6 @@
    * Event handler that is invoked just before the frame is shown.
    */
   onBeforeShow() {
-    this.screenMode_ = AuthMode.DEFAULT;
-    this.loadingFrameContents_ = true;
     chrome.send('loginUIStateChanged', ['gaia-signin', true]);
 
     // Ensure that GAIA signin (or loading UI) is actually visible.
diff --git a/chrome/browser/resources/nearby_internals/BUILD.gn b/chrome/browser/resources/nearby_internals/BUILD.gn
index 39ef7df..9edcbf9 100644
--- a/chrome/browser/resources/nearby_internals/BUILD.gn
+++ b/chrome/browser/resources/nearby_internals/BUILD.gn
@@ -102,7 +102,6 @@
     ":types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js:cr.m",
-    "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
 }
 
diff --git a/chrome/browser/resources/nearby_internals/contact_tab.js b/chrome/browser/resources/nearby_internals/contact_tab.js
index 039e810..40943b0 100644
--- a/chrome/browser/resources/nearby_internals/contact_tab.js
+++ b/chrome/browser/resources/nearby_internals/contact_tab.js
@@ -24,6 +24,7 @@
 
 
   properties: {
+
     /** @private {!Array<!ContactUpdate>} */
     contactList_: {
       type: Array,
@@ -47,6 +48,7 @@
   attached() {
     this.addWebUIListener(
         'contacts-updated', contact => this.onContactUpdateAdded_([contact]));
+    this.browserProxy_.initialize();
   },
 
   /**
diff --git a/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js b/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js
index 89d78b5..8545af3 100644
--- a/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js
+++ b/chrome/browser/resources/nearby_internals/nearby_contact_browser_proxy.js
@@ -11,6 +11,13 @@
  */
 export class NearbyContactBrowserProxy {
   /**
+   * Initializes web contents in the WebUI handler.
+   */
+  initialize() {
+    chrome.send('initializeContacts');
+  }
+
+  /**
    * Downloads the user's contact list from the Nearby Share server. We can
    * force a download by passing |onlyDownloadIfContactsChanged| as false,
    * or we can choose to only download contacts if they have changed since the
diff --git a/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js b/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js
index f7a2919..97ea22f 100644
--- a/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js
+++ b/chrome/browser/resources/nearby_internals/nearby_http_browser_proxy.js
@@ -14,7 +14,7 @@
    * Initializes web contents in the WebUI handler.
    */
   initialize() {
-    chrome.send('initialize');
+    chrome.send('initializeHttp');
   }
 
   /**
diff --git a/chrome/browser/resources/pdf/navigator.js b/chrome/browser/resources/pdf/navigator.js
index 8aa2c1e..6b501b8b 100644
--- a/chrome/browser/resources/pdf/navigator.js
+++ b/chrome/browser/resources/pdf/navigator.js
@@ -7,8 +7,33 @@
 
 // NavigatorDelegate for calling browser-specific functions to do the actual
 // navigating.
+/** @interface */
 export class NavigatorDelegate {
   /**
+   * Called when navigation should happen in the current tab.
+   * @param {string} url The url to be opened in the current tab.
+   */
+  navigateInCurrentTab(url) {}
+
+  /**
+   * Called when navigation should happen in the new tab.
+   * @param {string} url The url to be opened in the new tab.
+   * @param {boolean} active Indicates if the new tab should be the active tab.
+   */
+  navigateInNewTab(url, active) {}
+
+  /**
+   * Called when navigation should happen in the new window.
+   * @param {string} url The url to be opened in the new window.
+   */
+  navigateInNewWindow(url) {}
+}
+
+// NavigatorDelegate for calling browser-specific functions to do the actual
+// navigating.
+/** @implements {NavigatorDelegate} */
+export class NavigatorDelegateImpl {
+  /**
    * @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is
    *     not displayed in a tab.
    */
@@ -17,10 +42,7 @@
     this.tabId_ = tabId;
   }
 
-  /**
-   * Called when navigation should happen in the current tab.
-   * @param {string} url The url to be opened in the current tab.
-   */
+  /** @override */
   navigateInCurrentTab(url) {
     // When the PDFviewer is inside a browser tab, prefer the tabs API because
     // it can navigate from one file:// URL to another.
@@ -31,11 +53,7 @@
     }
   }
 
-  /**
-   * Called when navigation should happen in the new tab.
-   * @param {string} url The url to be opened in the new tab.
-   * @param {boolean} active Indicates if the new tab should be the active tab.
-   */
+  /** @override */
   navigateInNewTab(url, active) {
     // Prefer the tabs API because it guarantees we can just open a new tab.
     // window.open doesn't have this guarantee.
@@ -46,10 +64,7 @@
     }
   }
 
-  /**
-   * Called when navigation should happen in the new window.
-   * @param {string} url The url to be opened in the new window.
-   */
+  /** @override */
   navigateInNewWindow(url) {
     // Prefer the windows API because it guarantees we can just open a new
     // window. window.open with '_blank' argument doesn't have this guarantee.
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js
index 618394b..8e164499 100644
--- a/chrome/browser/resources/pdf/pdf_viewer.js
+++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -29,7 +29,7 @@
 //</if>
 import {LocalStorageProxyImpl} from './local_storage_proxy.js';
 import {PDFMetrics} from './metrics.js';
-import {NavigatorDelegate, PdfNavigator} from './navigator.js';
+import {NavigatorDelegateImpl, PdfNavigator} from './navigator.js';
 import {OpenPdfParamsParser} from './open_pdf_params_parser.js';
 import {DeserializeKeyEvent, LoadState, SerializeKeyEvent} from './pdf_scripting_api.js';
 import {PDFViewerBaseElement} from './pdf_viewer_base.js';
@@ -357,7 +357,7 @@
     this.navigator_ = new PdfNavigator(
         this.originalUrl, this.viewport,
         /** @type {!OpenPdfParamsParser} */ (this.paramsParser),
-        new NavigatorDelegate(tabId));
+        new NavigatorDelegateImpl(tabId));
 
     // Listen for save commands from the browser.
     if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) {
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index d6f1c02b..bf0a8e73 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -387,14 +387,6 @@
       return {horizontal: false, vertical: false};
     }
 
-    // If scrollbars are required for one direction, expand the document in the
-    // other direction to take the width of the scrollbars into account when
-    // deciding whether the other direction needs scrollbars.
-    if (zoomedDimensions.width > this.window_.offsetWidth) {
-      zoomedDimensions.height += this.scrollbarWidth_;
-    } else if (zoomedDimensions.height > this.window_.offsetHeight) {
-      zoomedDimensions.width += this.scrollbarWidth_;
-    }
     return {
       horizontal: zoomedDimensions.width > this.window_.offsetWidth,
       vertical: zoomedDimensions.height + this.topToolbarHeight_ >
@@ -491,13 +483,9 @@
 
   /** @return {!Size} the size of the viewport excluding scrollbars. */
   get size() {
-    const needsScrollbars = this.documentNeedsScrollbars(this.getZoom());
-    const scrollbarWidth = needsScrollbars.vertical ? this.scrollbarWidth_ : 0;
-    const scrollbarHeight =
-        needsScrollbars.horizontal ? this.scrollbarWidth_ : 0;
     return {
-      width: this.window_.offsetWidth - scrollbarWidth,
-      height: this.window_.offsetHeight - scrollbarHeight
+      width: this.window_.offsetWidth,
+      height: this.window_.offsetHeight,
     };
   }
 
diff --git a/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.js b/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.js
index a1b21cb..d5a4ea40 100644
--- a/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.js
+++ b/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.js
@@ -30,6 +30,9 @@
     /** @type {!MultiStorePasswordUiEntry.Contents} */
     this.contents_ = MultiStorePasswordUiEntry.getContents_(entry1);
 
+    /** @type {string} */
+    this.password_ = '';
+
     this.setId(entry1.id, entry1.fromAccountStore);
 
     if (entry2) {
@@ -53,12 +56,23 @@
     this.setId(otherEntry.id, otherEntry.fromAccountStore);
   }
 
+  /** @return {!PasswordManagerProxy.UrlCollection} */
   get urls() {
     return this.contents_.urls;
   }
+  /** @return {string} */
   get username() {
     return this.contents_.username;
   }
+  /** @return {string} */
+  get password() {
+    return this.password_;
+  }
+  /** @param {string} password */
+  set password(password) {
+    this.password_ = password;
+  }
+  /** @return {(string|undefined)} */
   get federationText() {
     return this.contents_.federationText;
   }
diff --git a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html
index 5e7041bb..03829cb 100644
--- a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html
+++ b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html
@@ -21,8 +21,8 @@
       }
 
       #storageDetails {
-        margin-inline-start: 2px;
         margin-bottom: 16px;
+        margin-inline-start: 2px;
       }
 
       cr-icon-button {
@@ -43,16 +43,16 @@
             value="[[entry.username]]" on-blur="onInputBlur_" readonly>
         </cr-input>
         <cr-input id="passwordInput" label="$i18n{editPasswordPasswordLabel}"
-            type="[[getPasswordInputType_(password)]]"
-            value="[[getPassword_(password)]]" on-blur="onInputBlur_"
+            type="[[getPasswordInputType_(entry.password)]]"
+            value="[[getPassword_(entry.password)]]" on-blur="onInputBlur_"
             class="password-input" readonly="[[!isEditDialog_]]"
             required="[[isEditDialog_]]" auto-validate="[[isEditDialog_]]"
             invalid="{{inputInvalid_}}">
           <cr-icon-button id="showPasswordButton"
-              class$="[[getIconClass_(password)]]" slot="suffix"
+              class$="[[getIconClass_(entry.password)]]" slot="suffix"
               hidden$="[[entry.federationText]]"
               on-click="onShowPasswordButtonTap_"
-              title="[[showPasswordTitle_(password,
+              title="[[showPasswordTitle_(entry.password,
                   '$i18nPolymer{hidePassword}',
                   '$i18nPolymer{showPassword}')]]">
           </cr-icon-button>
diff --git a/chrome/browser/resources/settings/autofill_page/password_list_item.html b/chrome/browser/resources/settings/autofill_page/password_list_item.html
index 21f458c..9fa2cad4e 100644
--- a/chrome/browser/resources/settings/autofill_page/password_list_item.html
+++ b/chrome/browser/resources/settings/autofill_page/password_list_item.html
@@ -45,15 +45,15 @@
       <div class="password-column">
         <template is="dom-if" if="[[!entry.federationText]]">
           <input id="password" aria-label=$i18n{editPasswordPasswordLabel}
-              type="[[getPasswordInputType_(password)]]"
+              type="[[getPasswordInputType_(entry.password)]]"
               class="password-field password-input" readonly
-              disabled$="[[!password]]" on-click="onReadonlyInputTap_"
-              value="[[getPassword_(password)]]"
+              disabled$="[[!entry.password]]" on-click="onReadonlyInputTap_"
+              value="[[getPassword_(entry.password)]]"
               focus-row-control focus-type="passwordField">
           <cr-icon-button id="showPasswordButton"
-              class$="[[getIconClass_(password)]]"
+              class$="[[getIconClass_(entry.password)]]"
               on-click="onShowPasswordButtonTap_"
-              title="[[showPasswordTitle_(password,
+              title="[[showPasswordTitle_(entry.password,
                   '$i18nPolymer{hidePassword}',
                   '$i18nPolymer{showPassword}')]]"
               focus-row-control focus-type="showPassword"></cr-icon-button>
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
index c2352dc..04598bb 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
@@ -179,6 +179,7 @@
     e.preventDefault();
     this.$.menu.close();
     this.showPasswordEditDialog_ = true;
+    this.activePassword.hide();
   },
 
   /**
@@ -195,6 +196,7 @@
     this.showPasswordEditDialog_ = false;
     focusWithoutInk(assert(this.activeDialogAnchor_));
     this.activeDialogAnchor_ = null;
+    this.activePassword.hide();
     this.activePassword = null;
   },
 
diff --git a/chrome/browser/resources/settings/autofill_page/show_password_behavior.js b/chrome/browser/resources/settings/autofill_page/show_password_behavior.js
index 6570b2d..3cedefe 100644
--- a/chrome/browser/resources/settings/autofill_page/show_password_behavior.js
+++ b/chrome/browser/resources/settings/autofill_page/show_password_behavior.js
@@ -22,34 +22,21 @@
      */
     entry: Object,
 
-    /** The password that is being displayed. */
-    password: {
-      type: String,
-      value: '',
-    },
-
     // <if expr="chromeos">
     /** @type BlockingRequestManager */
     tokenRequestManager: Object
     // </if>
   },
 
-  observers: [
-    'resetPlaintextPasswordOnEntryChanged_(entry)',
-  ],
-
-  /** @private */
-  resetPlaintextPasswordOnEntryChanged_() {
-    this.password = '';
-  },
-
   /**
    * Gets the password input's type. Should be 'text' when password is visible
    * or when there's federated text otherwise 'password'.
+   * @return {string}
    * @private
    */
   getPasswordInputType_() {
-    return this.password || this.entry.federationText ? 'text' : 'password';
+    return this.entry.password || this.entry.federationText ? 'text' :
+                                                              'password';
   },
 
   /**
@@ -69,22 +56,19 @@
    * @private
    */
   getIconClass_() {
-    return this.password ? 'icon-visibility-off' : 'icon-visibility';
+    return this.entry.password ? 'icon-visibility-off' : 'icon-visibility';
   },
 
   /**
    * Gets the text of the password. Will use the value of |password| unless it
    * cannot be shown, in which case it will be a fixed number of spaces. It can
    * also be the federated text.
+   * @return {string}
    * @private
    */
   getPassword_() {
-    if (!this.entry) {
-      return '';
-    }
-
     const NUM_PLACEHOLDERS = 10;
-    return this.entry.federationText || this.password ||
+    return this.entry.federationText || this.entry.password ||
         ' '.repeat(NUM_PLACEHOLDERS);
   },
 
@@ -93,8 +77,8 @@
    * @private
    */
   onShowPasswordButtonTap_() {
-    if (this.password) {
-      this.password = '';
+    if (this.entry.password) {
+      this.hide();
       return;
     }
     PasswordManagerImpl.getInstance()
@@ -102,7 +86,7 @@
             this.entry.getAnyId(), chrome.passwordsPrivate.PlaintextReason.VIEW)
         .then(
             password => {
-              this.password = password;
+              this.set('entry.password', password);
             },
             error => {
               // <if expr="chromeos">
@@ -112,4 +96,11 @@
               // </if>
             });
   },
+
+  /**
+   * Hides the password.
+   */
+  hide() {
+    this.set('entry.password', '');
+  }
 };
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
index c7d0243..3c8f324 100644
--- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
+++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
@@ -33,15 +33,28 @@
 import {ClearBrowsingDataBrowserProxy, ClearBrowsingDataBrowserProxyImpl, InstalledApp} from './clear_browsing_data_browser_proxy.js';
 
 /**
- * @param {!Object} oldDialog the dialog to close
- * @param {!Object} newDialog the dialog to open
+ * @param {!CrDialogElement} dialog the dialog to close
+ * @param {boolean} isLast whether this is the last CBD-related dialog
+ * @private
+ */
+function closeDialog(dialog, isLast) {
+  // If this is not the last dialog, then stop the 'close' event from
+  // propagating so that other (following) dialogs don't get closed as well.
+  if (!isLast) {
+    dialog.addEventListener('close', e => {
+      e.stopPropagation();
+    }, {once: true});
+  }
+  dialog.close();
+}
+
+/**
+ * @param {!CrDialogElement} oldDialog the dialog to close
+ * @param {!CrDialogElement} newDialog the dialog to open
  * @private
  */
 function replaceDialog(oldDialog, newDialog) {
-  oldDialog.addEventListener('close', e => {
-    e.stopPropagation();
-  }, {once: true});
-  oldDialog.close();
+  closeDialog(oldDialog, false);
   if (!newDialog.open) {
     newDialog.showModal();
   }
@@ -462,21 +475,18 @@
     chrome.metricsPrivate.recordMediumTime(
         'History.ClearBrowsingData.TimeSpentInDialog',
         Date.now() - this.dialogOpenedTime_);
-    if (!showPasswordsNotice && !showHistoryNotice) {
-      this.closeDialogs_();
-    }
-  },
 
-  /**
-   * Closes clear browsing data or installed app dialog if they are open.
-   * @private
-   */
-  closeDialogs_() {
+    // Close the clear browsing data or installed apps dialog if they are open.
+    const isLastDialog = !showHistoryNotice && !showPasswordsNotice;
     if (this.$.clearBrowsingDataDialog.open) {
-      this.$.clearBrowsingDataDialog.close();
+      closeDialog(
+          /** @type {!CrDialogElement} */ (this.$.clearBrowsingDataDialog),
+          isLastDialog);
     }
     if (this.$.installedAppsDialog.open) {
-      this.$.installedAppsDialog.close();
+      closeDialog(
+          /** @type {!CrDialogElement} */ (this.$.installedAppsDialog),
+          isLastDialog);
     }
   },
 
@@ -491,15 +501,13 @@
    * @private
    */
   onHistoryDeletionDialogClose_(e) {
-    // Stop the close event from propagating further and also automatically
-    // closing the main CBD dialog. There's closeDialogs_() for that.
-    e.stopPropagation();
     this.showHistoryDeletionDialog_ = false;
     if (this.showPasswordsDeletionDialogLater_) {
+      // Stop the close event from propagating further and also automatically
+      // closing other dialogs.
+      e.stopPropagation();
       this.showPasswordsDeletionDialogLater_ = false;
       this.showPasswordsDeletionDialog_ = true;
-    } else {
-      this.closeDialogs_();
     }
   },
 
@@ -509,11 +517,7 @@
    * @private
    */
   onPasswordsDeletionDialogClose_(e) {
-    // Stop the close event from propagating further and also automatically
-    // closing the main CBD dialog. There's closeDialogs_() for that.
-    e.stopPropagation();
     this.showPasswordsDeletionDialog_ = false;
-    this.closeDialogs_();
   },
 
   /**
@@ -605,7 +609,9 @@
   onClearBrowsingDataClick_: async function() {
     await this.getInstalledApps_();
     if (this.shouldShowInstalledApps_()) {
-      replaceDialog(this.$.clearBrowsingDataDialog, this.$.installedAppsDialog);
+      replaceDialog(
+          /** @type {!CrDialogElement} */ (this.$.clearBrowsingDataDialog),
+          /** @type {!CrDialogElement} */ (this.$.installedAppsDialog));
     } else {
       await this.clearBrowsingData_();
     }
@@ -613,7 +619,9 @@
 
   /** @private */
   hideInstalledApps_() {
-    replaceDialog(this.$.installedAppsDialog, this.$.clearBrowsingDataDialog);
+    replaceDialog(
+        /** @type {!CrDialogElement} */ (this.$.installedAppsDialog),
+        /** @type {!CrDialogElement} */ (this.$.clearBrowsingDataDialog));
   },
 
   /**
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
index 3f89a71..500adff 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
@@ -124,7 +124,11 @@
   onSafetyCheckParentChanged_: function(event) {
     this.parentStatus_ = event.newState;
     this.parentDisplayString_ = event.displayString;
-    if (this.parentStatus_ === SafetyCheckParentStatus.AFTER) {
+    if (this.parentStatus_ === SafetyCheckParentStatus.CHECKING) {
+      // Ensure the re-run button is visible and focus it.
+      flush();
+      this.focusIconButton_();
+    } else if (this.parentStatus_ === SafetyCheckParentStatus.AFTER) {
       // Start periodic safety check parent ran string updates.
       const update = async () => {
         this.parentDisplayString_ =
@@ -162,16 +166,10 @@
     HatsBrowserProxyImpl.getInstance().tryShowSurvey();
 
     this.runSafetyCheck_();
-
-    // Update parent element so that re-run button is visible and can be
-    // focused.
-    this.parentStatus_ = SafetyCheckParentStatus.CHECKING;
-    flush();
-    this.focusParent_();
   },
 
   /** @private */
-  focusParent_() {
+  focusIconButton_() {
     const element =
         /** @type {!Element} */ (this.$$('#safetyCheckParentIconButton'));
     element.focus();
diff --git a/chrome/browser/resources/signin/profile_picker/navigation_behavior.js b/chrome/browser/resources/signin/profile_picker/navigation_behavior.js
index 0c3fbda..2abd1c4 100644
--- a/chrome/browser/resources/signin/profile_picker/navigation_behavior.js
+++ b/chrome/browser/resources/signin/profile_picker/navigation_behavior.js
@@ -108,6 +108,14 @@
   }
 }
 
+/**
+ * @param {!Routes} route
+ * @param {string} step
+ */
+export function navigateToStep(route, step) {
+  // TODO(crbug.com/1063856): Add implementation.
+}
+
 /** @polymerBehavior */
 export const NavigationBehavior = {
   /** @override */
@@ -131,4 +139,4 @@
    * @param {string} step
    */
   onRouteChange: function(route, step) {},
-};
+};
\ No newline at end of file
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
index 4109163..518f990 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
@@ -13,7 +13,9 @@
 js_library("profile_type_choice") {
   deps = [
     "..:manage_profiles_browser_proxy",
+    "..:navigation_behavior",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
     "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
   ]
 }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
index badc2fd..ba3186fd 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.html
@@ -1,4 +1,10 @@
-<style include="cr-icons profile-picker-shared">
+<style include="action-link-style cr-icons profile-picker-shared">
+  #actionContainer {
+    align-items: center;
+    display: flex;
+    flex-direction: column;
+  }
+
   #backButton {
     --cr-icon-button-icon-size: 14px;
     --cr-icon-button-margin-start: 4px;
@@ -28,15 +34,34 @@
     width: 100%;
   }
 
+  #notNowButton {
+    background: none;
+    border: none;
+    color: var(--cr-link-color);
+    cursor: pointer;
+    font-size: 1em;
+    font-weight: normal;
+    line-height: 20px;
+    margin-top: 18px;
+    outline: none;
+  }
+
+  #signInButton {
+    font-size: 1em;
+    font-weight: normal;
+    width: 208px;
+  }
+
   .title-container {
     margin: 104px auto;
+    margin-bottom: 48px;
     text-align: center;
   }
 </style>
 
 <div id="bannerContainer"
     style$="background-color:[[profileThemeInfo.themeColor]];">
-    <cr-icon-button class="icon-arrow-back" id="backButton"
+    <cr-icon-button id="backButton" class="icon-arrow-back"
         on-click="onTapBack_" aria-label="$i18n{backButtonLabel}">
     </cr-icon-button>
     <div id="banner"></div>
@@ -45,3 +70,13 @@
   <h2>$i18n{profileTypeChoiceTitle}</h2>
   <h3>$i18n{profileTypeChoiceSubtitle}</h3>
 </div>
+<div id="actionContainer">
+  <cr-button id="signInButton" class="action-button fade-in"
+      on-click="onSignInClick_">
+    $i18n{signInButtonLabel}
+  </cr-button>
+  <button id="notNowButton" class="action-link fade-in"
+      on-click="onNotNowClick_">
+    $i18n{notNowButtonLabel}
+  </button>
+</div>
\ No newline at end of file
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js
index da8225bd..af825004 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js
@@ -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://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import '../profile_picker_shared_css.js';
@@ -9,7 +10,7 @@
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {AutogeneratedThemeColorInfo} from '../manage_profiles_browser_proxy.js';
-import {navigateToPreviousRoute} from '../navigation_behavior.js';
+import {navigateToPreviousRoute, navigateToStep, ProfileCreationSteps, Routes} from '../navigation_behavior.js';
 
 Polymer({
   is: 'profile-type-choice',
@@ -24,6 +25,17 @@
   },
 
   /** @private */
+  onNotNowClick_() {
+    navigateToStep(
+        Routes.NEW_PROFILE, ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION);
+  },
+
+  /** @private */
+  onSignInClick_() {
+    navigateToStep(Routes.NEW_PROFILE, ProfileCreationSteps.LOAD_SIGNIN);
+  },
+
+  /** @private */
   onTapBack_() {
     navigateToPreviousRoute();
   },
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn
index 3e80ce68..ee663dd 100644
--- a/chrome/browser/safety_check/android/BUILD.gn
+++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -38,10 +38,12 @@
     "//base:base_java",
     "//base:jni_java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/password_manager/android:java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/safe_browsing/android:java",
     "//chrome/browser/settings:java",
     "//components/browser_ui/settings/android:java",
+    "//components/password_manager/core/browser:password_manager_java_enums",
     "//content/public/android:content_java",
     "//third_party/android_deps:android_support_v7_appcompat_java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
diff --git a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
index 515bffdb..ffccb48 100644
--- a/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
+++ b/chrome/browser/safety_check/android/java/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediator.java
@@ -19,6 +19,8 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.password_check.BulkLeakCheckServiceState;
+import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
+import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.safe_browsing.settings.SecuritySettingsFragment;
@@ -129,11 +131,8 @@
         mModel.set(SafetyCheckProperties.PASSWORDS_CLICK_LISTENER,
                 (Preference.OnPreferenceClickListener) (p) -> {
                     // Open the Passwords settings.
-                    // TODO(crbug.com/1070620): replace the hardcoded class name with an import and
-                    // ".class.getName()" once PasswordSettings is moved out of //chrome/android.
-                    p.getContext().startActivity(settingsLauncher.createSettingsActivityIntent(
-                            p.getContext(),
-                            "org.chromium.chrome.browser.password_manager.settings.PasswordSettings"));
+                    PasswordManagerHelper.showPasswordSettings(p.getContext(),
+                            ManagePasswordsReferrer.CHROME_SETTINGS, settingsLauncher);
                     return true;
                 });
         // Set the listener for clicking the Check button.
diff --git a/chrome/browser/signin/dice_browsertest.cc b/chrome/browser/signin/dice_browsertest.cc
index cc41a54..24879f54 100644
--- a/chrome/browser/signin/dice_browsertest.cc
+++ b/chrome/browser/signin/dice_browsertest.cc
@@ -1041,7 +1041,7 @@
 #if defined(OS_WIN)
     // Shortcut deletion delays tests shutdown on Win-7 and results in time out.
     // See crbug.com/1073451.
-    AppShortcutManager::SuppressDeleteAllShortcutsForTesting();
+    AppShortcutManager::SuppressShortcutsForTesting();
 #endif
     DiceBrowserTest::SetUp();
   }
diff --git a/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc b/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
index f11296e2..c0c6f0e 100644
--- a/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
+++ b/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/tab/state/tab_state_db_factory_unittest.cc b/chrome/browser/tab/state/tab_state_db_factory_unittest.cc
index 2f7965ff..a69bf26 100644
--- a/chrome/browser/tab/state/tab_state_db_factory_unittest.cc
+++ b/chrome/browser/tab/state/tab_state_db_factory_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/tab/state/tab_state_db_factory.h"
 
+#include <memory>
+
+#include "base/files/scoped_temp_dir.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -12,13 +15,31 @@
  public:
   TabStateDBFactoryTest() = default;
 
-  Profile* profile() { return &profile_; }
-  Profile* different_profile() { return &different_profile_; }
+  void SetUp() override {
+    // TODO(crbug.com/546640): This test seems to leak data across tests (on
+    // Windows, even temp files) because SharedProtoDatabase doesn't get
+    // reliably deleted upon steardown.
+    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
+    ASSERT_TRUE(different_profile_dir_.CreateUniqueTempDir());
+
+    TestingProfile::Builder profile_builder;
+    profile_builder.SetPath(profile_dir_.GetPath());
+    profile_ = profile_builder.Build();
+
+    TestingProfile::Builder different_profile_builder;
+    different_profile_builder.SetPath(different_profile_dir_.GetPath());
+    different_profile_ = different_profile_builder.Build();
+  }
+
+  Profile* profile() { return profile_.get(); }
+  Profile* different_profile() { return different_profile_.get(); }
 
  private:
+  base::ScopedTempDir profile_dir_;
+  base::ScopedTempDir different_profile_dir_;
   content::BrowserTaskEnvironment task_environment_;
-  TestingProfile profile_;
-  TestingProfile different_profile_;
+  std::unique_ptr<TestingProfile> profile_;
+  std::unique_ptr<TestingProfile> different_profile_;
 
   DISALLOW_COPY_AND_ASSIGN(TabStateDBFactoryTest);
 };
diff --git a/chrome/browser/ui/app_list/icon_standardizer.cc b/chrome/browser/ui/app_list/icon_standardizer.cc
index 0d447eb..601d09e 100644
--- a/chrome/browser/ui/app_list/icon_standardizer.cc
+++ b/chrome/browser/ui/app_list/icon_standardizer.cc
@@ -11,7 +11,7 @@
 
 namespace {
 
-constexpr float kCircleOutlineStrokeWidth = 6.0f;
+constexpr float kCircleOutlineStrokeWidth = 8.0f;
 
 constexpr int kMinimumVisibleAlpha = 40;
 
@@ -79,12 +79,10 @@
 
 // Returns whether the shape of the icon is roughly circle shaped.
 bool IsIconCircleShaped(const gfx::ImageSkia& image) {
+  bool is_icon_already_circle_shaped = false;
+
   for (gfx::ImageSkiaRep rep : image.image_reps()) {
-    if (rep.scale() != image.GetMaxSupportedScale())
-      continue;
-
     SkBitmap bitmap(rep.GetBitmap());
-
     int width = bitmap.width();
     int height = bitmap.height();
 
@@ -112,6 +110,30 @@
       }
     }
 
+    gfx::Rect visible_preview_bounds = GetVisibleIconBounds(preview);
+    float visible_icon_diagonal = std::sqrt(
+        visible_preview_bounds.height() * visible_preview_bounds.height() +
+        visible_preview_bounds.width() * visible_preview_bounds.width());
+
+    float preview_diagonal = std::sqrt(preview.height() * preview.height() +
+                                       preview.width() * preview.width());
+
+    float scale = preview_diagonal / visible_icon_diagonal;
+
+    gfx::Size scaled_icon_size =
+        gfx::ScaleToRoundedSize(rep.pixel_size(), scale);
+
+    // To detect a circle shaped icon of any size, resize and scale |preview| so
+    // the visible icon bounds match the maximum width and height of the bitmap.
+    const SkBitmap scaled_preview = skia::ImageOperations::Resize(
+        preview, skia::ImageOperations::RESIZE_BEST, scaled_icon_size.width(),
+        scaled_icon_size.height());
+
+    preview.eraseColor(SK_ColorTRANSPARENT);
+    SkCanvas canvas1(preview);
+    canvas1.drawBitmap(scaled_preview, -visible_preview_bounds.x() * scale,
+                       -visible_preview_bounds.y() * scale);
+
     // Use a canvas to perform XOR and DST_OUT operations, which should
     // generate a transparent bitmap for |preview| if the original icon is
     // shaped like a circle.
@@ -123,19 +145,18 @@
 
     // XOR operation to remove a circle.
     paint_circle_mask.setBlendMode(SkBlendMode::kXor);
-    canvas.drawCircle(SkPoint::Make(width / 2, height / 2), width / 2,
+    canvas.drawCircle(SkPoint::Make(width / 2.0f, height / 2.0f), width / 2.0,
                       paint_circle_mask);
 
     SkPaint paint_outline;
-    paint_outline.setColor(SK_ColorBLUE);
+    paint_outline.setColor(SK_ColorGREEN);
     paint_outline.setStyle(SkPaint::kStroke_Style);
     paint_outline.setStrokeWidth(kCircleOutlineStrokeWidth * rep.scale());
     paint_outline.setAntiAlias(true);
 
     // DST_OUT operation to remove an extra circle outline.
     paint_outline.setBlendMode(SkBlendMode::kDstOut);
-    canvas.drawCircle(SkPoint::Make((width - 1) / 2.0f, (height - 1) / 2.0f),
-                      (width - kCircleOutlineStrokeWidth) / 2.0f,
+    canvas.drawCircle(SkPoint::Make(width / 2.0f, height / 2.0f), width / 2.0f,
                       paint_outline);
 
     // Compute the total pixel difference between the circle mask and the
@@ -154,23 +175,19 @@
 
     // If the pixel difference between a circle and the original icon is small
     // enough, then the icon can be considered circle shaped.
-    bool is_icon_already_circle_shaped =
-        !(percentage_diff_pixels >= kCircleShapePixelDifferenceThreshold);
-
-    return is_icon_already_circle_shaped;
+    if (!(percentage_diff_pixels >= kCircleShapePixelDifferenceThreshold))
+      is_icon_already_circle_shaped = true;
   }
 
-  return false;
+  return is_icon_already_circle_shaped;
 }
 
 // Returns whether the opaque part of the icon can fit within a circle.
 bool CanVisibleIconFitInCircle(const gfx::ImageSkia& image) {
+  bool can_icon_fit_in_circle = false;
+
   for (gfx::ImageSkiaRep rep : image.image_reps()) {
-    if (rep.scale() != image.GetMaxSupportedScale())
-      continue;
-
     SkBitmap bitmap(rep.GetBitmap());
-
     int width = bitmap.width();
     int height = bitmap.height();
 
@@ -227,10 +244,11 @@
 
     // If the pixel difference between a circle and the original icon is small
     // enough, then the icon can be considered as fitting inside the circle.
-    return !(percentage_diff_pixels >= kInsideCircleDifferenceThreshold);
+    if (!(percentage_diff_pixels >= kInsideCircleDifferenceThreshold))
+      can_icon_fit_in_circle = true;
   }
 
-  return false;
+  return can_icon_fit_in_circle;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
index 9282cb0..8386dec 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
@@ -7,11 +7,16 @@
 #include "ash/public/cpp/holding_space/holding_space_controller.h"
 #include "ash/public/cpp/holding_space/holding_space_item.h"
 #include "base/guid.h"
+#include "components/account_id/account_id.h"
 
 namespace ash {
 
 HoldingSpaceKeyedService::HoldingSpaceKeyedService(
-    content::BrowserContext* context) {}
+    content::BrowserContext* context,
+    const AccountId& account_id) {
+  HoldingSpaceController::Get()->RegisterModelForUser(account_id,
+                                                      &holding_space_model_);
+}
 
 HoldingSpaceKeyedService::~HoldingSpaceKeyedService() = default;
 
@@ -21,8 +26,4 @@
   holding_space_model_.AddItem(std::move(item));
 }
 
-void HoldingSpaceKeyedService::ActivateModel() {
-  HoldingSpaceController::Get()->SetModel(&holding_space_model_);
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
index 62c43a8..7b39b97 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
@@ -7,6 +7,7 @@
 
 #include "ash/public/cpp/holding_space/holding_space_model.h"
 #include "base/strings/string16.h"
+#include "components/account_id/account_id.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 namespace content {
@@ -20,16 +21,13 @@
 // *   Serves as an entry point to add holding space items from Chrome.
 class HoldingSpaceKeyedService : public KeyedService {
  public:
-  explicit HoldingSpaceKeyedService(content::BrowserContext* context);
+  HoldingSpaceKeyedService(content::BrowserContext* context,
+                           const AccountId& account_id);
   HoldingSpaceKeyedService(const HoldingSpaceKeyedService& other) = delete;
   HoldingSpaceKeyedService& operator=(const HoldingSpaceKeyedService& other) =
       delete;
   ~HoldingSpaceKeyedService() override;
 
-  // Sets the holding space model managed by this service as the active
-  // model.
-  void ActivateModel();
-
   // Adds a text item to the service's holding space model.
   // |text|: The item's text value.
   void AddTextItem(const base::string16& text);
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc
index 68e5023..15db76ec 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.cc
@@ -9,6 +9,8 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/user_manager/user.h"
+#include "components/user_manager/user_type.h"
 
 namespace ash {
 
@@ -35,14 +37,16 @@
   if (!features::IsTemporaryHoldingSpaceEnabled())
     return nullptr;
 
-  // TODO(https://crbug.com/1107713): Support multi-profile.
-  if (!chromeos::ProfileHelper::IsPrimaryProfile(
-          Profile::FromBrowserContext(context))) {
+  user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(
+      Profile::FromBrowserContext(context));
+  if (!user)
     return nullptr;
-  }
 
-  auto* service = new HoldingSpaceKeyedService(context);
-  service->ActivateModel();
+  if (user->GetType() == user_manager::USER_TYPE_KIOSK_APP)
+    return nullptr;
+
+  auto* service = new HoldingSpaceKeyedService(context, user->GetAccountId());
+
   return service;
 }
 
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
index b473379..b2ee10c 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -37,8 +37,13 @@
   TestingProfile* CreateProfile() override {
     const std::string kPrimaryProfileName = "primary_profile";
     const AccountId account_id(AccountId::FromUserEmail(kPrimaryProfileName));
+
     fake_user_manager_->AddUser(account_id);
     fake_user_manager_->LoginUser(account_id);
+
+    GetSessionControllerClient()->AddUserSession(kPrimaryProfileName);
+    GetSessionControllerClient()->SwitchActiveUser(account_id);
+
     return profile_manager()->CreateTestingProfile(kPrimaryProfileName);
   }
 
@@ -55,6 +60,17 @@
         TestingProfile::TestingFactories());
   }
 
+  void ActivateSecondaryProfile() {
+    const std::string kSecondaryProfileName = "secondary_profile";
+    const AccountId account_id(AccountId::FromUserEmail(kSecondaryProfileName));
+    GetSessionControllerClient()->AddUserSession(kSecondaryProfileName);
+    GetSessionControllerClient()->SwitchActiveUser(account_id);
+  }
+
+  TestSessionControllerClient* GetSessionControllerClient() {
+    return ash_test_helper()->test_session_controller_client();
+  }
+
  private:
   chromeos::FakeChromeUserManager* fake_user_manager_;
   user_manager::ScopedUserManager user_manager_enabler_;
@@ -92,12 +108,19 @@
       HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(GetProfile());
 
   TestingProfile* const second_profile = CreateSecondaryProfile();
-  EXPECT_FALSE(HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(
-      second_profile));
+  HoldingSpaceKeyedService* const secondary_holding_space_service =
+      HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(
+          second_profile);
 
   // Just creating a secondary profile should not change the active model.
   EXPECT_EQ(HoldingSpaceController::Get()->model(),
             primary_holding_space_service->model_for_testing());
+
+  // Switching the active user should change the active model (multi user
+  // support)
+  ActivateSecondaryProfile();
+  EXPECT_EQ(HoldingSpaceController::Get()->model(),
+            secondary_holding_space_service->model_for_testing());
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
index 50726904..0107376 100644
--- a/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
+++ b/chrome/browser/ui/views/accessibility/browser_accessibility_uitest_auralinux.cc
@@ -6,6 +6,7 @@
 #include <stddef.h>
 
 #include "base/macros.h"
+#include "chrome/browser/devtools/devtools_window_testing.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog.h"
@@ -187,3 +188,34 @@
 
   VerifyEmbedRelationships();
 }
+
+// Tests that the embedded relationship is set on the main web contents when
+// the DevTools is opened.
+IN_PROC_BROWSER_TEST_F(AuraLinuxAccessibilityInProcessBrowserTest,
+                       EmbeddedRelationshipWithDevTools) {
+  // Force the creation of the document's native object which sets up the
+  // relationship.
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_NE(nullptr, active_web_contents->GetRenderWidgetHostView()
+                         ->GetNativeViewAccessible());
+  EXPECT_EQ(1, browser()->tab_strip_model()->count());
+  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
+
+  // Opens DevTools docked.
+  DevToolsWindow* devtools =
+      DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), true);
+  VerifyEmbedRelationships();
+
+  // Closes the DevTools window.
+  DevToolsWindowTesting::CloseDevToolsWindowSync(devtools);
+  VerifyEmbedRelationships();
+
+  // Opens DevTools in a separate window.
+  devtools = DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
+  VerifyEmbedRelationships();
+
+  // Closes the DevTools window.
+  DevToolsWindowTesting::CloseDevToolsWindowSync(devtools);
+  VerifyEmbedRelationships();
+}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 92274e8..adbc523 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -568,6 +568,7 @@
       contents_container->AddChildView(std::move(devtools_web_view));
   contents_web_view_ =
       contents_container->AddChildView(std::move(contents_web_view));
+  contents_web_view_->set_is_primary_web_contents_for_window(true);
   contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
       devtools_web_view_, contents_web_view_));
 
diff --git a/chrome/browser/ui/views/profiles/incognito_menu_view.cc b/chrome/browser/ui/views/profiles/incognito_menu_view.cc
index c078e3150..6f2d307 100644
--- a/chrome/browser/ui/views/profiles/incognito_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/incognito_menu_view.cc
@@ -71,6 +71,7 @@
 
 void IncognitoMenuView::OnExitButtonClicked() {
   RecordClick(ActionableItem::kExitProfileButton);
+  base::RecordAction(base::UserMetricsAction("IncognitoMenu_ExitClicked"));
   // Skipping before-unload trigger to give incognito mode users a chance to
   // quickly close all incognito windows without needing to confirm closing the
   // open forms.
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index beb0a32..f9b8b01 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -160,6 +160,7 @@
 #include "chrome/browser/chromeos/printing/print_management/printing_manager.h"
 #include "chrome/browser/chromeos/printing/print_management/printing_manager_factory.h"
 #include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h"
+#include "chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.h"
 #include "chrome/browser/chromeos/web_applications/chrome_help_app_ui_delegate.h"
 #include "chrome/browser/chromeos/web_applications/chrome_media_app_ui_delegate.h"
 #include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h"
@@ -312,6 +313,13 @@
 }
 
 template <>
+WebUIController* NewWebUI<chromeos::CameraAppUI>(WebUI* web_ui,
+                                                 const GURL& url) {
+  auto delegate = std::make_unique<ChromeCameraAppUIDelegate>();
+  return new chromeos::CameraAppUI(web_ui, std::move(delegate));
+}
+
+template <>
 WebUIController* NewWebUI<chromeos::HelpAppUI>(WebUI* web_ui, const GURL& url) {
   auto delegate = std::make_unique<ChromeHelpAppUIDelegate>(web_ui);
   return new chromeos::HelpAppUI(web_ui, std::move(delegate));
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 1d5554c..75db1295 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -697,8 +697,10 @@
   initialized_ = true;
   // This should be called only once on page load.
   AllowJavascript();
-  if (show_when_ready_)
+  if (show_on_init_) {
+    show_on_init_ = false;
     ShowGaiaScreenIfReady();
+  }
 }
 
 void GaiaScreenHandler::RegisterMessages() {
@@ -881,7 +883,7 @@
   if (LoginDisplayHost::default_host())
     LoginDisplayHost::default_host()->SetDisplayEmail(username);
 
-  set_populated_account(AccountId::FromUserEmail(username));
+  populated_account_id_ = AccountId::FromUserEmail(username);
   DCHECK(authpolicy_login_helper_);
   Key key(password);
   key.SetLabel(kCryptohomeGaiaKeyLabel);
@@ -925,6 +927,15 @@
   }
 
   ContinueAuthenticationWhenCookiesAvailable();
+
+  if (test_expects_complete_login_) {
+    VLOG(2) << "Complete test login for " << sanitized_email
+            << ", requested=" << test_user_;
+
+    test_expects_complete_login_ = false;
+    test_user_.clear();
+    test_pass_.clear();
+  }
 }
 
 void GaiaScreenHandler::ContinueAuthenticationWhenCookiesAvailable() {
@@ -1082,7 +1093,7 @@
   // |args| can be null if it's OOBE.
   if (args)
     args->GetString(0, &email);
-  set_populated_account(AccountId::FromUserEmail(email));
+  populated_account_id_ = AccountId::FromUserEmail(email);
   OnShowAddUser();
 }
 
@@ -1147,7 +1158,8 @@
 void GaiaScreenHandler::OnShowAddUser() {
   signin_screen_handler_->is_account_picker_showing_first_time_ = false;
   lock_screen_utils::EnforceDevicePolicyInputMethods(std::string());
-  ShowGaiaAsync(EmptyAccountId());
+  LoadGaiaAsync(EmptyAccountId());
+  LoginDisplayHost::default_host()->StartWizard(GaiaView::kScreenId);
 }
 
 void GaiaScreenHandler::DoCompleteLogin(
@@ -1180,15 +1192,6 @@
   }
 
   LoginDisplayHost::default_host()->CompleteLogin(user_context);
-
-  if (test_expects_complete_login_) {
-    VLOG(2) << "Complete test login for " << typed_email
-            << ", requested=" << test_user_;
-
-    test_expects_complete_login_ = false;
-    test_user_.clear();
-    test_pass_.clear();
-  }
 }
 
 void GaiaScreenHandler::StartClearingDnsCache() {
@@ -1270,8 +1273,8 @@
                                      base::NullCallback());
   }
 
-  // Test properties are cleared in HandleCompleteLogin because the form
-  // submission might fail and login will not be attempted after reloading
+  // Test properties are cleared in HandleCompleteAuthentication because the
+  // form submission might fail and login will not be attempted after reloading
   // if they are cleared here.
 }
 
@@ -1283,10 +1286,18 @@
   RecordAPILogin(is_third_party_idp, is_api_used);
 }
 
-void GaiaScreenHandler::ShowGaiaAsync(const AccountId& account_id) {
+void GaiaScreenHandler::Show() {
+  ShowScreen(GaiaView::kScreenId);
+  hidden_ = false;
+}
+
+void GaiaScreenHandler::Hide() {
+  hidden_ = true;
+}
+
+void GaiaScreenHandler::LoadGaiaAsync(const AccountId& account_id) {
   if (account_id.is_valid())
     populated_account_id_ = account_id;
-  show_when_ready_ = true;
   if (gaia_silent_load_ && !populated_account_id_.is_valid()) {
     dns_cleared_ = true;
     cookies_cleared_ = true;
@@ -1298,6 +1309,11 @@
   }
 }
 
+void GaiaScreenHandler::LoadOfflineGaia(const AccountId& account_id) {
+  populated_account_id_ = account_id;
+  LoadAuthExtension(true /* force */, true /* offline */);
+}
+
 void GaiaScreenHandler::ShowSigninScreenForTest(const std::string& username,
                                                 const std::string& password,
                                                 const std::string& services) {
@@ -1381,13 +1397,12 @@
   saml_challenge_key_handler_ = std::make_unique<SamlChallengeKeyHandler>();
 }
 
-void GaiaScreenHandler::CancelShowGaiaAsync() {
-  show_when_ready_ = false;
-}
-
 void GaiaScreenHandler::ShowGaiaScreenIfReady() {
-  if (!dns_cleared_ || !cookies_cleared_ || !initialized_ ||
-      !show_when_ready_ || !LoginDisplayHost::default_host()) {
+  if (!initialized_) {
+    show_on_init_ = true;
+    return;
+  }
+  if (!dns_cleared_ || !cookies_cleared_ || !LoginDisplayHost::default_host()) {
     return;
   }
 
@@ -1518,7 +1533,7 @@
 }
 
 void GaiaScreenHandler::UpdateState(NetworkError::ErrorReason reason) {
-  if (signin_screen_handler_)
+  if (signin_screen_handler_ && !hidden_)
     signin_screen_handler_->UpdateState(reason);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 786fd32..49d1e140 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -58,11 +58,17 @@
 
   virtual void DisableRestrictiveProxyCheckForTest() = 0;
 
-  // Show the sign-in screen. Depending on internal state, the screen will
-  // either be shown immediately or after an asynchronous clean-up process that
+  // Loads Gaia into the webview. Depending on internal state, the Gaia will
+  // either be loaded immediately or after an asynchronous clean-up process that
   // cleans DNS cache and cookies. If available, |account_id| is used for
   // prefilling information.
-  virtual void ShowGaiaAsync(const AccountId& account_id) = 0;
+  virtual void LoadGaiaAsync(const AccountId& account_id) = 0;
+
+  virtual void LoadOfflineGaia(const AccountId& account_id) = 0;
+
+  // Shows Gaia screen.
+  virtual void Show() = 0;
+  virtual void Hide() = 0;
 
   // Show sign-in screen for the given credentials. |services| is a list of
   // services returned by userInfo call as JSON array. Should be an empty array
@@ -115,7 +121,10 @@
   // GaiaView:
   void MaybePreloadAuthExtension() override;
   void DisableRestrictiveProxyCheckForTest() override;
-  void ShowGaiaAsync(const AccountId& account_id) override;
+  void LoadGaiaAsync(const AccountId& account_id) override;
+  void LoadOfflineGaia(const AccountId& account_id) override;
+  void Show() override;
+  void Hide() override;
   void ShowSigninScreenForTest(const std::string& username,
                                const std::string& password,
                                const std::string& services) override;
@@ -251,11 +260,6 @@
                        bool using_saml,
                        const SamlPasswordAttributes& password_attributes);
 
-  // Fill GAIA account.
-  void set_populated_account(const AccountId& populated_account_id) {
-    populated_account_id_ = populated_account_id;
-  }
-
   // Kick off cookie / local storage cleanup.
   void StartClearingCookies(const base::Closure& on_clear_callback);
   void OnCookiesCleared(const base::Closure& on_clear_callback);
@@ -277,10 +281,6 @@
   // Chrome Credentials Passing API was used during SAML login.
   void SetSAMLPrincipalsAPIUsed(bool is_third_party_idp, bool is_api_used);
 
-  // Cancels the request to show the sign-in screen while the asynchronous
-  // clean-up process that precedes the screen showing is in progress.
-  void CancelShowGaiaAsync();
-
   // Shows signin screen after dns cache and cookie cleanup operations finish.
   void ShowGaiaScreenIfReady();
 
@@ -359,6 +359,8 @@
   // Whether the handler has been initialized.
   bool initialized_ = false;
 
+  bool show_on_init_ = false;
+
   // True if dns cache cleanup is done.
   bool dns_cleared_ = false;
 
@@ -445,6 +447,8 @@
   // canceled by the user.
   bool was_security_token_pin_canceled_ = false;
 
+  bool hidden_ = true;
+
   // Handler for |samlChallengeMachineKey| request.
   std::unique_ptr<SamlChallengeKeyHandler> saml_challenge_key_handler_;
   std::unique_ptr<SamlChallengeKeyHandler> saml_challenge_key_handler_for_test_;
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index edae50a..519959b 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -45,6 +45,7 @@
 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h"
 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h"
 #include "chrome/browser/chromeos/login/reauth_stats.h"
+#include "chrome/browser/chromeos/login/screens/gaia_screen.h"
 #include "chrome/browser/chromeos/login/screens/network_error.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
@@ -520,11 +521,9 @@
   switch (ui_state) {
     case UI_STATE_GAIA_SIGNIN:
       ui_state_ = UI_STATE_GAIA_SIGNIN;
-      ShowScreen(GaiaView::kScreenId);
       break;
     case UI_STATE_ACCOUNT_PICKER:
       ui_state_ = UI_STATE_ACCOUNT_PICKER;
-      gaia_screen_handler_->CancelShowGaiaAsync();
       ShowScreen(OobeScreen::SCREEN_ACCOUNT_PICKER);
       break;
     default:
@@ -868,7 +867,9 @@
     // We need to reload GAIA if UI_STATE_UNKNOWN or the allow new user setting
     // has changed so that reloaded GAIA shows/hides the option to create a new
     // account.
-    UpdateUIState(UI_STATE_ACCOUNT_PICKER);
+    GaiaScreen* gaia_screen = GaiaScreen::Get(
+        WizardController::default_controller()->screen_manager());
+    gaia_screen->LoadOnline(EmptyAccountId());
   }
 }
 
@@ -1056,8 +1057,13 @@
   std::string email;
   args->GetString(0, &email);
 
-  gaia_screen_handler_->set_populated_account(AccountId::FromUserEmail(email));
-  gaia_screen_handler_->LoadAuthExtension(true /* force */, true /* offline */);
+  GaiaScreen* gaia_screen =
+      GaiaScreen::Get(WizardController::default_controller()->screen_manager());
+  gaia_screen->LoadOffline(AccountId::FromUserEmail(email));
+  HideOfflineMessage(NetworkStateInformer::OFFLINE,
+                     NetworkError::ERROR_REASON_NONE);
+  LoginDisplayHost::default_host()->StartWizard(GaiaView::kScreenId);
+
   UpdateUIState(UI_STATE_GAIA_SIGNIN);
 }
 
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
index 270937d..4826dd3c 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
@@ -11,6 +11,8 @@
 #include "base/time/time.h"
 #include "chrome/browser/nearby_sharing/logging/logging.h"
 #include "chrome/browser/nearby_sharing/logging/proto_to_dictionary_conversion.h"
+#include "chrome/browser/nearby_sharing/nearby_sharing_service.h"
+#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 
 namespace {
 
@@ -79,28 +81,54 @@
 
 }  // namespace
 
-NearbyInternalsContactHandler::NearbyInternalsContactHandler() = default;
+NearbyInternalsContactHandler::NearbyInternalsContactHandler(
+    content::BrowserContext* context)
+    : context_(context) {}
 
 NearbyInternalsContactHandler::~NearbyInternalsContactHandler() = default;
 
 void NearbyInternalsContactHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
+      "initializeContacts",
+      base::BindRepeating(&NearbyInternalsContactHandler::InitializeContents,
+                          base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
       "downloadContacts",
       base::BindRepeating(
           &NearbyInternalsContactHandler::HandleDownloadContacts,
           base::Unretained(this)));
 }
 
-void NearbyInternalsContactHandler::OnJavascriptAllowed() {}
+void NearbyInternalsContactHandler::OnJavascriptAllowed() {
+  NearbySharingService* service_ =
+      NearbySharingServiceFactory::GetForBrowserContext(context_);
+  if (service_) {
+    observer_.Add(service_->GetContactManager());
+  } else {
+    NS_LOG(ERROR) << "No NearbyShareService instance to call.";
+  }
+}
 
-void NearbyInternalsContactHandler::OnJavascriptDisallowed() {}
+void NearbyInternalsContactHandler::OnJavascriptDisallowed() {
+  observer_.RemoveAll();
+}
+
+void NearbyInternalsContactHandler::InitializeContents(
+    const base::ListValue* args) {
+  AllowJavascript();
+}
 
 void NearbyInternalsContactHandler::HandleDownloadContacts(
     const base::ListValue* args) {
-  AllowJavascript();
-  // TODO(julietlevesque): Trigger Download Contact RPC. A boolean that
-  // represents whether the RPC should be forced is passed to this function from
-  // the JavaScript button interaction.
+  NearbySharingService* service_ =
+      NearbySharingServiceFactory::GetForBrowserContext(context_);
+  if (service_) {
+    const bool only_download_if_contacts_changed = args->GetList()[0].GetBool();
+    service_->GetContactManager()->DownloadContacts(
+        only_download_if_contacts_changed);
+  } else {
+    NS_LOG(ERROR) << "No NearbyShareService instance to call.";
+  }
 }
 
 void NearbyInternalsContactHandler::OnContactsUpdated(
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.h b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.h
index 80a3ddce..dc0e0a7 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.h
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.h
@@ -20,13 +20,17 @@
 class ListValue;
 }  // namespace base
 
+namespace content {
+class BrowserContext;
+}  // namespace content
+
 // WebUIMessageHandler for Contact Messages to pass messages to the
 // chrome://nearby-internals Contact tab.
 class NearbyInternalsContactHandler
     : public content::WebUIMessageHandler,
       public NearbyShareContactManager::Observer {
  public:
-  NearbyInternalsContactHandler();
+  explicit NearbyInternalsContactHandler(content::BrowserContext* context);
   NearbyInternalsContactHandler(const NearbyInternalsContactHandler&) = delete;
   NearbyInternalsContactHandler& operator=(
       const NearbyInternalsContactHandler&) = delete;
@@ -38,6 +42,9 @@
   void OnJavascriptDisallowed() override;
 
  private:
+  // Message handler callback that initializes JavaScript.
+  void InitializeContents(const base::ListValue* args);
+
   // NearbyShareContactManager::Observer:
   void OnContactsUpdated(
       bool contacts_list_changed,
@@ -51,9 +58,7 @@
   // manager.
   void HandleDownloadContacts(const base::ListValue* args);
 
-  // TODO(julietlevesque): Add observer functionality for
-  // NearbyShareContactManager observer in order to pass Contact messages to
-  // front-end.
+  content::BrowserContext* context_;
   ScopedObserver<NearbyShareContactManager, NearbyShareContactManager::Observer>
       observer_{this};
   base::WeakPtrFactory<NearbyInternalsContactHandler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
index 31c6064..1dc65012 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
@@ -32,7 +32,7 @@
 
 void NearbyInternalsHttpHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
-      "initialize",
+      "initializeHttp",
       base::BindRepeating(&NearbyInternalsHttpHandler::InitializeContents,
                           base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui.cc
index deb9c15e..af4a9b4 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui.cc
@@ -17,6 +17,8 @@
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/nearby_internals_resources.h"
 #include "chrome/grit/nearby_internals_resources_map.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/base/webui/web_ui_util.h"
@@ -42,10 +44,13 @@
       kNearbyInternalsGeneratedPath, IDR_NEARBY_INTERNALS_INDEX_HTML);
 
   content::WebUIDataSource::Add(profile, html_source);
+  content::BrowserContext* context =
+      web_ui->GetWebContents()->GetBrowserContext();
 
   web_ui->AddMessageHandler(std::make_unique<NearbyInternalsLogsHandler>());
   web_ui->AddMessageHandler(std::make_unique<NearbyInternalsHttpHandler>());
-  web_ui->AddMessageHandler(std::make_unique<NearbyInternalsContactHandler>());
+  web_ui->AddMessageHandler(
+      std::make_unique<NearbyInternalsContactHandler>(context));
 }
 
 NearbyInternalsUI::~NearbyInternalsUI() = default;
diff --git a/chrome/browser/ui/webui/profile_helper_browsertest.cc b/chrome/browser/ui/webui/profile_helper_browsertest.cc
index b463594..b191e4e 100644
--- a/chrome/browser/ui/webui/profile_helper_browsertest.cc
+++ b/chrome/browser/ui/webui/profile_helper_browsertest.cc
@@ -107,7 +107,7 @@
     // Shortcut deletion delays tests shutdown on Win-7 and results in time out.
     // See crbug.com/1073451.
 #if defined(OS_WIN)
-    AppShortcutManager::SuppressDeleteAllShortcutsForTesting();
+    AppShortcutManager::SuppressShortcutsForTesting();
 #endif
     InProcessBrowserTest::SetUp();
   }
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chrome/browser/ui/webui/settings/safety_check_handler.cc
index 167a0f9..d254ad3 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -160,9 +160,6 @@
   chrome_cleaner_status_ = ChromeCleanerStatus::kChecking;
 
   // Update WebUi.
-  FireBasicSafetyCheckWebUiListener(kParentEvent,
-                                    static_cast<int>(parent_status_),
-                                    GetStringForParent(parent_status_));
   FireBasicSafetyCheckWebUiListener(kUpdatesEvent,
                                     static_cast<int>(update_status_),
                                     GetStringForUpdates(update_status_));
@@ -182,6 +179,10 @@
       kChromeCleanerEvent, static_cast<int>(chrome_cleaner_status_),
       GetStringForChromeCleaner(chrome_cleaner_status_));
 #endif
+  // Parent update is last as it reveals the children elements.
+  FireBasicSafetyCheckWebUiListener(kParentEvent,
+                                    static_cast<int>(parent_status_),
+                                    GetStringForParent(parent_status_));
 }
 
 void SafetyCheckHandler::PerformSafetyCheck() {
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
index 213a2f5..160d1d20 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/callback.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/run_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
index 45826a4..2536b066 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -26,6 +26,10 @@
        IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE},
       {"profileTypeChoiceSubtitle",
        IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_SUBTITLE},
+      {"signInButtonLabel",
+       IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_SIGNIN_BUTTON_LABEL},
+      {"notNowButtonLabel",
+       IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_NOT_NOW_BUTTON_LABEL},
   };
   AddLocalizedStringsBulk(html_source, kLocalizedStrings);
 }
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
index 0a2cd79..0ca12ee 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -174,7 +174,7 @@
   // When testing, scale everything back so that a day passes in ten seconds.
   if (is_testing_) {
     constexpr int64_t scale_factor =
-        base::TimeDelta::FromDays(1).FltDiv(base::TimeDelta::FromSeconds(10));
+        base::TimeDelta::FromDays(1) / base::TimeDelta::FromSeconds(10);
     for (auto& stage : stages_)
       stage /= scale_factor;
   }
diff --git a/chrome/browser/web_applications/components/external_app_install_features.cc b/chrome/browser/web_applications/components/external_app_install_features.cc
index 3ad3da25..027f934 100644
--- a/chrome/browser/web_applications/components/external_app_install_features.cc
+++ b/chrome/browser/web_applications/components/external_app_install_features.cc
@@ -12,7 +12,17 @@
 
 // A hard coded list of features available for externally installed apps to gate
 // their installation on via their config file settings.
-constexpr base::Feature kExternalAppInstallFeatures[] = {};
+constexpr base::Feature kExternalAppInstallFeatures[] = {
+    // Enables migration of default installed GSuite apps over to their
+    // replacement web apps.
+    {"MigrateDefaultChromeAppToWebAppsGSuite",
+     base::FEATURE_DISABLED_BY_DEFAULT},
+
+    // Enables migration of default installed non-GSuite apps over to their
+    // replacement web apps.
+    {"MigrateDefaultChromeAppToWebAppsNonGSuite",
+     base::FEATURE_DISABLED_BY_DEFAULT},
+};
 
 bool g_always_enabled_for_testing = false;
 
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 26eeaa8..fa0f42f9 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1596488085-5cc589a537a51c7f4881b4c0be2ff92ccb84b267.profdata
+chrome-win32-master-1596517143-2f042d93a0262e3ee661fb2ff69050debe3380fe.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 32cc647..622012e 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1596475240-c04fb94f5c423840dafe90091ae571ba5e35789c.profdata
+chrome-win64-master-1596520791-9a2885d858aeb98ad5bcc11e2200637e7a775fe0.profdata
diff --git a/chrome/chrome_cleaner/pup_data/pup_cleaner_util_unittest.cc b/chrome/chrome_cleaner/pup_data/pup_cleaner_util_unittest.cc
index 96646e5..3598b6f 100644
--- a/chrome/chrome_cleaner/pup_data/pup_cleaner_util_unittest.cc
+++ b/chrome/chrome_cleaner/pup_data/pup_cleaner_util_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/chrome_cleaner/pup_data/pup_cleaner_util.h"
 
+#include <string>
+
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
@@ -35,14 +37,14 @@
         temp_dir_.GetPath(), L"subfolder", &subfolder_path_));
   }
 
-  base::FilePath CreateFileInTopDir(const base::string16& basename,
+  base::FilePath CreateFileInTopDir(const std::wstring& basename,
                                     const char* content) {
     base::FilePath file_path = temp_dir_.GetPath().Append(basename);
     CreateFileWithContent(file_path, content, strlen(content));
     return file_path;
   }
 
-  base::FilePath CreateFileInSubfolder(const base::string16& basename,
+  base::FilePath CreateFileInSubfolder(const std::wstring& basename,
                                        const char* content) {
     base::FilePath file_path = subfolder_path_.Append(basename);
     CreateFileWithContent(file_path, content, strlen(content));
diff --git a/chrome/chrome_cleaner/pup_data/pup_data.cc b/chrome/chrome_cleaner/pup_data/pup_data.cc
index cb83b66..9b9a25b 100644
--- a/chrome/chrome_cleaner/pup_data/pup_data.cc
+++ b/chrome/chrome_cleaner/pup_data/pup_data.cc
@@ -5,6 +5,7 @@
 #include "chrome/chrome_cleaner/pup_data/pup_data.h"
 
 #include <algorithm>
+#include <string>
 #include <utility>
 
 #include "base/check.h"
@@ -50,8 +51,8 @@
 
 PUPData::RegistryFootprint::RegistryFootprint(
     const RegKeyPath& key_path,
-    const base::string16& value_name,
-    const base::string16& value_substring,
+    const std::wstring& value_name,
+    const std::wstring& value_substring,
     RegistryMatchRule rule)
     : key_path(key_path),
       value_name(value_name),
diff --git a/chrome/chrome_cleaner/pup_data/pup_data.h b/chrome/chrome_cleaner/pup_data/pup_data.h
index f8bcff45..c5d83a9 100644
--- a/chrome/chrome_cleaner/pup_data/pup_data.h
+++ b/chrome/chrome_cleaner/pup_data/pup_data.h
@@ -199,8 +199,8 @@
   struct RegistryFootprint {
     RegistryFootprint();
     RegistryFootprint(const RegKeyPath& key_path,
-                      const base::string16& value_name,
-                      const base::string16& value_substring,
+                      const std::wstring& value_name,
+                      const std::wstring& value_substring,
                       RegistryMatchRule rule);
     RegistryFootprint(const RegistryFootprint& other);
     ~RegistryFootprint();
@@ -212,9 +212,9 @@
     // Must not be empty.
     RegKeyPath key_path;
     // Can be empty for default value or when value is unused.
-    base::string16 value_name;
+    std::wstring value_name;
     // Can be empty when unused.
-    base::string16 value_substring;
+    std::wstring value_substring;
     // Describe the way |value_substring| is used to match the content of the
     // registry value.
     RegistryMatchRule rule;
@@ -315,7 +315,7 @@
 
     // The list of expanded scheduled task names generated by the scanner.
     // Only populated by the legacy unsandboxed engine.
-    std::vector<base::string16> expanded_scheduled_tasks;
+    std::vector<std::wstring> expanded_scheduled_tasks;
 
     // Mapping from detected files to where they were found. Populated in the
     // target process when the engine is sandboxed.
diff --git a/chrome/chrome_cleaner/pup_data/pup_data_unittest.cc b/chrome/chrome_cleaner/pup_data/pup_data_unittest.cc
index aefa86db..8a41e01 100644
--- a/chrome/chrome_cleaner/pup_data/pup_data_unittest.cc
+++ b/chrome/chrome_cleaner/pup_data/pup_data_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/stl_util.h"
-#include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_reg_util_win.h"
 #include "chrome/chrome_cleaner/os/file_path_sanitization.h"
@@ -448,7 +447,7 @@
   // Make sure we can read and write.
   EXPECT_EQ(ERROR_SUCCESS,
             reg_key.WriteValue(k24RegistryValueName, k24RegistryValue));
-  base::string16 value;
+  std::wstring value;
   EXPECT_EQ(ERROR_SUCCESS, reg_key.ReadValue(k24RegistryValueName, &value));
   EXPECT_STREQ(k24RegistryValue, value.c_str());
   reg_key.Close();
@@ -465,7 +464,7 @@
   const RegKeyPath reg_key_path(HKEY_CURRENT_USER, k42RegistryKeyPath);
   EXPECT_TRUE(reg_key_path.Open(KEY_READ, &reg_key));
   // Make sure we can read the empty default value of the key.
-  base::string16 value;
+  std::wstring value;
   EXPECT_EQ(ERROR_SUCCESS, reg_key.ReadValue(k24RegistryValueName, &value));
   EXPECT_STREQ(k24RegistryValue, value.c_str());
   EXPECT_TRUE(reg_key.Valid());
@@ -488,8 +487,8 @@
 }
 
 TEST_F(PUPDataTest, CommonSeparators) {
-  base::string16 delimiters(PUPData::kCommonDelimiters,
-                            PUPData::kCommonDelimitersLength);
+  std::wstring delimiters(PUPData::kCommonDelimiters,
+                          PUPData::kCommonDelimitersLength);
   EXPECT_EQ(3UL, delimiters.size());
   EXPECT_NE(delimiters.find(L','), std::string::npos);
   EXPECT_NE(delimiters.find(L' '), std::string::npos);
@@ -500,8 +499,8 @@
 }
 
 TEST_F(PUPDataTest, CommaSeparators) {
-  base::string16 delimiters(PUPData::kCommaDelimiter,
-                            PUPData::kCommaDelimiterLength);
+  std::wstring delimiters(PUPData::kCommaDelimiter,
+                          PUPData::kCommaDelimiterLength);
   EXPECT_EQ(1UL, delimiters.size());
   EXPECT_NE(delimiters.find(L','), std::string::npos);
   EXPECT_EQ(delimiters.find(L' '), std::string::npos);
diff --git a/chrome/chrome_cleaner/scanner/matcher_util.h b/chrome/chrome_cleaner/scanner/matcher_util.h
index 6a3b4474..c87da9a 100644
--- a/chrome/chrome_cleaner/scanner/matcher_util.h
+++ b/chrome/chrome_cleaner/scanner/matcher_util.h
@@ -9,8 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "base/strings/string16.h"
-
 namespace base {
 class FilePath;
 }  // namespace base
diff --git a/chrome/chrome_cleaner/scanner/scanner_controller.cc b/chrome/chrome_cleaner/scanner/scanner_controller.cc
index 4b534b1..7b567e0d 100644
--- a/chrome/chrome_cleaner/scanner/scanner_controller.cc
+++ b/chrome/chrome_cleaner/scanner/scanner_controller.cc
@@ -6,7 +6,9 @@
 
 #include <stdlib.h>
 #include <time.h>
+
 #include <memory>
+#include <string>
 
 #include "base/bind.h"
 #include "base/check_op.h"
@@ -153,7 +155,7 @@
 
   LoggingServiceAPI* logging_service_api = LoggingServiceAPI::GetInstance();
 
-  const base::string16 kChromeExecutableName = L"chrome.exe";
+  const std::wstring kChromeExecutableName = L"chrome.exe";
   bool has_modified_shortcuts = false;
   for (const auto& shortcut : shortcuts_found_) {
     base::FilePath target_path(shortcut.target_path);
diff --git a/chrome/chrome_cleaner/scanner/signature_matcher_api.h b/chrome/chrome_cleaner/scanner/signature_matcher_api.h
index 882f826..cbd51ac 100644
--- a/chrome/chrome_cleaner/scanner/signature_matcher_api.h
+++ b/chrome/chrome_cleaner/scanner/signature_matcher_api.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/files/file_path.h"
-#include "base/strings/string16.h"
 
 namespace chrome_cleaner {
 
@@ -18,8 +17,8 @@
 // This structure holds version information about an executable.
 // (see: base/file_version_info.h)
 struct VersionInformation {
-  base::string16 company_name;
-  base::string16 original_filename;
+  std::wstring company_name;
+  std::wstring original_filename;
 };
 
 // This class is used as a wrapper around the signature matcher calls. The
diff --git a/chrome/chrome_cleaner/settings/settings.cc b/chrome/chrome_cleaner/settings/settings.cc
index b117df9e..fa8967a 100644
--- a/chrome/chrome_cleaner/settings/settings.cc
+++ b/chrome/chrome_cleaner/settings/settings.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <set>
+#include <string>
 
 #include "base/command_line.h"
 #include "base/guid.h"
@@ -26,7 +27,7 @@
 
 // Returns the value associated with flag --session-id when it's present or
 // empty string when it's not found.
-base::string16 GetSessionId(const base::CommandLine& command_line) {
+std::wstring GetSessionId(const base::CommandLine& command_line) {
   return command_line.GetSwitchValueNative(kSessionIdSwitch);
 }
 
@@ -238,7 +239,7 @@
   return allow_crash_report_upload_;
 }
 
-base::string16 Settings::session_id() const {
+std::wstring Settings::session_id() const {
   return session_id_;
 }
 
diff --git a/chrome/chrome_cleaner/settings/settings.h b/chrome/chrome_cleaner/settings/settings.h
index f3ebf99e..05d39ef 100644
--- a/chrome/chrome_cleaner/settings/settings.h
+++ b/chrome/chrome_cleaner/settings/settings.h
@@ -6,13 +6,13 @@
 #define CHROME_CHROME_CLEANER_SETTINGS_SETTINGS_H_
 
 #include <windows.h>
+
 #include <string>
 #include <unordered_map>
 #include <vector>
 
 #include "base/command_line.h"
 #include "base/memory/singleton.h"
-#include "base/strings/string16.h"
 #include "chrome/chrome_cleaner/logging/proto/shared_data.pb.h"
 #include "chrome/chrome_cleaner/settings/settings_definitions.h"
 #include "components/chrome_cleaner/public/constants/constants.h"
@@ -38,7 +38,7 @@
   virtual bool allow_crash_report_upload() const;
 
   // Returns the session id for this run as passed by Chrome to the reporter.
-  virtual base::string16 session_id() const;
+  virtual std::wstring session_id() const;
 
   virtual std::string cleanup_id() const;
 
@@ -183,7 +183,7 @@
 
   // Statistics about the current run.
   std::string cleanup_id_;
-  base::string16 session_id_;
+  std::wstring session_id_;
 
   // Execution parameters.
   ExecutionMode execution_mode_ = ExecutionMode::kNone;
diff --git a/chrome/chrome_cleaner/strings/string_test_helpers.cc b/chrome/chrome_cleaner/strings/string_test_helpers.cc
index f1e8651..55caa92 100644
--- a/chrome/chrome_cleaner/strings/string_test_helpers.cc
+++ b/chrome/chrome_cleaner/strings/string_test_helpers.cc
@@ -4,12 +4,13 @@
 
 #include <algorithm>
 #include <sstream>
+#include <string>
 
 #include "chrome/chrome_cleaner/strings/string_test_helpers.h"
 
 namespace chrome_cleaner {
 
-std::vector<wchar_t> CreateVectorWithNulls(const base::string16& str) {
+std::vector<wchar_t> CreateVectorWithNulls(const std::wstring& str) {
   std::vector<wchar_t> str_with_nulls(str.begin(), str.end());
   std::replace(str_with_nulls.begin(), str_with_nulls.end(), L'0', L'\0');
   // Make sure the resulting vector ends with a null. NtOpenKey requires a
@@ -19,7 +20,7 @@
   return str_with_nulls;
 }
 
-base::string16 FormatVectorWithNulls(const std::vector<wchar_t>& v) {
+std::wstring FormatVectorWithNulls(const std::vector<wchar_t>& v) {
   std::wostringstream ss;
   for (wchar_t c : v) {
     if (c)
diff --git a/chrome/chrome_cleaner/strings/string_test_helpers.h b/chrome/chrome_cleaner/strings/string_test_helpers.h
index 8db4b70..05f7935c 100644
--- a/chrome/chrome_cleaner/strings/string_test_helpers.h
+++ b/chrome/chrome_cleaner/strings/string_test_helpers.h
@@ -5,18 +5,17 @@
 #ifndef CHROME_CHROME_CLEANER_STRINGS_STRING_TEST_HELPERS_H_
 #define CHROME_CHROME_CLEANER_STRINGS_STRING_TEST_HELPERS_H_
 
+#include <string>
 #include <vector>
 
-#include "base/strings/string16.h"
-
 namespace chrome_cleaner {
 
 // Turns a string constant into a vector containing embedded nulls by
 // converting every '0' to null.
-std::vector<wchar_t> CreateVectorWithNulls(const base::string16& str);
+std::vector<wchar_t> CreateVectorWithNulls(const std::wstring& str);
 
 // Returns a string16 obtained from |v| by replacing null characters with "\\0".
-base::string16 FormatVectorWithNulls(const std::vector<wchar_t>& v);
+std::wstring FormatVectorWithNulls(const std::vector<wchar_t>& v);
 
 }  // namespace chrome_cleaner
 
diff --git a/chrome/chrome_cleaner/strings/string_util.cc b/chrome/chrome_cleaner/strings/string_util.cc
index 4636c8f..ff0471c 100644
--- a/chrome/chrome_cleaner/strings/string_util.cc
+++ b/chrome/chrome_cleaner/strings/string_util.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <map>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -21,16 +22,16 @@
 // A map from (text offset, pattern offest) to bool.
 typedef std::map<std::pair<size_t, size_t>, bool> WildcardMatchCache;
 
-bool String16WildcardMatchRecursive(const base::string16& text,
+bool String16WildcardMatchRecursive(const std::wstring& text,
                                     size_t text_offset,
-                                    const base::string16& pattern,
+                                    const std::wstring& pattern,
                                     size_t pattern_offset,
                                     const wchar_t escape_char,
                                     WildcardMatchCache* cache);
 
-bool String16WildcardMatchRecursiveCached(const base::string16& text,
+bool String16WildcardMatchRecursiveCached(const std::wstring& text,
                                           size_t text_offset,
-                                          const base::string16& pattern,
+                                          const std::wstring& pattern,
                                           size_t pattern_offset,
                                           const wchar_t escape_char,
                                           WildcardMatchCache* cache) {
@@ -50,9 +51,9 @@
   return result;
 }
 
-bool String16WildcardMatchRecursive(const base::string16& text,
+bool String16WildcardMatchRecursive(const std::wstring& text,
                                     size_t text_offset,
-                                    const base::string16& pattern,
+                                    const std::wstring& pattern,
                                     size_t pattern_offset,
                                     const wchar_t escape_char,
                                     WildcardMatchCache* cache) {
@@ -124,29 +125,29 @@
 
 }  // namespace
 
-bool String16EqualsCaseInsensitive(const base::string16& str1,
-                                   const base::string16& str2) {
+bool String16EqualsCaseInsensitive(const std::wstring& str1,
+                                   const std::wstring& str2) {
   return _wcsicmp(str1.c_str(), str2.c_str()) == 0;
 }
 
-bool String16ContainsCaseInsensitive(const base::string16& value,
-                                     const base::string16& substring) {
+bool String16ContainsCaseInsensitive(const std::wstring& value,
+                                     const std::wstring& substring) {
   return std::search(
              value.begin(), value.end(), substring.begin(), substring.end(),
-             base::CaseInsensitiveCompareASCII<base::string16::value_type>()) !=
+             base::CaseInsensitiveCompareASCII<std::wstring::value_type>()) !=
          value.end();
 }
 
-bool String16SetMatchEntry(const base::string16& value,
-                           const base::string16& delimiters,
-                           const base::string16& substring,
+bool String16SetMatchEntry(const std::wstring& value,
+                           const std::wstring& delimiters,
+                           const std::wstring& substring,
                            String16Matcher matcher) {
   // Split the string in tokens.
-  std::vector<base::string16> tokens = base::SplitString(
+  std::vector<std::wstring> tokens = base::SplitString(
       value, delimiters, base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
   // Search for a matching token.
-  for (std::vector<base::string16>::const_iterator it = tokens.begin();
+  for (std::vector<std::wstring>::const_iterator it = tokens.begin();
        it != tokens.end(); ++it) {
     if (matcher(*it, substring))
       return true;
@@ -154,8 +155,8 @@
   return false;
 }
 
-bool String16WildcardMatchInsensitive(const base::string16& text,
-                                      const base::string16& pattern,
+bool String16WildcardMatchInsensitive(const std::wstring& text,
+                                      const std::wstring& pattern,
                                       const wchar_t escape_char) {
   // TODO(crbug.com/837637): Check the performance of Chromium's MatchPattern
   // and replace this with it if possible.
diff --git a/chrome/chrome_cleaner/strings/string_util.h b/chrome/chrome_cleaner/strings/string_util.h
index 63e55b73..c65c0ff 100644
--- a/chrome/chrome_cleaner/strings/string_util.h
+++ b/chrome/chrome_cleaner/strings/string_util.h
@@ -10,48 +10,45 @@
 #include <set>
 #include <string>
 
-#include "base/strings/string16.h"
-
 namespace chrome_cleaner {
 
 struct String16InsensitiveLess {
-  bool operator()(const base::string16& str1,
-                  const base::string16& str2) const {
+  bool operator()(const std::wstring& str1, const std::wstring& str2) const {
     return _wcsicmp(str1.c_str(), str2.c_str()) < 0;
   }
 };
 
-typedef std::set<base::string16, String16InsensitiveLess>
+typedef std::set<std::wstring, String16InsensitiveLess>
     String16CaseInsensitiveSet;
 
 // A function that returns true if |pattern| matches |value|, for some
 // definition of "matches".
-typedef bool (*String16Matcher)(const base::string16& value,
-                                const base::string16& pattern);
+typedef bool (*String16Matcher)(const std::wstring& value,
+                                const std::wstring& pattern);
 
 // Returns true when both strings are equal, ignoring the string case.
-bool String16EqualsCaseInsensitive(const base::string16& str1,
-                                   const base::string16& str2);
+bool String16EqualsCaseInsensitive(const std::wstring& str1,
+                                   const std::wstring& str2);
 
 // Returns true when |value| contains an occurrence of |substring|, ignoring
 // the string case.
-bool String16ContainsCaseInsensitive(const base::string16& value,
-                                     const base::string16& substring);
+bool String16ContainsCaseInsensitive(const std::wstring& value,
+                                     const std::wstring& substring);
 
 // Splits |value| into a set of strings separated by any characters in
 // |delimiters|, and returns true if any entry of the set is matched by
 // |matcher|.
-bool String16SetMatchEntry(const base::string16& value,
-                           const base::string16& delimiters,
-                           const base::string16& substring,
+bool String16SetMatchEntry(const std::wstring& value,
+                           const std::wstring& delimiters,
+                           const std::wstring& substring,
                            String16Matcher matcher);
 
 // Returns true if |text| matches |pattern|. |pattern| can contain can
 // wild-cards like * and ?. |escape_char| is an escape character for * and ?.
 // The ? wild-card matches exactly 1 character, while the * wild-card matches 0
 // or more characters.
-bool String16WildcardMatchInsensitive(const base::string16& text,
-                                      const base::string16& pattern,
+bool String16WildcardMatchInsensitive(const std::wstring& text,
+                                      const std::wstring& pattern,
                                       const wchar_t escape_char);
 
 // Returns a copy of |input| without any invalid UTF8 characters.
diff --git a/chrome/chrome_cleaner/strings/string_util_unittest.cc b/chrome/chrome_cleaner/strings/string_util_unittest.cc
index 6e97c39..f9775b0f 100644
--- a/chrome/chrome_cleaner/strings/string_util_unittest.cc
+++ b/chrome/chrome_cleaner/strings/string_util_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/chrome_cleaner/strings/string_util.h"
 
+#include <string>
+
 #include "base/strings/string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -27,8 +29,8 @@
 const char kNoCharsLeftOnlySpaces[] = "  ";
 const char kSingleInvalidUTF8Char[] = "\xf1";
 
-bool WildcardMatchInsensitive(const base::string16& text,
-                              const base::string16& pattern) {
+bool WildcardMatchInsensitive(const std::wstring& text,
+                              const std::wstring& pattern) {
   return String16WildcardMatchInsensitive(text, pattern, L'\\');
 }
 
diff --git a/chrome/chrome_cleaner/test/cleaner_test.cc b/chrome/chrome_cleaner/test/cleaner_test.cc
index 1671b17a..f554c80 100644
--- a/chrome/chrome_cleaner/test/cleaner_test.cc
+++ b/chrome/chrome_cleaner/test/cleaner_test.cc
@@ -54,7 +54,7 @@
 // Case 2: A registry value contains paths which would ideally be sanitized,
 //   but the exact value should be reported to prevent ambiguity. Currently this
 //   generally means we just ignore the registry fields in the proto.
-const std::vector<base::string16> kAllowedLogStringsForSanitizationCheck = {
+const std::vector<std::wstring> kAllowedLogStringsForSanitizationCheck = {
     // TryToExpandPath() in disk_util.cc fits Case 1.
     L"] unable to retrieve file information on non-existing file: \'",
 
@@ -82,19 +82,19 @@
          report->ParseFromString(dumped_proto_string);
 }
 
-base::string16 StringToWLower(const base::string16& source) {
+std::wstring StringToWLower(const std::wstring& source) {
   // TODO(joenotcharles): Investigate moving this into string_util.cc and using
   // it instead of ToLowerASCII() through the whole code base. Case insensitive
   // compares will also need to be changed.
-  base::string16 copy = source;
+  std::wstring copy = source;
   for (wchar_t& character : copy) {
     character = towlower(character);
   }
   return copy;
 }
 
-std::vector<base::string16> GetUnsanitizedPaths() {
-  std::vector<base::string16> unsanitized_path_strings;
+std::vector<std::wstring> GetUnsanitizedPaths() {
+  std::vector<std::wstring> unsanitized_path_strings;
   bool success = true;
   for (const auto& entry : chrome_cleaner::PathKeyToSanitizeString()) {
     int id = entry.first;
@@ -104,7 +104,7 @@
       success = false;
       continue;
     }
-    base::string16 unsanitized_path_string =
+    std::wstring unsanitized_path_string =
         StringToWLower(unsanitized_path.value());
     unsanitized_path_strings.push_back(unsanitized_path_string);
   }
@@ -112,11 +112,11 @@
   return unsanitized_path_strings;
 }
 
-bool ContainsAnyOf(const base::string16& main_string,
-                   const std::vector<base::string16>& substrings) {
+bool ContainsAnyOf(const std::wstring& main_string,
+                   const std::vector<std::wstring>& substrings) {
   return std::any_of(substrings.begin(), substrings.end(),
-                     [&main_string](const base::string16& path) -> bool {
-                       return main_string.find(path) != base::string16::npos;
+                     [&main_string](const std::wstring& path) -> bool {
+                       return main_string.find(path) != std::wstring::npos;
                      });
 }
 
@@ -124,7 +124,7 @@
 void CheckFieldForUnsanitizedPaths(
     const RepeatedTypeWithFileInformation& field,
     const std::string& field_name,
-    const std::vector<base::string16>& unsanitized_path_strings) {
+    const std::vector<std::wstring>& unsanitized_path_strings) {
   for (const auto& sub_field : field) {
     std::string utf8_path = sub_field.file_information().path();
     EXPECT_FALSE(ContainsAnyOf(StringToWLower(base::UTF8ToWide(utf8_path)),
@@ -136,7 +136,7 @@
 bool CheckCleanerReportForUnsanitizedPaths(
     const chrome_cleaner::ChromeCleanerReport& report) {
   EXPECT_GT(report.raw_log_line_size(), 0);
-  std::vector<base::string16> unsanitized_path_strings = GetUnsanitizedPaths();
+  std::vector<std::wstring> unsanitized_path_strings = GetUnsanitizedPaths();
   size_t line_number = 0;
   for (const auto& utf8_line : report.raw_log_line()) {
     ++line_number;
@@ -293,7 +293,7 @@
     ASSERT_TRUE(
         chrome_cleaner::ComputeSHA256DigestOfString(uws_content, &uws_hash));
 
-    const base::string16 zip_filename =
+    const std::wstring zip_filename =
         chrome_cleaner::internal::ConstructZipArchiveFileName(
             chrome_cleaner::kTestUwsBFilename, uws_hash,
             /*max_filename_length=*/255);
diff --git a/chrome/chrome_cleaner/test/generate_test_uws_test.cc b/chrome/chrome_cleaner/test/generate_test_uws_test.cc
index 89d80b7..9882ad4 100644
--- a/chrome/chrome_cleaner/test/generate_test_uws_test.cc
+++ b/chrome/chrome_cleaner/test/generate_test_uws_test.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+
 #include "base/base_paths_win.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
@@ -10,7 +12,6 @@
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
-#include "base/strings/string16.h"
 #include "base/test/test_timeouts.h"
 #include "chrome/chrome_cleaner/pup_data/test_uws.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/chrome_cleaner/test/reboot_deletion_helper.cc b/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
index 5285768..a76be87 100644
--- a/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
+++ b/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
@@ -6,6 +6,8 @@
 
 #include <windows.h>
 
+#include <string>
+
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
@@ -31,7 +33,7 @@
 // is a pointer to an empty vector of pending moves. On success, this vector
 // contains all of the strings extracted from |buffer|.
 // Returns false if buffer does not meet the above specification.
-bool MultiSZToStringArray(const base::string16& buffer,
+bool MultiSZToStringArray(const std::wstring& buffer,
                           std::vector<PendingMove>* value) {
   DCHECK(value);
   DCHECK(value->empty());
@@ -42,13 +44,13 @@
   // Put null-terminated strings into the sequence.
   while (data < data_end) {
     // Parse the source path.
-    base::string16 str_from(data);
+    std::wstring str_from(data);
     data += str_from.length() + 1;
 
     // Parse the destination path. If the offset is at the end of the string,
     // we assume the destination is empty. This may happen with corrupt registry
     // values where there are missing trailing null characters.
-    base::string16 str_to;
+    std::wstring str_to;
     if (data > data_end)
       return false;
     if (data < data_end)
@@ -66,7 +68,7 @@
 // kPendingFileRenameOps registry value. It concatenates the strings and
 // appends an additional terminating null character.
 void StringArrayToMultiSZ(const std::vector<PendingMove>& pending_moves,
-                          base::string16* buffer) {
+                          std::wstring* buffer) {
   DCHECK(buffer);
   buffer->clear();
 
@@ -116,7 +118,7 @@
 // then GetShortPathName will return |path| unchanged, unlike the win32
 // GetShortPathName which will return an error.
 base::FilePath GetShortPathName(const base::FilePath& path) {
-  base::string16 short_path;
+  std::wstring short_path;
   DWORD length = ::GetShortPathName(
       path.value().c_str(), base::WriteInto(&short_path, MAX_PATH), MAX_PATH);
   DPLOG_IF(WARNING, length == 0 && ::GetLastError() != ERROR_PATH_NOT_FOUND)
@@ -134,10 +136,10 @@
 
 base::FilePath GetShortPathNameWithoutPrefix(const base::FilePath& reg_path) {
   // Stores the path stored in each entry.
-  base::string16 match_path(reg_path.value());
+  std::wstring match_path(reg_path.value());
 
   // First chomp the prefix since that will mess up GetShortPathName.
-  base::string16 prefix(L"\\??\\");
+  std::wstring prefix(L"\\??\\");
   if (base::StartsWith(match_path, prefix,
                        base::CompareCase::INSENSITIVE_ASCII))
     match_path = match_path.substr(4);
@@ -231,7 +233,7 @@
   }
 
   // Read the content of the registry value to retrieve the pending moves.
-  base::string16 pending_moves_value;
+  std::wstring pending_moves_value;
   uint32_t pending_moves_value_type;
   if (!ReadRegistryValue(session_manager_key, kPendingFileRenameOps,
                          &pending_moves_value, &pending_moves_value_type,
@@ -281,14 +283,14 @@
   }
 
   // Serialize pending moves as a sequence of bytes.
-  base::string16 buffer;
+  std::wstring buffer;
   StringArrayToMultiSZ(pending_moves, &buffer);
   if (buffer.empty())
     return false;
 
   // The pending moves format needs a null entry at the end which consists of
   // two MULTISZ empty string.
-  base::string16 last_entry(kDoubleNullEntry, base::size(kDoubleNullEntry) - 1);
+  std::wstring last_entry(kDoubleNullEntry, base::size(kDoubleNullEntry) - 1);
   buffer = buffer + last_entry;
 
   // Write back the serialized values into the registry key.
diff --git a/chrome/chrome_cleaner/test/reboot_deletion_helper.h b/chrome/chrome_cleaner/test/reboot_deletion_helper.h
index 1a9165e..4b14dcb 100644
--- a/chrome/chrome_cleaner/test/reboot_deletion_helper.h
+++ b/chrome/chrome_cleaner/test/reboot_deletion_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_CHROME_CLEANER_TEST_REBOOT_DELETION_HELPER_H_
 #define CHROME_CHROME_CLEANER_TEST_REBOOT_DELETION_HELPER_H_
 
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -14,7 +15,7 @@
 
 // Holds the (source, destination) paths of a pending move. An empty
 // destination string means deletion instead of move.
-typedef std::pair<base::string16, base::string16> PendingMove;
+typedef std::pair<std::wstring, std::wstring> PendingMove;
 typedef std::vector<PendingMove> PendingMoveVector;
 
 // Returns true if the given file is registered to be deleted on the next
diff --git a/chrome/chrome_cleaner/test/scoped_file.cc b/chrome/chrome_cleaner/test/scoped_file.cc
index 6e19c37..66cff04 100644
--- a/chrome/chrome_cleaner/test/scoped_file.cc
+++ b/chrome/chrome_cleaner/test/scoped_file.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/chrome_cleaner/test/scoped_file.h"
 
+#include <string>
+
 #include "base/base_paths_win.h"
 #include "base/check_op.h"
 #include "base/files/file_util.h"
@@ -11,7 +13,7 @@
 
 // static
 std::unique_ptr<ScopedFile> ScopedFile::Create(const base::FilePath& dir,
-                                               const base::string16& file_name,
+                                               const std::wstring& file_name,
                                                const std::string& contents) {
   base::FilePath file_path = dir.Append(file_name);
   CHECK(base::PathExists(file_path.DirName()));
diff --git a/chrome/chrome_cleaner/test/scoped_file.h b/chrome/chrome_cleaner/test/scoped_file.h
index 69ef7aa..89a5d07 100644
--- a/chrome/chrome_cleaner/test/scoped_file.h
+++ b/chrome/chrome_cleaner/test/scoped_file.h
@@ -9,13 +9,12 @@
 #include <string>
 
 #include "base/files/file_path.h"
-#include "base/strings/string16.h"
 
 // Holds the path for a file that gets deleted on destruction.
 class ScopedFile {
  public:
   static std::unique_ptr<ScopedFile> Create(const base::FilePath& dir,
-                                            const base::string16& file_name,
+                                            const std::wstring& file_name,
                                             const std::string& contents);
 
   explicit ScopedFile(const base::FilePath& file_path);
diff --git a/chrome/chrome_cleaner/test/scoped_process_protector.cc b/chrome/chrome_cleaner/test/scoped_process_protector.cc
index b2dda83..5aaa67622 100644
--- a/chrome/chrome_cleaner/test/scoped_process_protector.cc
+++ b/chrome/chrome_cleaner/test/scoped_process_protector.cc
@@ -6,10 +6,11 @@
 
 #include <aclapi.h>
 
+#include <string>
+
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/logging.h"
-#include "base/strings/string16.h"
 
 namespace chrome_cleaner {
 
@@ -90,7 +91,7 @@
   static constexpr wchar_t kEveryoneGroup[] = L"EVERYONE";
 
   // The Trustee parameter requires a non-const string.
-  base::string16 trustee_name(kEveryoneGroup);
+  std::wstring trustee_name(kEveryoneGroup);
 
   EXPLICIT_ACCESS access = {};
   access.grfAccessPermissions = access_to_deny;
diff --git a/chrome/chrome_cleaner/test/secure_dll_loading_test.cc b/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
index d8c0fd0..05606388 100644
--- a/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
+++ b/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
@@ -8,6 +8,7 @@
 
 #include <memory>
 #include <set>
+#include <string>
 #include <vector>
 
 #include "base/base_paths.h"
@@ -18,7 +19,6 @@
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/waitable_event.h"
@@ -34,7 +34,7 @@
 #include "components/chrome_cleaner/test/test_name_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
+class SecureDLLLoadingTest : public testing::TestWithParam<std::wstring> {
  protected:
   void SetUp() override {
     ASSERT_TRUE(child_process_logger_.Initialize());
@@ -104,7 +104,7 @@
   }
 
   bool EmptyDLLLoaded(const base::Process& process) {
-    std::set<base::string16> module_paths;
+    std::set<std::wstring> module_paths;
     chrome_cleaner::GetLoadedModuleFileNames(process.Handle(), &module_paths);
 
     for (const auto& module_path : module_paths) {
diff --git a/chrome/chrome_cleaner/test/test_executables.h b/chrome/chrome_cleaner/test/test_executables.h
index 45fbc3e..7891b2d 100644
--- a/chrome/chrome_cleaner/test/test_executables.h
+++ b/chrome/chrome_cleaner/test/test_executables.h
@@ -5,9 +5,10 @@
 #ifndef CHROME_CHROME_CLEANER_TEST_TEST_EXECUTABLES_H_
 #define CHROME_CHROME_CLEANER_TEST_TEST_EXECUTABLES_H_
 
+#include <string>
+
 #include "base/command_line.h"
 #include "base/process/process.h"
-#include "base/strings/string16.h"
 
 namespace chrome_cleaner {
 
diff --git a/chrome/chrome_cleaner/test/test_extensions.cc b/chrome/chrome_cleaner/test/test_extensions.cc
index 873f1c8..da74572a 100644
--- a/chrome/chrome_cleaner/test/test_extensions.cc
+++ b/chrome/chrome_cleaner/test/test_extensions.cc
@@ -4,15 +4,17 @@
 
 #include "chrome/chrome_cleaner/test/test_extensions.h"
 
+#include <string>
+
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 
 namespace chrome_cleaner {
 
 TestRegistryEntry::TestRegistryEntry(HKEY hkey,
-                                     const base::string16& path,
-                                     const base::string16& name,
-                                     const base::string16& value)
+                                     const std::wstring& path,
+                                     const std::wstring& name,
+                                     const std::wstring& value)
     : hkey(hkey), path(path), name(name), value(value) {}
 TestRegistryEntry::TestRegistryEntry(const TestRegistryEntry& other) = default;
 TestRegistryEntry& TestRegistryEntry::operator=(
@@ -20,8 +22,8 @@
 
 bool CreateProfileWithExtensionAndFiles(
     const base::FilePath& profile_path,
-    const base::string16& extension_id,
-    const std::vector<base::string16>& extension_files) {
+    const std::wstring& extension_id,
+    const std::vector<std::wstring>& extension_files) {
   if (!base::CreateDirectory(profile_path))
     return false;
 
@@ -33,7 +35,7 @@
   if (!base::CreateDirectory(extension_path))
     return false;
 
-  for (const base::string16& file_name : extension_files) {
+  for (const std::wstring& file_name : extension_files) {
     base::File extension_file(
         extension_path.Append(file_name),
         base::File::Flags::FLAG_CREATE | base::File::Flags::FLAG_READ);
diff --git a/chrome/chrome_cleaner/test/test_extensions.h b/chrome/chrome_cleaner/test/test_extensions.h
index aa64c42..9463a3c 100644
--- a/chrome/chrome_cleaner/test/test_extensions.h
+++ b/chrome/chrome_cleaner/test/test_extensions.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_CHROME_CLEANER_TEST_TEST_EXTENSIONS_H_
 #define CHROME_CHROME_CLEANER_TEST_TEST_EXTENSIONS_H_
 
+#include <string>
 #include <vector>
 
 #include "base/files/file_path.h"
-#include "base/strings/string16.h"
 #include "base/win/registry.h"
 #include "chrome/chrome_cleaner/os/registry_util.h"
 
@@ -16,14 +16,14 @@
 
 struct TestRegistryEntry {
   HKEY hkey;
-  base::string16 path;
-  base::string16 name;
-  base::string16 value;
+  std::wstring path;
+  std::wstring name;
+  std::wstring value;
 
   TestRegistryEntry(HKEY hkey,
-                    const base::string16& path,
-                    const base::string16& name,
-                    const base::string16& value);
+                    const std::wstring& path,
+                    const std::wstring& name,
+                    const std::wstring& value);
   TestRegistryEntry(const TestRegistryEntry& other);
   TestRegistryEntry& operator=(const TestRegistryEntry& other);
 };
@@ -45,7 +45,7 @@
 // Test force installed extension settings
 const TestRegistryEntry kExtensionForcelistEntries[] = {
     {HKEY_LOCAL_MACHINE, kChromePoliciesForcelistKeyPath, L"test1",
-     base::string16(kTestExtensionId3) + L"https://test.test/crxupdate2/crx"}};
+     std::wstring(kTestExtensionId3) + L"https://test.test/crxupdate2/crx"}};
 const char kValidExtensionSettingsJson[] =
     "{\"extensionwithinstallmodeblockeda\":{\"installation_mode\":\"blocked\","
     "\"update_url\":"
@@ -133,8 +133,8 @@
 
 bool CreateProfileWithExtensionAndFiles(
     const base::FilePath& profile_path,
-    const base::string16& extension_id,
-    const std::vector<base::string16>& extension_files);
+    const std::wstring& extension_id,
+    const std::vector<std::wstring>& extension_files);
 
 }  // namespace chrome_cleaner
 
diff --git a/chrome/chrome_cleaner/test/test_file_util.cc b/chrome/chrome_cleaner/test/test_file_util.cc
index e784aa1..8303a4ad 100644
--- a/chrome/chrome_cleaner/test/test_file_util.cc
+++ b/chrome/chrome_cleaner/test/test_file_util.cc
@@ -6,6 +6,8 @@
 
 #include <windows.h>
 
+#include <string>
+
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -29,7 +31,7 @@
 }
 
 bool CreateFileInFolder(const base::FilePath& folder,
-                        const base::string16& name) {
+                        const std::wstring& name) {
   DCHECK(!name.empty());
   DCHECK(base::PathExists(folder));
   base::FilePath file_path = folder.Append(name);
@@ -60,13 +62,13 @@
 
 base::win::ScopedHandle CreateFileWithContent(
     const std::string& content,
-    const base::string16& file_name,
+    const std::wstring& file_name,
     const base::ScopedTempDir& temp_dir) {
   base::FilePath path(temp_dir.GetPath().Append(file_name));
   EXPECT_NE(base::WriteFile(path, content.c_str(), content.size()), -1);
-  base::string16 utf16_file_path = path.value();
+  std::wstring wide_file_path = path.value();
   base::win::ScopedHandle file_handle(
-      ::CreateFile(utf16_file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
+      ::CreateFile(wide_file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
   EXPECT_TRUE(file_handle.IsValid());
   return file_handle;
@@ -82,7 +84,7 @@
       ::GetShortPathName(long_name_path.value().c_str(), nullptr, 0);
   ASSERT_GT(short_name_len, 0UL);
 
-  base::string16 short_name_string;
+  std::wstring short_name_string;
   short_name_len = ::GetShortPathName(
       long_name_path.value().c_str(),
       base::WriteInto(&short_name_string, short_name_len), short_name_len);
diff --git a/chrome/chrome_cleaner/test/test_file_util.h b/chrome/chrome_cleaner/test/test_file_util.h
index cec2606..6c9d1a2 100644
--- a/chrome/chrome_cleaner/test/test_file_util.h
+++ b/chrome/chrome_cleaner/test/test_file_util.h
@@ -9,14 +9,12 @@
 
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/strings/string16.h"
 #include "base/win/scoped_handle.h"
 
 namespace chrome_cleaner {
 
 // Create an empty file named |name| under |folder|. Return false on failure.
-bool CreateFileInFolder(const base::FilePath& folder,
-                        const base::string16& name);
+bool CreateFileInFolder(const base::FilePath& folder, const std::wstring& name);
 
 // Create an empty file for path |path|. Return true on success.
 bool CreateEmptyFile(const base::FilePath& path);
@@ -29,7 +27,7 @@
 // Creates a file |file_name| in |temp_dir| with the specified |content|.
 base::win::ScopedHandle CreateFileWithContent(
     const std::string& content,
-    const base::string16& file_name,
+    const std::wstring& file_name,
     const base::ScopedTempDir& temp_dir);
 
 // Create a file |path| by writing |count| times the content |content|.
diff --git a/chrome/chrome_cleaner/test/test_native_reg_util.cc b/chrome/chrome_cleaner/test/test_native_reg_util.cc
index 7ec27c8..e3879ee9 100644
--- a/chrome/chrome_cleaner/test/test_native_reg_util.cc
+++ b/chrome/chrome_cleaner/test/test_native_reg_util.cc
@@ -4,9 +4,10 @@
 
 #include "chrome/chrome_cleaner/test/test_native_reg_util.h"
 
+#include <string>
+
 #include "base/guid.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_reg_util_win.h"
@@ -44,11 +45,11 @@
   return reg_key_.Handle();
 }
 
-const base::string16& ScopedTempRegistryKey::Path() const {
+const std::wstring& ScopedTempRegistryKey::Path() const {
   return key_path_;
 }
 
-const base::string16& ScopedTempRegistryKey::FullyQualifiedPath() const {
+const std::wstring& ScopedTempRegistryKey::FullyQualifiedPath() const {
   return fully_qualified_key_path_;
 }
 
diff --git a/chrome/chrome_cleaner/test/test_native_reg_util.h b/chrome/chrome_cleaner/test/test_native_reg_util.h
index 02732d09..ec8244d 100644
--- a/chrome/chrome_cleaner/test/test_native_reg_util.h
+++ b/chrome/chrome_cleaner/test/test_native_reg_util.h
@@ -5,9 +5,9 @@
 #ifndef CHROME_CHROME_CLEANER_TEST_TEST_NATIVE_REG_UTIL_H_
 #define CHROME_CHROME_CLEANER_TEST_TEST_NATIVE_REG_UTIL_H_
 
+#include <string>
 #include <vector>
 
-#include "base/strings/string16.h"
 #include "base/win/registry.h"
 
 namespace chrome_cleaner_sandbox {
@@ -22,14 +22,14 @@
   HANDLE Get();
 
   // Returne the relative registry path.
-  const base::string16& Path() const;
+  const std::wstring& Path() const;
 
   // Returns a fully qualified native registry path.
-  const base::string16& FullyQualifiedPath() const;
+  const std::wstring& FullyQualifiedPath() const;
 
  private:
-  base::string16 key_path_;
-  base::string16 fully_qualified_key_path_;
+  std::wstring key_path_;
+  std::wstring fully_qualified_key_path_;
   base::win::RegKey reg_key_;
 };
 
diff --git a/chrome/chrome_cleaner/test/test_process_main.cc b/chrome/chrome_cleaner/test/test_process_main.cc
index 8e01a0e..82534234 100644
--- a/chrome/chrome_cleaner/test/test_process_main.cc
+++ b/chrome/chrome_cleaner/test/test_process_main.cc
@@ -10,7 +10,6 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
@@ -80,7 +79,7 @@
   if (command_line->HasSwitch(chrome_cleaner::kTestEventToSignal)) {
     LOG(INFO) << "Process is signaling event '"
               << chrome_cleaner::kTestEventToSignal << "'";
-    base::string16 event_name =
+    std::wstring event_name =
         command_line->GetSwitchValueNative(chrome_cleaner::kTestEventToSignal);
     base::win::ScopedHandle handle(
         ::OpenEvent(EVENT_ALL_ACCESS, TRUE, event_name.c_str()));
diff --git a/chrome/chrome_cleaner/test/test_registry_util.h b/chrome/chrome_cleaner/test/test_registry_util.h
index b83a52e..97903f22 100644
--- a/chrome/chrome_cleaner/test/test_registry_util.h
+++ b/chrome/chrome_cleaner/test/test_registry_util.h
@@ -7,10 +7,10 @@
 
 #include <windows.h>
 
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/win/registry.h"
 #include "chrome/chrome_cleaner/os/registry.h"
 #include "chrome/chrome_cleaner/proto/shared_pup_enums.pb.h"
diff --git a/chrome/chrome_cleaner/test/test_scoped_service_handle.cc b/chrome/chrome_cleaner/test/test_scoped_service_handle.cc
index f5d96b5..c714cb60 100644
--- a/chrome/chrome_cleaner/test/test_scoped_service_handle.cc
+++ b/chrome/chrome_cleaner/test/test_scoped_service_handle.cc
@@ -6,6 +6,7 @@
 
 #include <windows.h>
 
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -14,7 +15,6 @@
 #include "base/path_service.h"
 #include "base/process/process_iterator.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/unguessable_token.h"
 #include "chrome/chrome_cleaner/os/scoped_service_handle.h"
@@ -61,7 +61,7 @@
   DCHECK(service_name_.empty());
 
   // Find an unused name for this service.
-  base::string16 service_name = RandomUnusedServiceNameForTesting();
+  std::wstring service_name = RandomUnusedServiceNameForTesting();
 
   // Get a handle to the service manager.
   service_manager_.Set(
@@ -71,7 +71,7 @@
            << "Cannot open service manager:" << LastErrorString();
   }
 
-  const base::string16 service_desc =
+  const std::wstring service_desc =
       base::StrCat({service_name, L" - Chrome Cleanup Tool (test)"});
 
   service_.Set(::CreateServiceW(
@@ -110,7 +110,7 @@
 
 AssertionResult TestScopedServiceHandle::StopAndDelete() {
   Close();
-  base::string16 service_name;
+  std::wstring service_name;
   std::swap(service_name, service_name_);
   if (service_name.empty()) {
     return AssertionFailure() << "Attempt to stop service with no name";
@@ -134,8 +134,8 @@
   service_manager_.Close();
 }
 
-base::string16 RandomUnusedServiceNameForTesting() {
-  base::string16 service_name;
+std::wstring RandomUnusedServiceNameForTesting() {
+  std::wstring service_name;
   do {
     service_name =
         base::UTF8ToWide(base::UnguessableToken::Create().ToString());
@@ -167,9 +167,9 @@
                          SERVICE_STATE_ALL, &services)) {
     return AssertionFailure() << "Failed to enumerate services";
   }
-  std::vector<base::string16> stopped_service_names;
+  std::vector<std::wstring> stopped_service_names;
   for (const ServiceStatus& service : services) {
-    base::string16 service_name = service.service_name;
+    std::wstring service_name = service.service_name;
     base::ProcessId pid = service.service_status_process.dwProcessId;
     if (base::Contains(process_ids, pid)) {
       if (!StopService(service_name.c_str()))
@@ -186,11 +186,11 @@
   }
   // Issue an async DeleteService request for each service in parallel, then
   // wait for all of them to finish deleting.
-  for (const base::string16& service_name : stopped_service_names) {
+  for (const std::wstring& service_name : stopped_service_names) {
     if (!DeleteService(service_name.c_str()))
       return AssertionFailure() << "Could not delete service " << service_name;
   }
-  for (const base::string16& service_name : stopped_service_names) {
+  for (const std::wstring& service_name : stopped_service_names) {
     if (!WaitForServiceDeleted(service_name.c_str())) {
       return AssertionFailure()
              << "Did not finish deleting service " << service_name;
diff --git a/chrome/chrome_cleaner/test/test_scoped_service_handle.h b/chrome/chrome_cleaner/test/test_scoped_service_handle.h
index a56ff956..0415a25b 100644
--- a/chrome/chrome_cleaner/test/test_scoped_service_handle.h
+++ b/chrome/chrome_cleaner/test/test_scoped_service_handle.h
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/files/file_path.h"
-#include "base/strings/string16.h"
 #include "chrome/chrome_cleaner/os/scoped_service_handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -29,13 +28,13 @@
   const wchar_t* service_name() const { return service_name_.c_str(); }
 
  private:
-  base::string16 service_name_;
+  std::wstring service_name_;
 };
 
 // Returns a random string that is not an existing service name. This is a
 // best-effort check as a service with that name could be created before the
 // function returns.
-base::string16 RandomUnusedServiceNameForTesting();
+std::wstring RandomUnusedServiceNameForTesting();
 
 // Tries to stop any copies of the test service executable that are running.
 // Returns false if an executable remains running.
diff --git a/chrome/chrome_cleaner/test/test_service_main.cc b/chrome/chrome_cleaner/test/test_service_main.cc
index 68f0b429..bd78ff6 100644
--- a/chrome/chrome_cleaner/test/test_service_main.cc
+++ b/chrome/chrome_cleaner/test/test_service_main.cc
@@ -12,7 +12,6 @@
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/path_service.h"
-#include "base/strings/string16.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread_checker.h"
 #include "chrome/chrome_cleaner/test/test_strings.h"
diff --git a/chrome/chrome_cleaner/test/test_settings_util.h b/chrome/chrome_cleaner/test/test_settings_util.h
index d97e3876..c82f43f 100644
--- a/chrome/chrome_cleaner/test/test_settings_util.h
+++ b/chrome/chrome_cleaner/test/test_settings_util.h
@@ -5,9 +5,9 @@
 #ifndef CHROME_CHROME_CLEANER_TEST_TEST_SETTINGS_UTIL_H_
 #define CHROME_CHROME_CLEANER_TEST_TEST_SETTINGS_UTIL_H_
 
+#include <string>
 #include <vector>
 
-#include "base/strings/string16.h"
 #include "chrome/chrome_cleaner/logging/proto/shared_data.pb.h"
 #include "chrome/chrome_cleaner/settings/settings.h"
 #include "components/chrome_cleaner/public/constants/constants.h"
@@ -35,7 +35,7 @@
   ~MockSettings() override;
 
   MOCK_CONST_METHOD0(allow_crash_report_upload, bool());
-  MOCK_CONST_METHOD0(session_id, base::string16());
+  MOCK_CONST_METHOD0(session_id, std::wstring());
   MOCK_CONST_METHOD0(cleanup_id, std::string());
   MOCK_CONST_METHOD0(engine, Engine::Name());
   MOCK_CONST_METHOD0(is_stub_engine, bool());
diff --git a/chrome/chrome_cleaner/test/test_task_scheduler.cc b/chrome/chrome_cleaner/test/test_task_scheduler.cc
index 7c0af81..61b1f8c 100644
--- a/chrome/chrome_cleaner/test/test_task_scheduler.cc
+++ b/chrome/chrome_cleaner/test/test_task_scheduler.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/chrome_cleaner/test/test_task_scheduler.h"
 
+#include <string>
+
 #include "base/check.h"
 #include "base/command_line.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -50,8 +52,7 @@
   return false;
 }
 
-bool TestTaskScheduler::GetTaskNameList(
-    std::vector<base::string16>* task_names) {
+bool TestTaskScheduler::GetTaskNameList(std::vector<std::wstring>* task_names) {
   DCHECK(task_names);
 
   for (const auto& task : tasks_)
diff --git a/chrome/chrome_cleaner/test/test_task_scheduler.h b/chrome/chrome_cleaner/test/test_task_scheduler.h
index 0baa6a4..292b1e8 100644
--- a/chrome/chrome_cleaner/test/test_task_scheduler.h
+++ b/chrome/chrome_cleaner/test/test_task_scheduler.h
@@ -6,6 +6,7 @@
 #define CHROME_CHROME_CLEANER_TEST_TEST_TASK_SCHEDULER_H_
 
 #include <map>
+#include <string>
 #include <vector>
 
 #include "chrome/chrome_cleaner/os/task_scheduler.h"
@@ -24,7 +25,7 @@
   bool DeleteTask(const wchar_t* task_name) override;
   bool GetNextTaskRunTime(const wchar_t* task_name,
                           base::Time* next_run_time) override;
-  bool GetTaskNameList(std::vector<base::string16>* task_names) override;
+  bool GetTaskNameList(std::vector<std::wstring>* task_names) override;
   bool GetTaskInfo(const wchar_t* task_name,
                    TaskScheduler::TaskInfo* info) override;
   bool RegisterTask(const wchar_t* task_name,
@@ -45,7 +46,7 @@
   bool delete_task_called_ = false;
   bool register_task_called_ = false;
   bool register_task_return_value_ = true;
-  std::map<base::string16, TaskInfo> tasks_;
+  std::map<std::wstring, TaskInfo> tasks_;
 };
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/test/test_util.cc b/chrome/chrome_cleaner/test/test_util.cc
index 6b741245..7ccd8b6 100644
--- a/chrome/chrome_cleaner/test/test_util.cc
+++ b/chrome/chrome_cleaner/test/test_util.cc
@@ -11,6 +11,7 @@
 #include <iterator>
 #include <memory>
 #include <set>
+#include <string>
 #include <utility>
 
 #include "base/base_paths.h"
@@ -180,11 +181,11 @@
   scoped_command_line_.GetProcessCommandLine()->AppendSwitch(kPostRebootSwitch);
 }
 
-bool RunOnceCommandLineContains(const base::string16& product_shortname,
+bool RunOnceCommandLineContains(const std::wstring& product_shortname,
                                 const wchar_t* sub_string) {
   DCHECK(sub_string);
   PostRebootRegistration post_reboot(product_shortname);
-  base::string16 run_once_value = post_reboot.RunOnceOnRestartRegisteredValue();
+  std::wstring run_once_value = post_reboot.RunOnceOnRestartRegisteredValue();
   return String16ContainsCaseInsensitive(run_once_value, sub_string);
 }
 
@@ -192,7 +193,7 @@
                                         const wchar_t* sub_string) {
   DCHECK(sub_string);
 
-  base::string16 reg_value;
+  std::wstring reg_value;
   base::win::RegKey run_once_key(
       HKEY_CURRENT_USER,
       PostRebootRegistration::GetPostRebootSwitchKeyPath().c_str(), KEY_READ);
@@ -389,7 +390,7 @@
 }
 
 bool ScopedTempDirNoWow64::CreateEmptyFileInUniqueSystem32TempDir(
-    const base::string16& file_name) {
+    const std::wstring& file_name) {
   if (!CreateUniqueSystem32TempDir())
     return false;
   ScopedDisableWow64Redirection disable_wow64_redirection;
diff --git a/chrome/chrome_cleaner/test/test_util.h b/chrome/chrome_cleaner/test/test_util.h
index fd176ce..b255c4e6 100644
--- a/chrome/chrome_cleaner/test/test_util.h
+++ b/chrome/chrome_cleaner/test/test_util.h
@@ -14,7 +14,6 @@
 
 #include "base/files/scoped_temp_dir.h"
 #include "base/process/process.h"
-#include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
@@ -92,7 +91,7 @@
 
 // Validate that the run once on restart registry value contains the given
 // |sub_string|.
-bool RunOnceCommandLineContains(const base::string16& product_shortname,
+bool RunOnceCommandLineContains(const std::wstring& product_shortname,
                                 const wchar_t* sub_string);
 
 // Validate that the run once on restart switch-containing registry value
@@ -157,7 +156,7 @@
 
   // Convenience function to call CreateUniqueSystem32TempDir and create an
   // empty file with the given |file_name| in the resulting directory.
-  bool CreateEmptyFileInUniqueSystem32TempDir(const base::string16& file_name)
+  bool CreateEmptyFileInUniqueSystem32TempDir(const std::wstring& file_name)
       WARN_UNUSED_RESULT;
 
   using base::ScopedTempDir::Delete;
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 1280419..be7b42c 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -763,9 +763,6 @@
 const char kDisableWindows10CustomTitlebar[] =
     "disable-windows10-custom-titlebar";
 
-// Fallback to XPS. By default connector uses CDD.
-const char kEnableCloudPrintXps[]           = "enable-cloud-print-xps";
-
 // Force-enables the profile shortcut manager. This is needed for tests since
 // they use a custom-user-data-dir which disables this.
 const char kEnableProfileShortcutManager[]  = "enable-profile-shortcut-manager";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 8292813..78b96f7 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -231,7 +231,6 @@
 
 #if defined(OS_WIN)
 extern const char kDisableWindows10CustomTitlebar[];
-extern const char kEnableCloudPrintXps[];
 extern const char kEnableProfileShortcutManager[];
 extern const char kHideIcons[];
 extern const char kNoNetworkProfileWarning[];
diff --git a/chrome/common/cloud_print/cloud_print_constants.cc b/chrome/common/cloud_print/cloud_print_constants.cc
index 6c9f5d3..bb6110d4 100644
--- a/chrome/common/cloud_print/cloud_print_constants.cc
+++ b/chrome/common/cloud_print/cloud_print_constants.cc
@@ -25,8 +25,6 @@
 
 const char kContentTypeJSON[] = "application/json";
 const char kContentTypePDF[] = "application/pdf";
-const char kContentTypeXML[] = "application/xml";
-const char kContentTypeXPS[] = "application/vnd.ms-xpsdocument";
 
 const char kPrintSystemFailedMessageId[] = "printsystemfail";
 const char kGetPrinterCapsFailedMessageId[] = "getprncapsfail";
diff --git a/chrome/common/cloud_print/cloud_print_constants.h b/chrome/common/cloud_print/cloud_print_constants.h
index b9648347..3940ef3 100644
--- a/chrome/common/cloud_print/cloud_print_constants.h
+++ b/chrome/common/cloud_print/cloud_print_constants.h
@@ -31,8 +31,6 @@
 
 extern const char kContentTypeJSON[];
 extern const char kContentTypePDF[];
-extern const char kContentTypeXML[];
-extern const char kContentTypeXPS[];
 
 // Value of "code" parameter in cloud print "/message" requests.
 extern const char kPrintSystemFailedMessageId[];
diff --git a/chrome/common/profiler/stack_sampling_configuration.cc b/chrome/common/profiler/stack_sampling_configuration.cc
index e89846df..0942eb8 100644
--- a/chrome/common/profiler/stack_sampling_configuration.cc
+++ b/chrome/common/profiler/stack_sampling_configuration.cc
@@ -105,7 +105,7 @@
   const base::TimeDelta duration =
       base::TimeDelta::FromSeconds(IsBrowserTestModeEnabled() ? 1 : 30);
   params.sampling_interval = base::TimeDelta::FromMilliseconds(100);
-  params.samples_per_profile = duration.FltDiv(params.sampling_interval);
+  params.samples_per_profile = duration / params.sampling_interval;
 
   return params;
 }
diff --git a/chrome/common/service_process_util.cc b/chrome/common/service_process_util.cc
index b20c9da..d1fc750 100644
--- a/chrome/common/service_process_util.cc
+++ b/chrome/common/service_process_util.cc
@@ -134,9 +134,6 @@
     switches::kCloudPrintSetupProxy,
     switches::kCloudPrintURL,
     switches::kCloudPrintXmppEndpoint,
-#if defined(OS_WIN)
-    switches::kEnableCloudPrintXps,
-#endif
     switches::kEnableLogging,
     switches::kLang,
     switches::kLoggingLevel,
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc
index 2e5460d..197a4e3 100644
--- a/chrome/service/cloud_print/print_system_win.cc
+++ b/chrome/service/cloud_print/print_system_win.cc
@@ -273,58 +273,42 @@
         return false;
       }
 
-      // We only support PDF and XPS documents for now.
-      if (print_data_mime_type == kContentTypePDF) {
-        base::string16 printer_wide = base::UTF8ToWide(printer_name);
-        std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode;
-        if (print_ticket_mime_type == kContentTypeJSON) {
-          dev_mode = CjtToDevMode(printer_wide, print_ticket);
-        } else {
-          DCHECK_EQ(kContentTypeXML, print_ticket_mime_type);
-          dev_mode = printing::XpsTicketToDevMode(printer_wide, print_ticket);
-        }
-
-        if (!dev_mode) {
-          NOTREACHED();
-          return false;
-        }
-
-        HDC dc = CreateDC(L"WINSPOOL", printer_wide.c_str(), nullptr,
-                          dev_mode.get());
-        if (!dc) {
-          NOTREACHED();
-          return false;
-        }
-        DOCINFO di = {0};
-        di.cbSize = sizeof(DOCINFO);
-        base::string16 doc_name = base::UTF8ToUTF16(job_title);
-        DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name);
-        di.lpszDocName = doc_name.c_str();
-        job_id_ = StartDoc(dc, &di);
-        if (job_id_ <= 0)
-          return false;
-
-        printer_dc_.Set(dc);
-        saved_dc_ = SaveDC(printer_dc_.Get());
-        delegate_ = delegate;
-        RenderPDFPages(print_data_file_path,
-                       printing::IsDevModeWithColor(dev_mode.get()));
-        return true;
+      // We only support PDF documents.
+      if (print_data_mime_type != kContentTypePDF ||
+          print_ticket_mime_type != kContentTypeJSON) {
+        NOTREACHED();
+        return false;
       }
 
-      if (print_data_mime_type == kContentTypeXPS) {
-        DCHECK(print_ticket_mime_type == kContentTypeXML);
-        bool ret = PrintXPSDocument(printer_name,
-                                    job_title,
-                                    print_data_file_path,
-                                    print_ticket);
-        if (ret)
-          delegate_ = delegate;
-        return ret;
+      base::string16 printer_wide = base::UTF8ToWide(printer_name);
+      std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode =
+          CjtToDevMode(printer_wide, print_ticket);
+      if (!dev_mode) {
+        NOTREACHED();
+        return false;
       }
 
-      NOTREACHED();
-      return false;
+      HDC dc =
+          CreateDC(L"WINSPOOL", printer_wide.c_str(), nullptr, dev_mode.get());
+      if (!dc) {
+        NOTREACHED();
+        return false;
+      }
+      DOCINFO di = {0};
+      di.cbSize = sizeof(DOCINFO);
+      base::string16 doc_name = base::UTF8ToUTF16(job_title);
+      DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name);
+      di.lpszDocName = doc_name.c_str();
+      job_id_ = StartDoc(dc, &di);
+      if (job_id_ <= 0)
+        return false;
+
+      printer_dc_.Set(dc);
+      saved_dc_ = SaveDC(printer_dc_.Get());
+      delegate_ = delegate;
+      RenderPDFPages(print_data_file_path,
+                     printing::IsDevModeWithColor(dev_mode.get()));
+      return true;
     }
 
     void PreparePageDCForPrinting(HDC, float scale_factor) {
@@ -655,7 +639,7 @@
   std::string GetPrinterDriverInfo(const std::string& printer_name) const;
 
   scoped_refptr<printing::PrintBackend> print_backend_;
-  bool use_cdd_ = true;
+
   DISALLOW_COPY_AND_ASSIGN(PrintSystemWin);
 };
 
@@ -665,21 +649,6 @@
                                                  /*locale=*/std::string())) {}
 
 PrintSystem::PrintSystemResult PrintSystemWin::Init() {
-  use_cdd_ = !base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableCloudPrintXps);
-
-  if (!use_cdd_)
-    use_cdd_ = !printing::XPSModule::Init();
-
-  if (!use_cdd_) {
-    HPTPROVIDER provider = nullptr;
-    HRESULT hr = printing::XPSModule::OpenProvider(L"", 1, &provider);
-    if (provider)
-      printing::XPSModule::CloseProvider(provider);
-    // Use cdd if error is different from expected.
-    use_cdd_ = (hr != HRESULT_FROM_WIN32(ERROR_INVALID_PRINTER_NAME));
-  }
-
   return PrintSystemResult(true, std::string());
 }
 
@@ -698,10 +667,7 @@
   PrinterCapsHandler* handler =
       new PrinterCapsHandler(printer_name, std::move(callback));
   handler->AddRef();
-  if (use_cdd_)
-    handler->StartGetPrinterSemanticCapsAndDefaults();
-  else
-    handler->StartGetPrinterCapsAndDefaults();
+  handler->StartGetPrinterSemanticCapsAndDefaults();
 }
 
 bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) {
@@ -714,42 +680,8 @@
     const std::string& print_ticket_data_mime_type) {
   crash_keys::ScopedPrinterInfo crash_key(GetPrinterDriverInfo(printer_name));
 
-  if (use_cdd_) {
-    return print_ticket_data_mime_type == kContentTypeJSON &&
-           IsValidCjt(print_ticket_data);
-  }
-  DCHECK(print_ticket_data_mime_type == kContentTypeXML);
-
-  printing::ScopedXPSInitializer xps_initializer;
-  CHECK(xps_initializer.initialized());
-
-  HPTPROVIDER provider = nullptr;
-  printing::XPSModule::OpenProvider(base::UTF8ToWide(printer_name), 1,
-                                    &provider);
-  if (!provider)
-    return false;
-
-  bool ret;
-  {
-    Microsoft::WRL::ComPtr<IStream> print_ticket_stream;
-    CreateStreamOnHGlobal(nullptr, TRUE, &print_ticket_stream);
-    ULONG bytes_written = 0;
-    print_ticket_stream->Write(print_ticket_data.c_str(),
-                               print_ticket_data.length(),
-                               &bytes_written);
-    DCHECK(bytes_written == print_ticket_data.length());
-    LARGE_INTEGER pos = {};
-    ULARGE_INTEGER new_pos = {};
-    print_ticket_stream->Seek(pos, STREAM_SEEK_SET, &new_pos);
-    base::win::ScopedBstr error;
-    Microsoft::WRL::ComPtr<IStream> result_ticket_stream;
-    CreateStreamOnHGlobal(nullptr, TRUE, &result_ticket_stream);
-    ret = SUCCEEDED(printing::XPSModule::MergeAndValidatePrintTicket(
-        provider, print_ticket_stream.Get(), nullptr, kPTJobScope,
-        result_ticket_stream.Get(), error.Receive()));
-    printing::XPSModule::CloseProvider(provider);
-  }
-  return ret;
+  return print_ticket_data_mime_type == kContentTypeJSON &&
+         IsValidCjt(print_ticket_data);
 }
 
 bool PrintSystemWin::GetJobDetails(const std::string& printer_name,
@@ -813,17 +745,11 @@
 }
 
 bool PrintSystemWin::UseCddAndCjt() {
-  return use_cdd_;
+  return true;
 }
 
 std::string PrintSystemWin::GetSupportedMimeTypes() {
-  std::string result;
-  if (!use_cdd_) {
-    result = kContentTypeXPS;
-    result += ",";
-  }
-  result += kContentTypePDF;
-  return result;
+  return kContentTypePDF;
 }
 
 std::string PrintSystemWin::GetPrinterDriverInfo(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 80a6825b..d2867693 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2325,6 +2325,7 @@
         "../browser/chromeos/login/screens/mock_eula_screen.h",
         "../browser/chromeos/login/screens/mock_wrong_hwid_screen.cc",
         "../browser/chromeos/login/screens/mock_wrong_hwid_screen.h",
+        "../browser/chromeos/login/screens/multidevice_setup_screen_browsertest.cc",
         "../browser/chromeos/login/screens/network_screen_browsertest.cc",
         "../browser/chromeos/login/screens/packaged_license_screen_browsertest.cc",
         "../browser/chromeos/login/screens/recommend_apps/scoped_test_recommend_apps_fetcher_factory.cc",
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index cff2334..1218311 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -55,11 +55,9 @@
   SetConstrainedWindowViewsClient(CreateChromeConstrainedWindowViewsClient());
 #endif
 
-  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
   profile_manager_ = std::make_unique<TestingProfileManager>(
       TestingBrowserProcess::GetGlobal());
-  ASSERT_TRUE(profile_manager_->SetUp(temp_dir_.GetPath()));
+  ASSERT_TRUE(profile_manager_->SetUp());
 
   // Subclasses can provide their own Profile.
   profile_ = CreateProfile();
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 0e6f551..63ae6b4 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/compiler_specific.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
@@ -203,12 +202,6 @@
       Browser::Type browser_type,
       bool hosted_app);
 
-  // Temporary directory to store profile data. This must outlive
-  // |task_environment_| to avoid leaking data across tests (see
-  // https://crbug.com/546640) and to avoid fatal failures if the directory is
-  // deleted too early, while backend tasks are still running.
-  base::ScopedTempDir temp_dir_;
-
   // We need to create a MessageLoop, otherwise a bunch of things fails.
   std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
 
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 17d61d2d..3b88ef2 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -19,6 +19,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/test_file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -235,8 +236,7 @@
       override_policy_connector_is_managed_(base::nullopt),
       otr_profile_id_(base::nullopt) {
   if (profile_path_.empty()) {
-    CreateTempProfileDir();
-    profile_path_ = temp_dir_.GetPath();
+    profile_path_ = base::CreateUniqueTempDirectoryScopedToTest();
   }
   Init();
   if (delegate_) {
@@ -298,8 +298,7 @@
 
   // If no profile path was supplied, create one.
   if (profile_path_.empty()) {
-    CreateTempProfileDir();
-    profile_path_ = temp_dir_.GetPath();
+    profile_path_ = base::CreateUniqueTempDirectoryScopedToTest();
   }
 
   // Set any testing factories prior to initializing the services.
@@ -323,34 +322,6 @@
   SetSupervisedUserId(supervised_user_id);
 }
 
-void TestingProfile::CreateTempProfileDir() {
-  base::ScopedAllowBlockingForTesting allow_blocking;
-  if (!temp_dir_.CreateUniqueTempDir()) {
-    LOG(ERROR) << "Failed to create unique temporary directory.";
-
-    // Fallback logic in case we fail to create unique temporary directory.
-    base::FilePath system_tmp_dir;
-    bool success = base::PathService::Get(base::DIR_TEMP, &system_tmp_dir);
-
-    // We're severly screwed if we can't get the system temporary
-    // directory. Die now to avoid writing to the filesystem root
-    // or other bad places.
-    CHECK(success);
-
-    base::FilePath fallback_dir(
-        system_tmp_dir.AppendASCII("TestingProfilePath"));
-    base::DeletePathRecursively(fallback_dir);
-    base::CreateDirectory(fallback_dir);
-    if (!temp_dir_.Set(fallback_dir)) {
-      // That shouldn't happen, but if it does, try to recover.
-      LOG(ERROR) << "Failed to use a fallback temporary directory.";
-
-      // We're screwed if this fails, see CHECK above.
-      CHECK(temp_dir_.Set(system_tmp_dir));
-    }
-  }
-}
-
 void TestingProfile::Init() {
   base::ScopedAllowBlockingForTesting allow_blocking;
   // If threads have been initialized, we should be on the UI thread.
@@ -565,9 +536,6 @@
     resource_context_ = nullptr;
     content::RunAllPendingInMessageLoop(BrowserThread::IO);
   }
-
-  base::ScopedAllowBlockingForTesting allow_blocking;
-  ignore_result(temp_dir_.Delete());
 }
 
 bool TestingProfile::CreateHistoryService(bool delete_file, bool no_db) {
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 135017b..9c4bb0e 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -10,7 +10,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
@@ -392,13 +391,6 @@
   }
 
  private:
-  // We use a temporary directory to store testing profile data. This
-  // must be declared before anything that may make use of the
-  // directory so as to ensure files are closed before cleanup.  In a
-  // multi-profile environment, this is invalid and the directory is
-  // managed by the TestingProfileManager.
-  base::ScopedTempDir temp_dir_;
-
   // Called when profile is deleted.
   ProfileDestructionCallback profile_destruction_callback_;
 
@@ -414,9 +406,6 @@
   sync_preferences::TestingPrefServiceSyncable* testing_prefs_;
 
  private:
-  // Creates a temporary directory for use by this profile.
-  void CreateTempProfileDir();
-
   // Common initialization between the two constructors.
   void Init();
 
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index 9e75baac..851f317 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/test_file_util.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
@@ -273,8 +274,7 @@
 
   // Set up the directory for profiles.
   if (profiles_path.empty()) {
-    ASSERT_TRUE(profiles_dir_.CreateUniqueTempDir());
-    profiles_path_ = profiles_dir_.GetPath();
+    profiles_path_ = base::CreateUniqueTempDirectoryScopedToTest();
   } else {
     profiles_path_ = profiles_path;
   }
diff --git a/chrome/test/base/testing_profile_manager.h b/chrome/test/base/testing_profile_manager.h
index 1a783391c..5598f830 100644
--- a/chrome/test/base/testing_profile_manager.h
+++ b/chrome/test/base/testing_profile_manager.h
@@ -11,7 +11,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "base/test/scoped_path_override.h"
@@ -137,13 +136,8 @@
   bool called_set_up_;
 
   // |profiles_path_| is the path under which new directories for the profiles
-  // will be placed. Depending on the way SetUp is invoked, this path might
-  // either be a directory owned by TestingProfileManager, in which case
-  // ownership will be managed by |profiles_dir_|, or the directory will be
-  // owned by the test which has instantiated |this|, and then |profiles_dir_|
-  // will remain empty.
+  // will be placed.
   base::FilePath profiles_path_;
-  base::ScopedTempDir profiles_dir_;
 
   // The user data directory in the path service is overriden because some
   // functions, e.g. GetPathOfHighResAvatarAtIndex, get the user data directory
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
index eb283ff..dd493f605 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
@@ -37,10 +37,22 @@
   return Status(kOk);
 }
 
-bool MobileEmulationOverrideManager::IsEmulatingTouch() {
+bool MobileEmulationOverrideManager::IsEmulatingTouch() const {
   return overridden_device_metrics_ && overridden_device_metrics_->touch;
 }
 
+bool MobileEmulationOverrideManager::HasOverrideMetrics() const {
+  return overridden_device_metrics_;
+}
+
+Status MobileEmulationOverrideManager::RestoreOverrideMetrics() {
+  return ApplyOverrideIfNeeded();
+}
+
+const DeviceMetrics* MobileEmulationOverrideManager::GetDeviceMetrics() const {
+  return overridden_device_metrics_;
+}
+
 Status MobileEmulationOverrideManager::ApplyOverrideIfNeeded() {
   if (!overridden_device_metrics_)
     return Status(kOk);
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h
index 90c85efd..8f683e51 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h
@@ -34,7 +34,10 @@
                  const std::string& method,
                  const base::DictionaryValue& params) override;
 
-  bool IsEmulatingTouch();
+  bool IsEmulatingTouch() const;
+  bool HasOverrideMetrics() const;
+  Status RestoreOverrideMetrics();
+  const DeviceMetrics* GetDeviceMetrics() const;
 
  private:
   Status ApplyOverrideIfNeeded();
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.cc b/chrome/test/chromedriver/chrome/stub_web_view.cc
index b58d230..1248898 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.cc
+++ b/chrome/test/chromedriver/chrome/stub_web_view.cc
@@ -184,7 +184,12 @@
 }
 
 JavaScriptDialogManager* StubWebView::GetJavaScriptDialogManager() {
-  return NULL;
+  return nullptr;
+}
+
+MobileEmulationOverrideManager* StubWebView::GetMobileEmulationOverrideManager()
+    const {
+  return nullptr;
 }
 
 Status StubWebView::OverrideGeolocation(const Geoposition& geoposition) {
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.h b/chrome/test/chromedriver/chrome/stub_web_view.h
index 8275a5c..7ce8ce8 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.h
+++ b/chrome/test/chromedriver/chrome/stub_web_view.h
@@ -96,6 +96,8 @@
   Status IsPendingNavigation(const Timeout* timeout,
                              bool* is_pending) const override;
   JavaScriptDialogManager* GetJavaScriptDialogManager() override;
+  MobileEmulationOverrideManager* GetMobileEmulationOverrideManager()
+      const override;
   Status OverrideGeolocation(const Geoposition& geoposition) override;
   Status OverrideNetworkConditions(
       const NetworkConditions& network_conditions) override;
diff --git a/chrome/test/chromedriver/chrome/web_view.h b/chrome/test/chromedriver/chrome/web_view.h
index 8cb9f01..9e89b0d 100644
--- a/chrome/test/chromedriver/chrome/web_view.h
+++ b/chrome/test/chromedriver/chrome/web_view.h
@@ -22,6 +22,7 @@
 struct Geoposition;
 class JavaScriptDialogManager;
 struct KeyEvent;
+class MobileEmulationOverrideManager;
 struct MouseEvent;
 struct NetworkConditions;
 class Status;
@@ -204,6 +205,10 @@
   // Returns the JavaScriptDialogManager. Never null.
   virtual JavaScriptDialogManager* GetJavaScriptDialogManager() = 0;
 
+  // Returns the MobileEmulationOverrideManager.
+  virtual MobileEmulationOverrideManager* GetMobileEmulationOverrideManager()
+      const = 0;
+
   // Overrides normal geolocation with a given geoposition.
   virtual Status OverrideGeolocation(const Geoposition& geoposition) = 0;
 
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index b607bbf..d1fa932 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -859,6 +859,11 @@
   return dialog_manager_.get();
 }
 
+MobileEmulationOverrideManager* WebViewImpl::GetMobileEmulationOverrideManager()
+    const {
+  return mobile_emulation_override_manager_.get();
+}
+
 Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) {
   return geolocation_override_manager_->OverrideGeolocation(geoposition);
 }
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h
index 2adffde3..0654382 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.h
+++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -138,6 +138,8 @@
   Status IsPendingNavigation(const Timeout* timeout,
                              bool* is_pending) const override;
   JavaScriptDialogManager* GetJavaScriptDialogManager() override;
+  MobileEmulationOverrideManager* GetMobileEmulationOverrideManager()
+      const override;
   Status OverrideGeolocation(const Geoposition& geoposition) override;
   Status OverrideNetworkConditions(
       const NetworkConditions& network_conditions) override;
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py
index 393635a..77b4da3 100644
--- a/chrome/test/chromedriver/client/chromedriver.py
+++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -593,6 +593,9 @@
   def TakeScreenshot(self):
     return self.ExecuteCommand(Command.SCREENSHOT)
 
+  def TakeFullPageScreenshot(self):
+    return self.ExecuteCommand(Command.FULL_PAGE_SCREENSHOT)
+
   def PrintPDF(self, params={}):
     return self.ExecuteCommand(Command.PRINT, params)
 
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py
index b727155..1ae64b2c 100644
--- a/chrome/test/chromedriver/client/command_executor.py
+++ b/chrome/test/chromedriver/client/command_executor.py
@@ -45,6 +45,7 @@
   SCREENSHOT = (_Method.GET, '/session/:sessionId/screenshot')
   ELEMENT_SCREENSHOT = (
       _Method.GET, '/session/:sessionId/element/:id/screenshot')
+  FULL_PAGE_SCREENSHOT = (_Method.GET, '/session/:sessionId/screenshot/full')
   PRINT = (_Method.POST, '/session/:sessionId/print')
   SET_BROWSER_VISIBLE = (_Method.POST, '/session/:sessionId/visible')
   IS_BROWSER_VISIBLE = (_Method.GET, '/session/:sessionId/visible')
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc
index e97cf9a..ba1c1e1 100644
--- a/chrome/test/chromedriver/server/http_handler.cc
+++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -382,6 +382,11 @@
                         base::BindRepeating(&ExecuteElementScreenshot))),
 
       CommandMapping(
+          kGet, "session/:sessionId/screenshot/full",
+          WrapToCommand("FullPageScreenshot",
+                        base::BindRepeating(&ExecuteFullPageScreenshot))),
+
+      CommandMapping(
           kPost, "session/:sessionId/print",
           WrapToCommand("Print", base::BindRepeating(&ExecutePrint))),
 
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 0c7c9f2..c516963 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -28,6 +28,8 @@
 import urllib
 import urllib2
 import uuid
+import imghdr
+import struct
 
 
 _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
@@ -222,6 +224,10 @@
         'ChromeDriverTest.testSettingPermissionDoesNotAffectOthers',
         # Android does not allow changing window size
         'JavaScriptTests.*',
+        # These tests are failing on Android
+        # https://bugs.chromium.org/p/chromedriver/issues/detail?id=3560
+        'ChromeDriverTest.testTakeLargeElementViewportScreenshot',
+        'ChromeDriverTest.testTakeLargeElementFullPageScreenshot'
     ]
 )
 _ANDROID_NEGATIVE_FILTER['chrome_stable'] = (
@@ -2285,6 +2291,88 @@
     analysisResult = self.takeScreenshotAndVerifyCorrect(redElement)
     self.assertEquals('PASS', analysisResult)
 
+  @staticmethod
+  def png_dimensions(png_data_in_base64):
+    image = base64.b64decode(png_data_in_base64)
+    width, height = struct.unpack('>LL', image[16:24])
+    return int(width), int(height)
+
+
+  def testTakeLargeElementViewportScreenshot(self):
+    self._driver.Load(self.GetHttpUrlForFile(
+        '/chromedriver/large_element.html'))
+    self._driver.SetWindowRect(640, 400, 0, 0)
+    # Wait for page to stabilize. See https://crbug.com/chromedriver/2986
+    time.sleep(1)
+    viewportScreenshotPNGBase64  = self._driver.TakeScreenshot()
+    self.assertIsNotNone(viewportScreenshotPNGBase64)
+    mime_type = imghdr.what('', base64.b64decode(viewportScreenshotPNGBase64))
+    self.assertEqual('png', mime_type)
+    image_width, image_height = self.png_dimensions(viewportScreenshotPNGBase64)
+    viewport_width, viewport_height = self._driver.ExecuteScript(
+        '''
+        const {devicePixelRatio, innerHeight, innerWidth} = window;
+
+        return [
+          Math.floor(innerWidth * devicePixelRatio),
+          Math.floor(innerHeight * devicePixelRatio)
+        ];
+        ''')
+    self.assertEquals(image_width, viewport_width)
+    self.assertEquals(image_height, viewport_height)
+
+  def testTakeLargeElementFullPageScreenshot(self):
+    self._driver.Load(self.GetHttpUrlForFile(
+        '/chromedriver/large_element.html'))
+    width = 640
+    height = 400
+    self._driver.SetWindowRect(width, height, 0, 0)
+    # Wait for page to stabilize. See https://crbug.com/chromedriver/2986
+    time.sleep(1)
+    fullpageScreenshotPNGBase64  = self._driver.TakeFullPageScreenshot()
+    self.assertIsNotNone(fullpageScreenshotPNGBase64)
+    mime_type = imghdr.what('', base64.b64decode(fullpageScreenshotPNGBase64))
+    self.assertEqual('png', mime_type)
+    image_width, image_height = self.png_dimensions(fullpageScreenshotPNGBase64)
+    # According to https://javascript.info/size-and-scroll-window,
+    # width/height of the whole document, with the scrolled out part
+    page_width, page_height = self._driver.ExecuteScript(
+        '''
+        const body = document.body;
+        const doc = document.documentElement;
+        const width = Math.max(body.scrollWidth, body.offsetWidth,\
+                               body.clientWidth, doc.scrollWidth,\
+                               doc.offsetWidth, doc.clientWidth);
+        const height = Math.max(body.scrollHeight, body.offsetHeight,\
+                                body.clientHeight, doc.scrollHeight,\
+                                doc.offsetHeight, doc.clientHeight);
+
+        return [
+          width,
+          height
+        ];
+        ''')
+    self.assertEquals(image_width, page_width)
+    self.assertEquals(image_height, page_height)
+
+    # Assert Window Rect size stay the same after taking fullpage screenshot
+    size = self._driver.GetWindowRect()
+    self.assertEquals(size[0], width)
+    self.assertEquals(size[1], height)
+
+    # Verify scroll bars presence after test
+    horizontal_scroll_bar, vertical_scroll_bar = self._driver.ExecuteScript(
+        '''
+        const doc = document.documentElement;
+
+        return [
+          doc.scrollWidth > doc.clientWidth,
+          doc.scrollHeight > doc.clientHeight
+        ];
+        ''')
+    self.assertEquals(horizontal_scroll_bar, True)
+    self.assertEquals(vertical_scroll_bar, True)
+
   def testPrint(self):
     self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
     pdf = self._driver.PrintPDF({
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 4bb56cb..ac5deef 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -28,6 +28,7 @@
 #include "chrome/test/chromedriver/chrome/geoposition.h"
 #include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h"
 #include "chrome/test/chromedriver/chrome/js.h"
+#include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h"
 #include "chrome/test/chromedriver/chrome/network_conditions.h"
 #include "chrome/test/chromedriver/chrome/status.h"
 #include "chrome/test/chromedriver/chrome/ui_events.h"
@@ -1964,6 +1965,90 @@
   return Status(kOk);
 }
 
+Status ExecuteFullPageScreenshot(Session* session,
+                                 WebView* web_view,
+                                 const base::DictionaryValue& params,
+                                 std::unique_ptr<base::Value>* value,
+                                 Timeout* timeout) {
+  Status status = session->chrome->ActivateWebView(web_view->GetId());
+  if (status.IsError())
+    return status;
+
+  std::unique_ptr<base::Value> layoutMetrics;
+  status = web_view->SendCommandAndGetResult(
+      "Page.getLayoutMetrics", base::DictionaryValue(), &layoutMetrics);
+  if (status.IsError())
+    return status;
+
+  const auto width = layoutMetrics->FindDoublePath("contentSize.width");
+  if (!width.has_value())
+    return Status(kUnknownError, "invalid width type");
+  int w = ceil(width.value());
+  if (w == 0)
+    return Status(kUnknownError, "invalid width 0");
+
+  const auto height = layoutMetrics->FindDoublePath("contentSize.height");
+  if (!height.has_value())
+    return Status(kUnknownError, "invalid height type");
+  int h = ceil(height.value());
+  if (h == 0)
+    return Status(kUnknownError, "invalid height 0");
+
+  auto* meom = web_view->GetMobileEmulationOverrideManager();
+  bool hasOverrideMetrics = meom->HasOverrideMetrics();
+
+  base::DictionaryValue deviceMetrics;
+  deviceMetrics.SetInteger("width", w);
+  deviceMetrics.SetInteger("height", h);
+  if (hasOverrideMetrics) {
+    const auto* dm = meom->GetDeviceMetrics();
+    deviceMetrics.SetInteger("deviceScaleFactor", dm->device_scale_factor);
+    deviceMetrics.SetBoolean("mobile", dm->mobile);
+  } else {
+    deviceMetrics.SetInteger("deviceScaleFactor", 1);
+    deviceMetrics.SetBoolean("mobile", false);
+  }
+  std::unique_ptr<base::Value> ignore;
+  status = web_view->SendCommandAndGetResult(
+      "Emulation.setDeviceMetricsOverride", deviceMetrics, &ignore);
+  if (status.IsError())
+    return status;
+
+  std::string screenshot;
+  // No need to supply clip as it would be default to the device metrics
+  // parameters
+  status = web_view->CaptureScreenshot(&screenshot, base::DictionaryValue());
+  if (status.IsError()) {
+    if (status.code() == kUnexpectedAlertOpen) {
+      LOG(WARNING) << status.message() << ", cancelling screenshot";
+      // we can't take screenshot in this state
+      // but we must return kUnexpectedAlertOpen_Keep instead
+      // see https://crbug.com/chromedriver/2117
+      return Status(kUnexpectedAlertOpen_Keep);
+    }
+    LOG(WARNING) << "screenshot failed, retrying " << status.message();
+    status = web_view->CaptureScreenshot(&screenshot, base::DictionaryValue());
+  }
+  if (status.IsError())
+    return status;
+
+  *value = std::make_unique<base::Value>(screenshot);
+
+  // Check if there is already deviceMetricsOverride in use,
+  // if so, restore to that instead
+  if (hasOverrideMetrics) {
+    status = meom->RestoreOverrideMetrics();
+  } else {
+    // The scroll bar disappear after setting device metrics to fullpage
+    // width and height, this is to clear device metrics and restore
+    // scroll bars
+    status = web_view->SendCommandAndGetResult(
+        "Emulation.clearDeviceMetricsOverride", base::DictionaryValue(),
+        &ignore);
+  }
+  return status;
+}
+
 Status ExecutePrint(Session* session,
                     WebView* web_view,
                     const base::DictionaryValue& params,
diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h
index f1b8d1a..8299ab75 100644
--- a/chrome/test/chromedriver/window_commands.h
+++ b/chrome/test/chromedriver/window_commands.h
@@ -291,6 +291,12 @@
                          std::unique_ptr<base::Value>* value,
                          Timeout* timeout);
 
+Status ExecuteFullPageScreenshot(Session* session,
+                                 WebView* web_view,
+                                 const base::DictionaryValue& params,
+                                 std::unique_ptr<base::Value>* value,
+                                 Timeout* timeout);
+
 Status ExecutePrint(Session* session,
                     WebView* web_view,
                     const base::DictionaryValue& params,
diff --git a/chrome/test/chromedriver/window_commands_unittest.cc b/chrome/test/chromedriver/window_commands_unittest.cc
index 2d65601..cfb79af 100644
--- a/chrome/test/chromedriver/window_commands_unittest.cc
+++ b/chrome/test/chromedriver/window_commands_unittest.cc
@@ -6,8 +6,10 @@
 #include <string>
 
 #include "base/values.h"
+#include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h"
 #include "chrome/test/chromedriver/chrome/status.h"
 #include "chrome/test/chromedriver/chrome/stub_chrome.h"
+#include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
 #include "chrome/test/chromedriver/chrome/stub_web_view.h"
 #include "chrome/test/chromedriver/commands.h"
 #include "chrome/test/chromedriver/net/timeout.h"
@@ -801,3 +803,110 @@
   status = CallWindowCommand(ExecutePrint, &webview, params, &result_value);
   ASSERT_EQ(kInvalidArgument, status.code()) << status.message();
 }
+
+namespace {
+constexpr double wd = 345.6;
+constexpr double hd = 5432.1;
+constexpr int wi = 346;
+constexpr int hi = 5433;
+constexpr bool mobile = false;
+constexpr double device_scale_factor = 0.3;
+
+class StoreScreenshotParamsWebView : public StubWebView {
+ public:
+  explicit StoreScreenshotParamsWebView(DevToolsClient* dtc = nullptr,
+                                        DeviceMetrics* dm = nullptr)
+      : StubWebView("1"), meom_(new MobileEmulationOverrideManager(dtc, dm)) {}
+  ~StoreScreenshotParamsWebView() override = default;
+
+  Status SendCommandAndGetResult(const std::string& cmd,
+                                 const base::DictionaryValue& params,
+                                 std::unique_ptr<base::Value>* value) override {
+    if (cmd == "Page.getLayoutMetrics") {
+      std::unique_ptr<base::DictionaryValue> res =
+          std::make_unique<base::DictionaryValue>();
+      std::unique_ptr<base::DictionaryValue> d =
+          std::make_unique<base::DictionaryValue>();
+      d->SetDouble("width", wd);
+      d->SetDouble("height", hd);
+      res->SetDictionary("contentSize", std::move(d));
+      *value = std::move(res);
+    } else if (cmd == "Emulation.setDeviceMetricsOverride") {
+      base::DictionaryValue expect;
+      expect.SetInteger("width", wi);
+      expect.SetInteger("height", hi);
+      if (meom_->HasOverrideMetrics()) {
+        expect.SetInteger("deviceScaleFactor", device_scale_factor);
+        expect.SetBoolean("mobile", mobile);
+      } else {
+        expect.SetInteger("deviceScaleFactor", 1);
+        expect.SetBoolean("mobile", false);
+      }
+      if (expect != params)
+        return Status(kInvalidArgument);
+    }
+
+    return Status(kOk);
+  }
+
+  Status CaptureScreenshot(std::string* screenshot,
+                           const base::DictionaryValue& params) override {
+    params_ = params.Clone();
+    return Status(kOk);
+  }
+
+  const base::Value& getParams() const { return params_; }
+
+  MobileEmulationOverrideManager* GetMobileEmulationOverrideManager()
+      const override {
+    return meom_.get();
+  }
+
+ private:
+  base::Value params_;
+  std::unique_ptr<MobileEmulationOverrideManager> meom_;
+};
+
+base::DictionaryValue getExpectedCaptureParams() {
+  base::DictionaryValue clip;
+  return clip;
+}
+}  // namespace
+
+TEST(WindowCommandsTest, ExecuteScreenCapture) {
+  StoreScreenshotParamsWebView webview;
+  base::DictionaryValue params;
+  std::unique_ptr<base::Value> result_value;
+  Status status =
+      CallWindowCommand(ExecuteScreenshot, &webview, params, &result_value);
+  ASSERT_EQ(kOk, status.code()) << status.message();
+  base::DictionaryValue screenshotParams = base::DictionaryValue();
+  ASSERT_EQ(static_cast<const base::Value&>(screenshotParams),
+            webview.getParams());
+}
+
+TEST(WindowCommandsTest, ExecuteFullPageScreenCapture) {
+  StoreScreenshotParamsWebView webview;
+  base::DictionaryValue params;
+  std::unique_ptr<base::Value> result_value;
+  Status status = CallWindowCommand(ExecuteFullPageScreenshot, &webview, params,
+                                    &result_value);
+  ASSERT_EQ(kOk, status.code()) << status.message();
+  ASSERT_EQ(static_cast<const base::Value&>(getExpectedCaptureParams()),
+            webview.getParams());
+}
+
+TEST(WindowCommandsTest, ExecuteMobileFullPageScreenCapture) {
+  StubDevToolsClient sdtc;
+  DeviceMetrics dm(0, 0, device_scale_factor, false, mobile);
+  StoreScreenshotParamsWebView webview(&sdtc, &dm);
+  ASSERT_EQ(webview.GetMobileEmulationOverrideManager()->HasOverrideMetrics(),
+            true);
+  base::DictionaryValue params;
+  std::unique_ptr<base::Value> result_value;
+  Status status = CallWindowCommand(ExecuteFullPageScreenshot, &webview, params,
+                                    &result_value);
+  ASSERT_EQ(kOk, status.code()) << status.message();
+  ASSERT_EQ(static_cast<const base::Value&>(getExpectedCaptureParams()),
+            webview.getParams());
+}
diff --git a/chrome/test/data/pdf/BUILD.gn b/chrome/test/data/pdf/BUILD.gn
index e2d573e..edf137e 100644
--- a/chrome/test/data/pdf/BUILD.gn
+++ b/chrome/test/data/pdf/BUILD.gn
@@ -23,7 +23,7 @@
     ":material_elements_test",
 
     #":metrics_test",
-    #":navigator_test",
+    ":navigator_test",
     ":nobeep_test",
     ":page_change_test",
     ":params_parser_test",
@@ -125,6 +125,16 @@
   externs_list = [ "$externs_path/test.js" ]
 }
 
+js_library("navigator_test") {
+  deps = [
+    ":test_util",
+    "//chrome/browser/resources/pdf:navigator",
+    "//chrome/browser/resources/pdf:open_pdf_params_parser",
+    "//chrome/browser/resources/pdf:pdf_scripting_api",
+  ]
+  externs_list = [ "$externs_path/test.js" ]
+}
+
 js_library("nobeep_test") {
   deps = [
     "//chrome/browser/resources/pdf:pdf_scripting_api",
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js
index cf4b04b..2d6fdb0 100644
--- a/chrome/test/data/pdf/navigator_test.js
+++ b/chrome/test/data/pdf/navigator_test.js
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {PdfNavigator} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/navigator.js';
+import {NavigatorDelegate, PdfNavigator} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/navigator.js';
 import {OpenPdfParamsParser} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/open_pdf_params_parser.js';
 import {PDFScriptingAPI} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_scripting_api.js';
 
 import {getZoomableViewport, MockDocumentDimensions, MockElement, MockSizer, MockViewportChangedCallback} from './test_util.js';
 
+/** @implements {NavigatorDelegate} */
 class MockNavigatorDelegate {
   constructor() {
     this.navigateInCurrentTabCalled = false;
@@ -16,18 +17,19 @@
     this.url = undefined;
   }
 
-  /** @param {?string} url */
+  /** @override */
   navigateInCurrentTab(url) {
     this.navigateInCurrentTabCalled = true;
     this.url = url || '<called, but no url set>';
   }
 
-  /** @param {?string} url */
+  /** @override */
   navigateInNewTab(url) {
     this.navigateInNewTabCalled = true;
     this.url = url || '<called, but no url set>';
   }
 
+  /** @override */
   navigateInNewWindow(url) {
     this.navigateInNewWindowCalled = true;
     this.url = url || '<called, but no url set>';
@@ -46,6 +48,12 @@
  * a new window depending on the value of |disposition|. Use
  * |viewportChangedCallback| and |navigatorDelegate| to check the callbacks,
  * and that the navigation to |expectedResultUrl| happened.
+ * @param {!PdfNavigator} navigator
+ * @param {string} url
+ * @param {!PdfNavigator.WindowOpenDisposition} disposition
+ * @param {(string|undefined)} expectedResultUrl
+ * @param {!MockViewportChangedCallback} viewportChangedCallback
+ * @param {!MockNavigatorDelegate} navigatorDelegate
  */
 function doNavigationUrlTest(
     navigator, url, disposition, expectedResultUrl, viewportChangedCallback,
@@ -76,9 +84,12 @@
 /**
  * Helper function to run doNavigationUrlTest() for the current tab, a new
  * tab, and a new window.
+ * @param {string} originalUrl
+ * @param {string} url
+ * @param {(string|undefined)} expectedResultUrl
  */
 function doNavigationUrlTests(originalUrl, url, expectedResultUrl) {
-  const mockWindow = new MockElement(100, 100);
+  const mockWindow = new MockElement(100, 100, null);
   const mockSizer = new MockSizer();
   const mockViewportChangedCallback = new MockViewportChangedCallback();
   const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
@@ -109,7 +120,7 @@
    * opening a url in a new tab.
    */
   function testNavigate() {
-    const mockWindow = new MockElement(100, 100);
+    const mockWindow = new MockElement(100, 100, null);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
     const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
diff --git a/chrome/test/data/pdf/test_util.js b/chrome/test/data/pdf/test_util.js
index 17be93842..4b428fb 100644
--- a/chrome/test/data/pdf/test_util.js
+++ b/chrome/test/data/pdf/test_util.js
@@ -4,7 +4,7 @@
 
 // Utilities that are used in multiple tests.
 
-import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js';
+import {LayoutOptions, Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 export class MockWindow {
@@ -222,9 +222,9 @@
 
 export class MockDocumentDimensions {
   /**
-   * @param {?number} width
-   * @param {?number} height
-   * @param {Object} layoutOptions
+   * @param {number=} width
+   * @param {number=} height
+   * @param {LayoutOptions=} layoutOptions
    */
   constructor(width, height, layoutOptions) {
     /** @type {number} */
@@ -233,7 +233,7 @@
     /** @type {number} */
     this.height = height ? height : 0;
 
-    /** @type {Object} */
+    /** @type {(LayoutOptions|undefined)} */
     this.layoutOptions = layoutOptions;
 
     /** @type {!Array<{x: number, y: number, width: number, height: number}>} */
@@ -296,9 +296,9 @@
 
 /**
  * Create a viewport with basic default zoom values.
- * @param {!HTMLElement} scrollParent
- * @param {!Element} sizer The element which represents the size of the
- *     document in the viewport
+ * @param {(!MockElement|!HTMLElement)} scrollParent
+ * @param {(!MockSizer|!HTMLDivElement)} sizer The element which represents the
+ *     size of the document in the viewport
  * @param {number} scrollbarWidth The width of scrollbars on the page
  * @param {number} defaultZoom The default zoom level.
  * @param {number} topToolbarHeight The number of pixels that should initially
@@ -312,8 +312,9 @@
       /** @type {!HTMLDivElement} */ (document.createElement('div'));
   document.body.appendChild(dummyContent);
   const viewport = new Viewport(
-      scrollParent, /** @type {!HTMLDivElement} */ (sizer), dummyContent,
-      scrollbarWidth, defaultZoom, topToolbarHeight, false);
+      /** @type {!HTMLElement} */ (scrollParent),
+      /** @type {!HTMLDivElement} */ (sizer), dummyContent, scrollbarWidth,
+      defaultZoom, topToolbarHeight, false);
   viewport.setZoomFactorRange([0.25, 0.4, 0.5, 1, 2]);
   return viewport;
 }
diff --git a/chrome/test/data/pdf/viewport_test.js b/chrome/test/data/pdf/viewport_test.js
index 6ee3750..42263f5 100644
--- a/chrome/test/data/pdf/viewport_test.js
+++ b/chrome/test/data/pdf/viewport_test.js
@@ -9,7 +9,7 @@
 
 const tests = [
   function testDocumentNeedsScrollbars() {
-    let viewport = getZoomableViewport(
+    const viewport = getZoomableViewport(
         new MockElement(100, 100), new MockSizer(), 10, 1, 0);
     let scrollbars;
 
@@ -43,30 +43,26 @@
     chrome.test.assertFalse(scrollbars.vertical);
     chrome.test.assertTrue(scrollbars.horizontal);
 
-    viewport.setDocumentDimensions(new MockDocumentDimensions(91, 101));
-    scrollbars = viewport.documentNeedsScrollbars(1);
-    chrome.test.assertTrue(scrollbars.vertical);
-    chrome.test.assertTrue(scrollbars.horizontal);
-
-    viewport.setDocumentDimensions(new MockDocumentDimensions(101, 91));
-    scrollbars = viewport.documentNeedsScrollbars(1);
-    chrome.test.assertTrue(scrollbars.vertical);
-    chrome.test.assertTrue(scrollbars.horizontal);
-
     viewport.setDocumentDimensions(new MockDocumentDimensions(40, 51));
     scrollbars = viewport.documentNeedsScrollbars(2);
     chrome.test.assertTrue(scrollbars.vertical);
     chrome.test.assertFalse(scrollbars.horizontal);
 
+    viewport.setDocumentDimensions(new MockDocumentDimensions(51, 40));
+    scrollbars = viewport.documentNeedsScrollbars(2);
+    chrome.test.assertFalse(scrollbars.vertical);
+    chrome.test.assertTrue(scrollbars.horizontal);
+
     viewport.setDocumentDimensions(new MockDocumentDimensions(101, 202));
     scrollbars = viewport.documentNeedsScrollbars(0.5);
     chrome.test.assertTrue(scrollbars.vertical);
     chrome.test.assertFalse(scrollbars.horizontal);
     chrome.test.succeed();
-
+  },
+  function testDocumentNeedsScrollbarsWithTopToolbar() {
     // Test the case when there is a toolbar at the top.
     const toolbarHeight = 10;
-    viewport = getZoomableViewport(
+    const viewport = getZoomableViewport(
         new MockElement(100, 100), new MockSizer(), 10, 1, toolbarHeight);
 
     viewport.setDocumentDimensions(new MockDocumentDimensions(90, 90));
@@ -98,6 +94,7 @@
     scrollbars = viewport.documentNeedsScrollbars(2);
     chrome.test.assertTrue(scrollbars.vertical);
     chrome.test.assertFalse(scrollbars.horizontal);
+    chrome.test.succeed();
   },
 
   function testSetZoom() {
diff --git a/chrome/test/data/webui/settings/clear_browsing_data_test.js b/chrome/test/data/webui/settings/clear_browsing_data_test.js
index 8c6a3ac..0feb7ae9 100644
--- a/chrome/test/data/webui/settings/clear_browsing_data_test.js
+++ b/chrome/test/data/webui/settings/clear_browsing_data_test.js
@@ -302,7 +302,8 @@
           assertFalse(cancelButton.disabled);
           assertFalse(actionButton.disabled);
           assertFalse(spinner.active);
-          assertFalse(!!element.$$('#notice'));
+          assertFalse(!!element.$$('#historyNotice'));
+          assertFalse(!!element.$$('#passwordsNotice'));
 
           // Check that the dialog didn't switch to installed apps.
           assertFalse(element.$$('#installedAppsDialog').open);
@@ -364,13 +365,13 @@
           const noticeActionButton = notice.$$('.action-button');
           assertTrue(!!noticeActionButton);
 
-          assertTrue(element.$$('#clearBrowsingDataDialog').open);
+          // The notice should have replaced the main dialog.
+          assertFalse(element.$$('#clearBrowsingDataDialog').open);
           assertTrue(notice.$$('#dialog').open);
 
           const whenNoticeClosed = eventToPromise('close', notice);
 
-          // Tapping the action button will close the notice. The parent dialog
-          // should subsequently close as well.
+          // Tapping the action button will close the notice.
           noticeActionButton.click();
 
           return whenNoticeClosed;
@@ -415,13 +416,13 @@
           const noticeActionButton = notice.$$('.action-button');
           assertTrue(!!noticeActionButton);
 
-          assertTrue(element.$$('#clearBrowsingDataDialog').open);
+          // The notice should have replaced the main dialog.
+          assertFalse(element.$$('#clearBrowsingDataDialog').open);
           assertTrue(notice.$$('#dialog').open);
 
           const whenNoticeClosed = eventToPromise('close', notice);
 
-          // Tapping the action button will close the notice. The parent dialog
-          // should subsequently close as well.
+          // Tapping the action button will close the notice.
           noticeActionButton.click();
 
           return whenNoticeClosed;
@@ -469,7 +470,8 @@
           const noticeActionButton = notice.$$('.action-button');
           assertTrue(!!noticeActionButton);
 
-          assertTrue(element.$$('#clearBrowsingDataDialog').open);
+          // The notice should have replaced the main dialog.
+          assertFalse(element.$$('#clearBrowsingDataDialog').open);
           assertTrue(notice.$$('#dialog').open);
 
           const whenNoticeClosed = eventToPromise('close', notice);
@@ -481,6 +483,7 @@
           return whenNoticeClosed;
         })
         .then(function() {
+          // The passwords notice should have replaced the history notice.
           const historyNotice = element.$$('#historyNotice');
           assertFalse(!!historyNotice);
           const passwordsNotice = element.$$('#passwordsNotice');
@@ -493,13 +496,12 @@
           const noticeActionButton = notice.$$('.action-button');
           assertTrue(!!noticeActionButton);
 
-          assertTrue(element.$$('#clearBrowsingDataDialog').open);
+          assertFalse(element.$$('#clearBrowsingDataDialog').open);
           assertTrue(notice.$$('#dialog').open);
 
           const whenNoticeClosed = eventToPromise('close', notice);
 
-          // Tapping the action button will close the notice.  The parent dialog
-          // should subsequently close as well.
+          // Tapping the action button will close the notice.
           noticeActionButton.click();
 
           return whenNoticeClosed;
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.js
index 9f646bb..674f8be 100644
--- a/chrome/test/data/webui/settings/passwords_section_test.js
+++ b/chrome/test/data/webui/settings/passwords_section_test.js
@@ -352,20 +352,79 @@
     const passwordListItems =
         passwordsSection.root.querySelectorAll('password-list-item');
     assertEquals(2, passwordListItems.length);
-    passwordListItems[0].password = 'pwd0';
-    passwordListItems[1].password = 'pwd1';
-    flush();
+    passwordListItems[0].set('entry.password', 'pwd0');
+    passwordListItems[1].set('entry.password', 'pwd1');
+    assertEquals('text', passwordListItems[0].$$('#password').type);
+    assertEquals('text', passwordListItems[1].$$('#password').type);
 
     // Remove first row and verify that the remaining password is hidden.
     passwordList.splice(0, 1);
     passwordManager.lastCallback.addSavedPasswordListChangedListener(
         passwordList);
     flush();
-    assertEquals('', getFirstPasswordListItem(passwordsSection).password);
+    assertEquals('', getFirstPasswordListItem(passwordsSection).entry.password);
+    assertEquals(
+        'password',
+        getFirstPasswordListItem(passwordsSection).$$('#password').type);
     assertEquals(
         'user1', getFirstPasswordListItem(passwordsSection).entry.username);
   });
 
+  test('listItemEditDialogShowAndHideInterplay', async function() {
+    const PASSWORD = 'p4ssw0rd';
+    const passwordList = [
+      createPasswordEntry({username: 'user0', id: 0}),
+    ];
+    const passwordsSection = elementFactory.createPasswordsSection(
+        passwordManager, passwordList, []);
+
+    // Make passwords visible.
+    const passwordListItem = getFirstPasswordListItem(passwordsSection);
+    passwordListItem.set('entry.password', PASSWORD);
+
+    assertEquals('text', passwordListItem.$$('#password').type);
+    assertFalse(passwordListItem.$$('#password').disabled);
+    assertTrue(passwordListItem.$$('#showPasswordButton')
+                   .classList.contains('icon-visibility-off'));
+
+    // Open Edit Dialog.
+    passwordListItem.$.moreActionsButton.click();
+    passwordsSection.$.passwordsListHandler.$.menuEditPassword.click();
+    flush();
+
+    // Verify that list item password is hidden.
+    assertEquals('', passwordListItem.entry.password);
+    assertEquals('password', passwordListItem.$$('#password').type);
+    assertTrue(passwordListItem.$$('#password').disabled);
+    assertTrue(passwordListItem.$$('#showPasswordButton')
+                   .classList.contains('icon-visibility'));
+
+    // Verify that edit dialog password is hidden.
+    const passwordEditDialog =
+        passwordsSection.$.passwordsListHandler.$$('#passwordEditDialog');
+    assertEquals('password', passwordEditDialog.$.passwordInput.type);
+    assertTrue(passwordEditDialog.$.showPasswordButton.classList.contains(
+        'icon-visibility'));
+
+    // Set password in edit dialog, verify it is visible.
+    passwordEditDialog.set('entry.password', PASSWORD);
+    assertEquals('text', passwordEditDialog.$.passwordInput.type);
+    assertTrue(passwordEditDialog.$.showPasswordButton.classList.contains(
+        'icon-visibility-off'));
+
+    // Close the dialog, verify that the list item password remains hidden.
+    // Note that the password only gets hidden in the on-close handler, thus we
+    // need to await this event first.
+    passwordEditDialog.$.actionButton.click();
+    await eventToPromise('close', passwordEditDialog);
+
+    assertEquals('', passwordListItem.entry.password);
+    assertEquals('password', passwordListItem.$$('#password').type);
+    assertTrue(passwordListItem.$$('#password').disabled);
+    assertTrue(passwordListItem.$$('#showPasswordButton')
+                   .classList.contains('icon-visibility'));
+  });
+
   // Test verifies that removing the account copy of a duplicated password will
   // still leave the device copy present.
   test('verifyPasswordListRemoveAccountCopy', function() {
@@ -1002,9 +1061,7 @@
 
     const editDialog = elementFactory.createPasswordEditDialog(commonEntry);
 
-    editDialog.password = PASSWORD1;
-    flush();
-
+    editDialog.set('entry.password', PASSWORD1);
     assertEquals(PASSWORD1, editDialog.$.passwordInput.value);
 
     // Empty password should be consider invalid and disables the save button.
@@ -1095,8 +1152,7 @@
 
     assertFalse(passwordDialog.$.showPasswordButton.hidden);
 
-    passwordDialog.password = PASSWORD;
-    flush();
+    passwordDialog.set('entry.password', PASSWORD);
 
     assertEquals(PASSWORD, passwordDialog.$.passwordInput.value);
     // Password should be visible.
@@ -1111,8 +1167,7 @@
     // Hidden passwords should be disabled.
     assertTrue(passwordListItem.$$('#password').disabled);
 
-    passwordListItem.password = PASSWORD;
-    flush();
+    passwordListItem.set('entry.password', PASSWORD);
 
     assertEquals(PASSWORD, passwordListItem.$$('#password').value);
     // Password should be visible.
@@ -1123,6 +1178,13 @@
     // Hide Password Button should be shown.
     assertTrue(passwordListItem.$$('#showPasswordButton')
                    .classList.contains('icon-visibility-off'));
+
+    // Hide the Password again.
+    passwordListItem.set('entry.password', '');
+    assertEquals('password', passwordListItem.$$('#password').type);
+    assertTrue(passwordListItem.$$('#password').disabled);
+    assertTrue(passwordListItem.$$('#showPasswordButton')
+                   .classList.contains('icon-visibility'));
   });
 
   // Tests that invoking the plaintext password sets the corresponding
@@ -1132,7 +1194,7 @@
         {url: 'goo.gl', username: 'bart', deviceId: 1});
     const passwordDialog =
         elementFactory.createPasswordEditDialog(expectedItem);
-    assertEquals('', passwordDialog.password);
+    assertEquals('', passwordDialog.entry.password);
 
     passwordManager.setPlaintextPassword('password');
     passwordDialog.$.showPasswordButton.click();
@@ -1140,7 +1202,7 @@
         .then(({id, reason}) => {
           assertEquals(1, id);
           assertEquals('VIEW', reason);
-          assertEquals('password', passwordDialog.password);
+          assertEquals('password', passwordDialog.entry.password);
         });
   });
 
@@ -1149,7 +1211,7 @@
         createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
     const passwordListItem =
         elementFactory.createPasswordListItem(expectedItem);
-    assertEquals('', passwordListItem.password);
+    assertEquals('', passwordListItem.entry.password);
 
     passwordManager.setPlaintextPassword('password');
     passwordListItem.$$('#showPasswordButton').click();
@@ -1157,7 +1219,7 @@
         .then(({id, reason}) => {
           assertEquals(1, id);
           assertEquals('VIEW', reason);
-          assertEquals('password', passwordListItem.password);
+          assertEquals('password', passwordListItem.entry.password);
         });
   });
 
diff --git a/chrome/test/data/webui/settings/safety_check_page_test.js b/chrome/test/data/webui/settings/safety_check_page_test.js
index 21b55a57..8dc02b0 100644
--- a/chrome/test/data/webui/settings/safety_check_page_test.js
+++ b/chrome/test/data/webui/settings/safety_check_page_test.js
@@ -210,6 +210,14 @@
     // Ensure the browser proxy call is done.
     await safetyCheckBrowserProxy.whenCalled('runSafetyCheck');
 
+    // Mock all incoming messages that indicate safety check is running.
+    fireSafetyCheckUpdatesEvent(SafetyCheckUpdatesStatus.CHECKING);
+    fireSafetyCheckPasswordsEvent(SafetyCheckPasswordsStatus.CHECKING);
+    fireSafetyCheckSafeBrowsingEvent(SafetyCheckSafeBrowsingStatus.CHECKING);
+    fireSafetyCheckExtensionsEvent(SafetyCheckExtensionsStatus.CHECKING);
+    fireSafetyCheckChromeCleanerEvent(SafetyCheckChromeCleanerStatus.CHECKING);
+    fireSafetyCheckParentEvent(SafetyCheckParentStatus.CHECKING);
+
     flush();
     // Only the icon button is present.
     assertFalse(!!page.$$('#safetyCheckParentButton'));
diff --git a/chrome/test/data/webui/signin/profile_creation_flow_test.js b/chrome/test/data/webui/signin/profile_creation_flow_test.js
index 72e4efd9..0663c21 100644
--- a/chrome/test/data/webui/signin/profile_creation_flow_test.js
+++ b/chrome/test/data/webui/signin/profile_creation_flow_test.js
@@ -21,4 +21,12 @@
   test('BackButton', function() {
     assertTrue(isChildVisible(choice, '#backButton'));
   });
+
+  test('SignInButton', function() {
+    assertTrue(isChildVisible(choice, '#signInButton'));
+  });
+
+  test('NotNowButton', function() {
+    assertTrue(isChildVisible(choice, '#notNowButton'));
+  });
 });
diff --git a/chrome/test/data/webui/signin/signin_browsertest.js b/chrome/test/data/webui/signin/signin_browsertest.js
index f4359d46..239aa4ca 100644
--- a/chrome/test/data/webui/signin/signin_browsertest.js
+++ b/chrome/test/data/webui/signin/signin_browsertest.js
@@ -97,6 +97,6 @@
   }
 };
 
-TEST_F('ProfileCreationFlowTest', 'BackButton', function() {
+TEST_F('ProfileCreationFlowTest', 'Buttons', function() {
   mocha.run();
 });
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 1bec8d4..352cb6c 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-13380.0.0
\ No newline at end of file
+13387.0.0
\ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/BUILD.gn b/chromeos/components/camera_app_ui/BUILD.gn
index efa0680..10ecec7 100644
--- a/chromeos/components/camera_app_ui/BUILD.gn
+++ b/chromeos/components/camera_app_ui/BUILD.gn
@@ -13,6 +13,7 @@
     "camera_app_helper_impl.h",
     "camera_app_ui.cc",
     "camera_app_ui.h",
+    "camera_app_ui_delegate.h",
     "url_constants.cc",
     "url_constants.h",
   ]
diff --git a/chromeos/components/camera_app_ui/camera_app_ui.cc b/chromeos/components/camera_app_ui/camera_app_ui.cc
index 5a4b019..d97e546 100644
--- a/chromeos/components/camera_app_ui/camera_app_ui.cc
+++ b/chromeos/components/camera_app_ui/camera_app_ui.cc
@@ -177,8 +177,9 @@
   mojo::MakeSelfOwnedReceiver(std::move(helper), std::move(receiver));
 }
 
-CameraAppUI::CameraAppUI(content::WebUI* web_ui)
-    : ui::MojoWebUIController(web_ui) {
+CameraAppUI::CameraAppUI(content::WebUI* web_ui,
+                         std::unique_ptr<CameraAppUIDelegate> delegate)
+    : ui::MojoWebUIController(web_ui), delegate_(std::move(delegate)) {
   content::BrowserContext* browser_context =
       web_ui->GetWebContents()->GetBrowserContext();
 
diff --git a/chromeos/components/camera_app_ui/camera_app_ui.h b/chromeos/components/camera_app_ui/camera_app_ui.h
index 31eafc50..756d109 100644
--- a/chromeos/components/camera_app_ui/camera_app_ui.h
+++ b/chromeos/components/camera_app_ui/camera_app_ui.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "chromeos/components/camera_app_ui/camera_app_helper.mojom.h"
+#include "chromeos/components/camera_app_ui/camera_app_ui_delegate.h"
 #include "media/capture/video/chromeos/mojom/camera_app.mojom.h"
 #include "ui/aura/window.h"
 #include "ui/webui/mojo_web_ui_controller.h"
@@ -23,7 +24,8 @@
 
 class CameraAppUI : public ui::MojoWebUIController {
  public:
-  explicit CameraAppUI(content::WebUI* web_ui);
+  CameraAppUI(content::WebUI* web_ui,
+              std::unique_ptr<CameraAppUIDelegate> delegate);
   ~CameraAppUI() override;
 
   // [To be deprecated] This method is only used for CCA as a platform app and
@@ -51,9 +53,13 @@
   void BindInterface(
       mojo::PendingReceiver<chromeos_camera::mojom::CameraAppHelper> receiver);
 
+  CameraAppUIDelegate* delegate() { return delegate_.get(); }
+
  private:
   aura::Window* window();
 
+  std::unique_ptr<CameraAppUIDelegate> delegate_;
+
   std::unique_ptr<media::CameraAppDeviceProviderImpl> provider_;
 
   std::unique_ptr<chromeos_camera::CameraAppHelperImpl> helper_;
diff --git a/chromeos/components/camera_app_ui/camera_app_ui_delegate.h b/chromeos/components/camera_app_ui/camera_app_ui_delegate.h
new file mode 100644
index 0000000..2f04ab4
--- /dev/null
+++ b/chromeos/components/camera_app_ui/camera_app_ui_delegate.h
@@ -0,0 +1,15 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_COMPONENTS_CAMERA_APP_UI_CAMERA_APP_UI_DELEGATE_H_
+#define CHROMEOS_COMPONENTS_CAMERA_APP_UI_CAMERA_APP_UI_DELEGATE_H_
+
+// A delegate which exposes browser functionality from //chrome to the camera
+// app ui page handler.
+class CameraAppUIDelegate {
+ public:
+  virtual ~CameraAppUIDelegate() = default;
+};
+
+#endif  // CHROMEOS_COMPONENTS_CAMERA_APP_UI_CAMERA_APP_UI_DELEGATE_H_
diff --git a/chromeos/components/telemetry_extension_ui/resources/BUILD.gn b/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
index 4695707d1..226dcde 100644
--- a/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
+++ b/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
@@ -52,5 +52,4 @@
 }
 
 js_library("untrusted_worker") {
-  sources = [ "untrusted_worker.js" ]
 }
diff --git a/chromeos/components/telemetry_extension_ui/resources/index.html b/chromeos/components/telemetry_extension_ui/resources/index.html
index 84ca774..5589737 100644
--- a/chromeos/components/telemetry_extension_ui/resources/index.html
+++ b/chromeos/components/telemetry_extension_ui/resources/index.html
@@ -7,7 +7,6 @@
 <iframe src="chrome-untrusted://telemetry-extension/untrusted.html"
      style="position:fixed; top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"></iframe>
 
-<!-- Below mojo script required to run browser tests -->
 <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
 
 <script src="diagnostics_service.mojom-lite.js"></script>
diff --git a/chromeos/components/telemetry_extension_ui/resources/message_types.js b/chromeos/components/telemetry_extension_ui/resources/message_types.js
index 6f42dbd..7d7edb6 100644
--- a/chromeos/components/telemetry_extension_ui/resources/message_types.js
+++ b/chromeos/components/telemetry_extension_ui/resources/message_types.js
@@ -9,21 +9,25 @@
  */
 
 /**
+ * @const
+ */
+const dpsl_internal = {};
+
+/**
  * Enum for message types.
  * @enum {string}
  */
-const Message = {
+dpsl_internal.Message = {
   DIAGNOSTICS_AVAILABLE_ROUTINES: 'DiagnosticsService.GetAvailableRoutines',
   PROBE_TELEMETRY_INFO: 'ProbeService.ProbeTelemetryInfo',
 };
 
-
 /**
  * Request message sent by the unprivileged context to request the privileged
  * context to diagnostics to get available routines.
  * @typedef {null}
  */
-let DiagnosticsGetAvailableRoutinesRequest;
+dpsl_internal.DiagnosticsGetAvailableRoutinesRequest;
 
 /**
  * Response message sent by the privileged context containing diagnostic
@@ -31,18 +35,21 @@
  * @typedef {{availableRoutines:
  *    !Array<!chromeos.health.mojom.DiagnosticRoutineEnum>}}
  */
-let DiagnosticsGetAvailableRoutinesResponse;
+dpsl_internal.DiagnosticsGetAvailableRoutinesResponse;
 
 /**
  * Request message sent by the unprivileged context to request the privileged
  * context to probe telemetry information
- * @typedef {null}
+ * @typedef { !Array<!string> }
  */
-let ProbeTelemetryInfoRequest;
+dpsl_internal.ProbeTelemetryInfoRequest;
 
 /**
  * Response message sent by the privileged context sending telemetry
  * information.
- * @typedef {{telemetryInfo: chromeos.health.mojom.TelemetryInfo}}
+ * @typedef {{
+ *   telemetryInfo: (!chromeos.health.mojom.TelemetryInfo|undefined),
+ *   error: (!Error|undefined)
+ * }}
  */
-let ProbeTelemetryInfoResponse;
+dpsl_internal.ProbeTelemetryInfoResponse;
diff --git a/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd b/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
index af1f4ad..d8a32cb6 100644
--- a/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
+++ b/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
@@ -22,7 +22,7 @@
         <include name="IDR_TELEMETRY_EXTENSION_DIAGNOSTICS_SERVICE_MOJO_LITE_JS" file="${root_gen_dir}/chromeos/components/telemetry_extension_ui/mojom/diagnostics_service.mojom-lite.js" compress="gzip" use_base_dir="false" type="BINDATA" />
         <include name="IDR_TELEMETRY_EXTENSION_PROBE_SERVICE_MOJO_LITE_JS" file="${root_gen_dir}/chromeos/components/telemetry_extension_ui/mojom/probe_service.mojom-lite.js" compress="gzip" use_base_dir="false" type="BINDATA" />
 
-        <!-- Untrusted app contents. -->
+        <!-- Untrusted app host contents. -->
         <include name="IDR_TELEMETRY_EXTENSION_UNTRUSTED_HTML" file="untrusted.html" type="BINDATA" compress="gzip" />
         <include name="IDR_TELEMETRY_EXTENSION_UNTRUSTED_SCRIPTS_JS" file="untrusted_scripts.js" flattenhtml="true" type="BINDATA" compress="gzip" />
         <include name="IDR_TELEMETRY_EXTENSION_UNTRUSTED_WORKER_JS" file="untrusted_worker.js" type="BINDATA" compress="gzip" />
diff --git a/chromeos/components/telemetry_extension_ui/resources/trusted.js b/chromeos/components/telemetry_extension_ui/resources/trusted.js
index fe65e6c..b334ecd 100644
--- a/chromeos/components/telemetry_extension_ui/resources/trusted.js
+++ b/chromeos/components/telemetry_extension_ui/resources/trusted.js
@@ -3,27 +3,110 @@
 // found in the LICENSE file.
 
 /**
- * Pointer to remote implementation of diagnostics service.
- * @type {!chromeos.health.mojom.DiagnosticsServiceRemote}
+ * @type { MessagePipe|null }
  */
-const diagnosticsService = chromeos.health.mojom.DiagnosticsService.getRemote();
+var untrustedMessagePipe = null;
 
-/**
- * Pointer to remote implementation of probe service.
- * @type {!chromeos.health.mojom.ProbeServiceRemote}
- */
-const probeService = chromeos.health.mojom.ProbeService.getRemote();
+document.addEventListener('DOMContentLoaded', async () => {
+  let diagnosticsService = null;
+  let probeService = null;
 
-const untrustedMessagePipe =
-  new MessagePipe('chrome-untrusted://telemetry-extension');
+  /**
+   * Lazy creates pointer to remote implementation of diagnostics service.
+   * @return {!chromeos.health.mojom.DiagnosticsServiceRemote}
+   */
+  function getOrCreateDiagnosticsService() {
+    if (diagnosticsService === null) {
+      diagnosticsService = chromeos.health.mojom.DiagnosticsService.getRemote();
+    }
+    return /** @type {!chromeos.health.mojom.DiagnosticsServiceRemote} */ (
+        diagnosticsService);
+  }
 
-untrustedMessagePipe.registerHandler(Message.DIAGNOSTICS_AVAILABLE_ROUTINES,
-  async () => {
-    return await diagnosticsService.getAvailableRoutines();
-  });
+  /**
+   * Lazy creates pointer to remote implementation of probe service.
+   * @return {!chromeos.health.mojom.ProbeServiceRemote}
+   */
+  function getOrCreateProbeService() {
+    if (probeService === null) {
+      probeService = chromeos.health.mojom.ProbeService.getRemote();
+    }
+    return /** @type {!chromeos.health.mojom.ProbeServiceRemote} */ (
+        probeService);
+  }
 
-untrustedMessagePipe.registerHandler(Message.PROBE_TELEMETRY_INFO, async () => {
-  const response = await probeService.probeTelemetryInfo(
-    [chromeos.health.mojom.ProbeCategoryEnum.kBattery]);
-  return { telemetryInfo: response.telemetryInfo };
+  /**
+   * Proxying telemetry requests between TelemetryRequester on
+   * chrome-untrusted:// side with WebIDL types and ProbeService on chrome://
+   * side with Mojo types.
+   */
+  class TelemetryProxy {
+    constructor() {
+      const categoryEnum = chromeos.health.mojom.ProbeCategoryEnum;
+
+      /**
+       * @type { !Map<!string, !chromeos.health.mojom.ProbeCategoryEnum> }
+       * @const
+       */
+      this.categoryToEnum_ = new Map([
+        ['battery', categoryEnum.kBattery],
+        ['non-removable-block-devices', categoryEnum.kNonRemovableBlockDevices],
+        ['cached-vpd-data', categoryEnum.kCachedVpdData],
+        ['cpu', categoryEnum.kCpu], ['timezone', categoryEnum.kTimezone],
+        ['memory', categoryEnum.kMemory],
+        ['backlight', categoryEnum.kBacklight], ['fan', categoryEnum.kFan],
+        ['stateful-partition', categoryEnum.kStatefulPartition],
+        ['bluetooth', categoryEnum.kBluetooth]
+      ]);
+    }
+
+    /**
+     * @param { !Array<!string> } categories
+     * @return { !Array<!chromeos.health.mojom.ProbeCategoryEnum> }
+     */
+    convertCategories(categories) {
+      return categories.map((category) => {
+        if (!this.categoryToEnum_.has(category)) {
+          throw TypeError(`Telemetry category '${category}' is unknown.`);
+        }
+        return this.categoryToEnum_.get(category);
+      });
+    }
+
+    /**
+     * Requests telemetry info.
+     * @param { Object } message
+     * @return { dpsl_internal.ProbeTelemetryInfoResponse }
+     */
+    async handleProbeTelemetryInfo(message) {
+      const request =
+          /** @type {!dpsl_internal.ProbeTelemetryInfoRequest} */ (message);
+
+      /** @type {!Array<!chromeos.health.mojom.ProbeCategoryEnum>} */
+      let categories = [];
+      try {
+        categories = telemetryProxy.convertCategories(request);
+      } catch (/** @type {!Error}*/ error) {
+        return {error};
+      }
+
+      return await getOrCreateProbeService().probeTelemetryInfo(categories);
+    }
+  };
+
+  const telemetryProxy = new TelemetryProxy();
+
+  const untrustedMessagePipe =
+      new MessagePipe('chrome-untrusted://telemetry-extension');
+
+  untrustedMessagePipe.registerHandler(
+      dpsl_internal.Message.DIAGNOSTICS_AVAILABLE_ROUTINES, async () => {
+        return await getOrCreateDiagnosticsService().getAvailableRoutines();
+      });
+
+  untrustedMessagePipe.registerHandler(
+      dpsl_internal.Message.PROBE_TELEMETRY_INFO,
+      (message) => telemetryProxy.handleProbeTelemetryInfo(message));
+
+  globalThis.untrustedMessagePipe = untrustedMessagePipe;
 });
diff --git a/chromeos/components/telemetry_extension_ui/resources/untrusted.html b/chromeos/components/telemetry_extension_ui/resources/untrusted.html
index 4556a41..c26350e0 100644
--- a/chromeos/components/telemetry_extension_ui/resources/untrusted.html
+++ b/chromeos/components/telemetry_extension_ui/resources/untrusted.html
@@ -6,6 +6,8 @@
 <meta charset="utf-8">
 <title>Untrusted Telemetry Extension</title>
 <h1 id='untrusted-title'>Telemetry Extension</h1>
+
 <script src="mojo_bindings_lite.js"></script>
 <script src="diagnostics_service.mojom-lite.js"></script>
+<script src="probe_service.mojom-lite.js"></script>
 <script src="untrusted_scripts.js"></script>
diff --git a/chromeos/components/telemetry_extension_ui/resources/untrusted.js b/chromeos/components/telemetry_extension_ui/resources/untrusted.js
index 52dd61c..d0f07b80 100644
--- a/chromeos/components/telemetry_extension_ui/resources/untrusted.js
+++ b/chromeos/components/telemetry_extension_ui/resources/untrusted.js
@@ -2,27 +2,86 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/** A pipe through which we can send messages to the parent frame. */
-const parentMessagePipe =
-    new MessagePipe('chrome://telemetry-extension', window.parent);
+/**
+ * @fileoverview
+ *
+ * Diagnostic Processor Support Library (DPSL) is a collection of telemetry and
+ * diagnostics interfaces exposed to third-parties:
+ *
+ *   - chromeos.diagnostics
+ *     | Diagnostics interface for running device diagnostics routines (tests).
+ *
+ *   - chromeos.telemetry
+ *     | Telemetry (a.k.a. Probe) interface for getting device telemetry
+ *     | information.
+ */
+
+chromeos.diagnostics = null;
+
+chromeos.telemetry = null;
 
 /**
- * Requests probe telemetry info.
- * @return {!Promise<ProbeTelemetryInfoResponse>}
+ * This is only for testing purposes. Please don't use it in the production,
+ * because we may silently change or remove it.
  */
-async function requestTelemetryInfo() {
-  const response = /** @type {!ProbeTelemetryInfoResponse} */ (
-      await parentMessagePipe.sendMessage(Message.PROBE_TELEMETRY_INFO));
-  return response;
-}
+chromeos.test_support = {};
 
-/**
- * Requests a list of available routines.
- * @return {!Promise<DiagnosticsGetAvailableRoutinesResponse>}
- */
-async function getAvailableRoutines() {
-  const response = /** @type {!DiagnosticsGetAvailableRoutinesResponse} */ (
-      await parentMessagePipe.sendMessage(
-        Message.DIAGNOSTICS_AVAILABLE_ROUTINES));
-  return response;
-}
+(() => {
+  const messagePipe =
+      new MessagePipe('chrome://telemetry-extension', window.parent);
+
+  /**
+   * DPSL Diagnostics Requester.
+   */
+  class DiagnosticsRequester {
+    constructor() {}
+
+    /**
+     * Requests a list of available routines.
+     * @return {!Promise<!Array<!chromeos.health.mojom.DiagnosticRoutineEnum>>}
+     * @public
+     */
+    async getAvailableRoutines() {
+      const response =
+          /** @type {dpsl_internal.DiagnosticsGetAvailableRoutinesResponse} */ (
+              await messagePipe.sendMessage(
+                  dpsl_internal.Message.DIAGNOSTICS_AVAILABLE_ROUTINES));
+      return response.availableRoutines;
+    }
+  };
+
+  /**
+   * DPSL Telemetry Requester.
+   */
+  class TelemetryRequester {
+    constructor() {}
+
+    /**
+     * Requests telemetry info.
+     * @param { !Array<!string> } categories
+     * @return { !Promise<!chromeos.health.mojom.TelemetryInfo> }
+     * @public
+     */
+    async probeTelemetryInfo(categories) {
+      const response =
+          /** @type {dpsl_internal.ProbeTelemetryInfoResponse} */ (
+              await messagePipe.sendMessage(
+                  dpsl_internal.Message.PROBE_TELEMETRY_INFO, categories));
+      if (response.error !== undefined) {
+        throw response.error;
+      }
+      return /** @type {!chromeos.health.mojom.TelemetryInfo} */ (
+          response.telemetryInfo);
+    }
+  };
+
+  globalThis.chromeos.diagnostics = new DiagnosticsRequester();
+  globalThis.chromeos.telemetry = new TelemetryRequester();
+
+  globalThis.chromeos.test_support.messagePipe = function() {
+    console.warn(
+        'messagePipe() is a method for testing purposes only. Please',
+        'do not use it, otherwise your app may be broken in the future.');
+    return messagePipe;
+  }
+})();
diff --git a/chromeos/components/telemetry_extension_ui/telemetry_extension_ui.cc b/chromeos/components/telemetry_extension_ui/telemetry_extension_ui.cc
index f0bcb96..572b79e1 100644
--- a/chromeos/components/telemetry_extension_ui/telemetry_extension_ui.cc
+++ b/chromeos/components/telemetry_extension_ui/telemetry_extension_ui.cc
@@ -77,6 +77,9 @@
   untrusted_source->AddResourcePath(
       "diagnostics_service.mojom-lite.js",
       IDR_TELEMETRY_EXTENSION_DIAGNOSTICS_SERVICE_MOJO_LITE_JS);
+  untrusted_source->AddResourcePath(
+      "probe_service.mojom-lite.js",
+      IDR_TELEMETRY_EXTENSION_PROBE_SERVICE_MOJO_LITE_JS);
 
   untrusted_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::FrameAncestors,
diff --git a/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js b/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js
index 8237e91..2c6881a4 100644
--- a/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js
+++ b/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js
@@ -43,6 +43,7 @@
   /** @override */
   get extraLibraries() {
     return [
+      ...super.extraLibraries,
       '//chromeos/components/telemetry_extension_ui/test/trusted_test_requester.js',
     ];
   }
@@ -76,15 +77,117 @@
     });
 
 TEST_F(
-    'TelemetryExtensionUIBrowserTest', 'UntrustedRequestTelemetryInfo',
+    'TelemetryExtensionUIBrowserTest', 'UntrustedRequestAvailableRoutines',
     async () => {
-      await runTestInUntrusted('UntrustedRequestTelemetryInfo');
+      await runTestInUntrusted('UntrustedRequestAvailableRoutines');
       testDone();
     });
 
 TEST_F(
-  'TelemetryExtensionUIBrowserTest', 'UntrustedRequestAvailableRoutines',
-  async () => {
-    await runTestInUntrusted('UntrustedRequestAvailableRoutines');
-    testDone();
-  });
+    'TelemetryExtensionUIBrowserTest',
+    'UntrustedRequestTelemetryInfoUnknownCategory', async () => {
+      await runTestInUntrusted('UntrustedRequestTelemetryInfoUnknownCategory');
+      testDone();
+    });
+
+/**
+ * @implements {chromeos.health.mojom.ProbeServiceInterface}
+ */
+class TestProbeService {
+  constructor() {
+    /**
+     * @type {chromeos.health.mojom.ProbeServiceReceiver}
+     */
+    this.receiver_ = null;
+
+    /**
+     * @type {Array<!chromeos.health.mojom.ProbeCategoryEnum>}
+     */
+    this.probeTelemetryInfoCategories = null;
+  }
+
+  /**
+   * @param {!MojoHandle} handle
+   */
+  bind(handle) {
+    this.receiver_ = new chromeos.health.mojom.ProbeServiceReceiver(this);
+    this.receiver_.$.bindHandle(handle);
+  }
+
+  /**
+   * @override
+   * @param { !Array<!chromeos.health.mojom.ProbeCategoryEnum> } categories
+   * @return {!Promise<{telemetryInfo:
+   *     !chromeos.health.mojom.TelemetryInfo}>}
+   */
+  probeTelemetryInfo(categories) {
+    this.probeTelemetryInfoCategories = categories;
+
+    const telemetryInfo = /** @type {!chromeos.health.mojom.TelemetryInfo} */ ({
+      backlightResult: null,
+      batteryResult: null,
+      blockDeviceResult: null,
+      bluetoothResult: null,
+      cpuResult: null,
+      fanResult: null,
+      memoryResult: null,
+      statefulPartitionResult: null,
+      timezoneResult: null,
+      vpdResult: null,
+    });
+    return Promise.resolve({telemetryInfo});
+  }
+};
+
+// Tests with a testing Mojo probe service, so we can test for example strings
+// conversion to Mojo enum values.
+var TelemetryExtensionUIWithInterceptorBrowserTest =
+    class extends TelemetryExtensionUIBrowserTest {
+  constructor() {
+    super();
+
+    /**
+     * @type {TestProbeService}
+     */
+    this.probeService = null;
+
+    this.probeServiceInterceptor = null;
+  }
+
+  /** @override */
+  setUp() {
+    this.probeService = new TestProbeService();
+
+    /** @suppress {undefinedVars} */
+    this.probeServiceInterceptor = new MojoInterfaceInterceptor(
+        chromeos.health.mojom.ProbeService.$interfaceName);
+    this.probeServiceInterceptor.oninterfacerequest = (e) => {
+      this.probeService.bind(e.handle);
+    };
+    this.probeServiceInterceptor.start();
+  }
+};
+
+// Test cases injected into the untrusted context.
+// See implementations in untrusted_browsertest.js.
+
+TEST_F(
+    'TelemetryExtensionUIWithInterceptorBrowserTest',
+    'UntrustedRequestTelemetryInfo', async function() {
+      await runTestInUntrusted('UntrustedRequestTelemetryInfo');
+
+      assertDeepEquals(this.probeService.probeTelemetryInfoCategories, [
+        chromeos.health.mojom.ProbeCategoryEnum.kBattery,
+        chromeos.health.mojom.ProbeCategoryEnum.kNonRemovableBlockDevices,
+        chromeos.health.mojom.ProbeCategoryEnum.kCachedVpdData,
+        chromeos.health.mojom.ProbeCategoryEnum.kCpu,
+        chromeos.health.mojom.ProbeCategoryEnum.kTimezone,
+        chromeos.health.mojom.ProbeCategoryEnum.kMemory,
+        chromeos.health.mojom.ProbeCategoryEnum.kBacklight,
+        chromeos.health.mojom.ProbeCategoryEnum.kFan,
+        chromeos.health.mojom.ProbeCategoryEnum.kStatefulPartition,
+        chromeos.health.mojom.ProbeCategoryEnum.kBluetooth
+      ]);
+
+      testDone();
+    });
diff --git a/chromeos/components/telemetry_extension_ui/test/untrusted_browsertest.js b/chromeos/components/telemetry_extension_ui/test/untrusted_browsertest.js
index 9bbb3dd..6f1e99a 100644
--- a/chromeos/components/telemetry_extension_ui/test/untrusted_browsertest.js
+++ b/chromeos/components/telemetry_extension_ui/test/untrusted_browsertest.js
@@ -51,47 +51,65 @@
   assertEquals(response, MESSAGE);
 });
 
-// Tests that TelemetryInfo can be successfully requested from
-// from chrome-untrusted://.
-UNTRUSTED_TEST('UntrustedRequestTelemetryInfo', async () => {
-  /** @type {!ProbeTelemetryInfoResponse} */
-  const response = await requestTelemetryInfo();
-  assertDeepEquals(response, {
-    'telemetryInfo': {
-      'backlightResult': null,
-      'batteryResult': null,
-      'blockDeviceResult': null,
-      'bluetoothResult': null,
-      'cpuResult': null,
-      'fanResult': null,
-      'memoryResult': null,
-      'statefulPartitionResult': null,
-      'timezoneResult': null,
-      'vpdResult': null,
-    }
-  });
+// Tests that TelemetryInfo throws an error if category is unknown.
+UNTRUSTED_TEST('UntrustedRequestTelemetryInfoUnknownCategory', async () => {
+  let caughtError = {};
+
+  try {
+    await chromeos.telemetry.probeTelemetryInfo(
+        ['unknown-category']);
+  } catch (error) {
+    caughtError = error;
+  }
+
+  assertEquals(caughtError.name, 'TypeError');
+  assertEquals(
+      caughtError.message,
+      'Telemetry category \'unknown-category\' is unknown.');
 });
 
 // Tests that array of available routines can be successfully
 // requested from chrome-untrusted://.
 UNTRUSTED_TEST('UntrustedRequestAvailableRoutines', async () => {
-  /** @type {!DiagnosticsGetAvailableRoutinesResponse} */
-  const response = await getAvailableRoutines();
+  /** @type {!Array<!chromeos.health.mojom.DiagnosticRoutineEnum>} */
+  const response = await chromeos.diagnostics.getAvailableRoutines();
+  assertDeepEquals(response, [
+    chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryCapacity,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryHealth,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kUrandom,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kSmartctlCheck,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kAcPower,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kCpuCache,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kCpuStress,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kFloatingPointAccuracy,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kNvmeWearLevel,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kNvmeSelfTest,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kDiskRead,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kPrimeSearch,
+    chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryDischarge,
+  ]);
+});
+
+// Tests that TelemetryInfo can be successfully requested from
+// from chrome-untrusted://.
+UNTRUSTED_TEST('UntrustedRequestTelemetryInfo', async () => {
+  /**
+   * @type {!chromeos.health.mojom.TelemetryInfo}
+   */
+  const response = await chromeos.telemetry.probeTelemetryInfo([
+    'battery', 'non-removable-block-devices', 'cached-vpd-data', 'cpu',
+    'timezone', 'memory', 'backlight', 'fan', 'stateful-partition', 'bluetooth'
+  ]);
   assertDeepEquals(response, {
-    'availableRoutines': [
-      chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryCapacity,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryHealth,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kUrandom,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kSmartctlCheck,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kAcPower,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kCpuCache,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kCpuStress,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kFloatingPointAccuracy,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kNvmeWearLevel,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kNvmeSelfTest,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kDiskRead,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kPrimeSearch,
-      chromeos.health.mojom.DiagnosticRoutineEnum.kBatteryDischarge,
-    ]
+    'backlightResult': null,
+    'batteryResult': null,
+    'blockDeviceResult': null,
+    'bluetoothResult': null,
+    'cpuResult': null,
+    'fanResult': null,
+    'memoryResult': null,
+    'statefulPartitionResult': null,
+    'timezoneResult': null,
+    'vpdResult': null,
   });
 });
diff --git a/chromeos/components/telemetry_extension_ui/test/untrusted_test_handlers.js b/chromeos/components/telemetry_extension_ui/test/untrusted_test_handlers.js
index 6a17b14..11ea18c4 100644
--- a/chromeos/components/telemetry_extension_ui/test/untrusted_test_handlers.js
+++ b/chromeos/components/telemetry_extension_ui/test/untrusted_test_handlers.js
@@ -32,10 +32,11 @@
 }
 
 function registerTestHandlers() {
-  parentMessagePipe.registerHandler('run-test-case', (message) => {
-    const {testName} = /** @type {{testName: !string}} */ (message);
-    return runTestCase(testName);
-  });
+  chromeos.test_support.messagePipe().registerHandler(
+      'run-test-case', (message) => {
+        const {testName} = /** @type {{testName: !string}} */ (message);
+        return runTestCase(testName);
+      });
 }
 
 registerTestHandlers();
diff --git a/chromeos/printing/ppd_metadata_matchers.h b/chromeos/printing/ppd_metadata_matchers.h
index 8843fe0..83d499e 100644
--- a/chromeos/printing/ppd_metadata_matchers.h
+++ b/chromeos/printing/ppd_metadata_matchers.h
@@ -74,6 +74,30 @@
                             result_listener);
 }
 
+// Matches a ParsedIndexLeaf struct against its
+// |ppd_basename| member.
+MATCHER_P(ParsedIndexLeafWithPpdBasename,
+          ppd_basename,
+          "is a ParsedIndexLeaf with ppd_basename ``" +
+              std::string(ppd_basename) + "''") {
+  return ExplainMatchResult(
+      Field(&ParsedIndexLeaf::ppd_basename, StrEq(ppd_basename)), arg,
+      result_listener);
+}
+
+// Matches a key-value pair in a ParsedIndex against its constituent
+// members. |parsed_index_leaf_matcher| is matched against the |values|
+// member of a ParsedIndexValues struct.
+MATCHER_P2(ParsedIndexEntryLike,
+           emm,
+           parsed_index_leaf_matcher,
+           "is a ParsedIndex entry with effective-make-and-model string ``" +
+               std::string(emm) + "''") {
+  return ExplainMatchResult(Pair(StrEq(emm), Field(&ParsedIndexValues::values,
+                                                   parsed_index_leaf_matcher)),
+                            arg, result_listener);
+}
+
 // Matches a ParsedPrinter struct against its
 // |user_visible_printer_name| and |effective_make_and_model| members.
 MATCHER_P2(ParsedPrinterLike,
diff --git a/chromeos/printing/ppd_metadata_parser.cc b/chromeos/printing/ppd_metadata_parser.cc
index 11a0e9b..458be47 100644
--- a/chromeos/printing/ppd_metadata_parser.cc
+++ b/chromeos/printing/ppd_metadata_parser.cc
@@ -120,6 +120,53 @@
   return printer;
 }
 
+// Returns a ParsedIndexLeaf from |value|.
+base::Optional<ParsedIndexLeaf> ParsedIndexLeafFrom(const base::Value& value) {
+  if (!value.is_dict()) {
+    return base::nullopt;
+  }
+
+  ParsedIndexLeaf leaf;
+
+  const std::string* const ppd_basename = value.FindStringKey("name");
+  if (!ppd_basename) {
+    return base::nullopt;
+  }
+  leaf.ppd_basename = *ppd_basename;
+
+  const base::Value* const restrictions_value =
+      value.FindDictKey("restriction");
+  if (restrictions_value) {
+    leaf.restrictions = ParseRestrictionsFromValue(*restrictions_value);
+  }
+  return leaf;
+}
+
+// Returns a ParsedIndexValues from a |value| extracted from a forward
+// index.
+base::Optional<ParsedIndexValues> UnnestPpdMetadata(const base::Value& value) {
+  if (!value.is_dict()) {
+    return base::nullopt;
+  }
+  const base::Value* const ppd_metadata_list = value.FindListKey("ppdMetadata");
+  if (!ppd_metadata_list || ppd_metadata_list->GetList().size() == 0) {
+    return base::nullopt;
+  }
+
+  ParsedIndexValues parsed_index_values;
+  for (const base::Value& v : ppd_metadata_list->GetList()) {
+    base::Optional<ParsedIndexLeaf> parsed_index_leaf = ParsedIndexLeafFrom(v);
+    if (parsed_index_leaf.has_value()) {
+      parsed_index_values.values.push_back(parsed_index_leaf.value());
+    }
+  }
+
+  if (parsed_index_values.values.empty()) {
+    return base::nullopt;
+  }
+  return parsed_index_values;
+}
+
 }  // namespace
 
 ParsedPrinter::ParsedPrinter() = default;
@@ -127,6 +174,17 @@
 ParsedPrinter::ParsedPrinter(const ParsedPrinter&) = default;
 ParsedPrinter& ParsedPrinter::operator=(const ParsedPrinter&) = default;
 
+ParsedIndexLeaf::ParsedIndexLeaf() = default;
+ParsedIndexLeaf::~ParsedIndexLeaf() = default;
+ParsedIndexLeaf::ParsedIndexLeaf(const ParsedIndexLeaf&) = default;
+ParsedIndexLeaf& ParsedIndexLeaf::operator=(const ParsedIndexLeaf&) = default;
+
+ParsedIndexValues::ParsedIndexValues() = default;
+ParsedIndexValues::~ParsedIndexValues() = default;
+ParsedIndexValues::ParsedIndexValues(const ParsedIndexValues&) = default;
+ParsedIndexValues& ParsedIndexValues::operator=(const ParsedIndexValues&) =
+    default;
+
 base::Optional<std::vector<std::string>> ParseLocales(
     base::StringPiece locales_json) {
   const auto as_value =
@@ -171,6 +229,32 @@
   return manufacturers;
 }
 
+base::Optional<ParsedIndex> ParseForwardIndex(
+    base::StringPiece forward_index_json) {
+  // Firstly, we unnest the dictionary keyed by "ppdIndex."
+  base::Optional<base::Value> ppd_index = ParseJsonAndUnnestKey(
+      forward_index_json, "ppdIndex", base::Value::Type::DICTIONARY);
+  if (!ppd_index || ppd_index->DictSize() == 0) {
+    return base::nullopt;
+  }
+
+  ParsedIndex parsed_index;
+
+  // Secondly, we iterate on the key-value pairs of the ppdIndex.
+  // This yields a list of leaf values (dictionaries).
+  for (const auto& kv : ppd_index->DictItems()) {
+    base::Optional<ParsedIndexValues> values = UnnestPpdMetadata(kv.second);
+    if (values.has_value()) {
+      parsed_index.insert_or_assign(kv.first, values.value());
+    }
+  }
+
+  if (parsed_index.empty()) {
+    return base::nullopt;
+  }
+  return parsed_index;
+}
+
 base::Optional<ParsedPrinters> ParsePrinters(base::StringPiece printers_json) {
   const auto as_value =
       ParseJsonAndUnnestKey(printers_json, "printers", base::Value::Type::LIST);
diff --git a/chromeos/printing/ppd_metadata_parser.h b/chromeos/printing/ppd_metadata_parser.h
index 9ac81f23..77ba4778 100644
--- a/chromeos/printing/ppd_metadata_parser.h
+++ b/chromeos/printing/ppd_metadata_parser.h
@@ -46,11 +46,40 @@
   base::Optional<PpdProvider::Restrictions> restrictions;
 };
 
+// A single leaf value parsed from a forward index.
+struct CHROMEOS_EXPORT ParsedIndexLeaf {
+  ParsedIndexLeaf();
+  ~ParsedIndexLeaf();
+  ParsedIndexLeaf(const ParsedIndexLeaf&);
+  ParsedIndexLeaf& operator=(const ParsedIndexLeaf&);
+
+  std::string ppd_basename;
+  base::Optional<PpdProvider::Restrictions> restrictions;
+};
+
+// A collection of values parsed from a forward index.
+// Corresponds to one effective-make-and-model string.
+struct CHROMEOS_EXPORT ParsedIndexValues {
+  ParsedIndexValues();
+  ~ParsedIndexValues();
+  ParsedIndexValues(const ParsedIndexValues&);
+  ParsedIndexValues& operator=(const ParsedIndexValues&);
+
+  std::vector<ParsedIndexLeaf> values;
+};
+
 // Maps manufacturer names to basenames of printers metadata.
 using ParsedManufacturers = base::flat_map<std::string, std::string>;
 
 using ParsedPrinters = std::vector<ParsedPrinter>;
 
+// *  Keys are effective-make-and-model strings.
+// *  Values collect information corresponding to each
+//    effective-make-and-model string - chiefly information about
+//    individual PPDs.
+// *  Googlers, see also: go/cros-printing:ppd-metadata#index
+using ParsedIndex = base::flat_map<std::string, ParsedIndexValues>;
+
 // Keyed on effective-make-and-model strings.
 using ParsedReverseIndex = base::flat_map<std::string, ReverseIndexLeaf>;
 
@@ -66,6 +95,10 @@
 CHROMEOS_EXPORT base::Optional<ParsedPrinters> ParsePrinters(
     base::StringPiece printers_json);
 
+// Parses |forward_index_json| and returns the parsed map type.
+CHROMEOS_EXPORT base::Optional<ParsedIndex> ParseForwardIndex(
+    base::StringPiece forward_index_json);
+
 // Parses |reverse_index_json| and returns the parsed map type.
 CHROMEOS_EXPORT base::Optional<ParsedReverseIndex> ParseReverseIndex(
     base::StringPiece reverse_index_json);
diff --git a/chromeos/printing/ppd_metadata_parser_unittest.cc b/chromeos/printing/ppd_metadata_parser_unittest.cc
index afe3a2ae..367931f 100644
--- a/chromeos/printing/ppd_metadata_parser_unittest.cc
+++ b/chromeos/printing/ppd_metadata_parser_unittest.cc
@@ -289,6 +289,271 @@
   EXPECT_FALSE(ParsePrinters(kInvalidJson).has_value());
 }
 
+// Verifies that ParseForwardIndex() can parse forward index metadata.
+TEST(PpdMetadataParserTest, CanParseForwardIndex) {
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "der wanderer": {
+      "ppdMetadata": [ {
+        "name": "d-489.ppd.gz"
+      } ]
+    },
+    "morgenlied": {
+      "ppdMetadata": [ {
+        "name": "d-685.ppd.gz"
+      } ]
+    },
+    "wandrers nachtlied": {
+      "ppdMetadata": [ {
+        "name": "d-224.ppd.gz"
+      } ]
+    }
+  }
+})";
+
+  const auto parsed = ParseForwardIndex(kJsonForwardIndex);
+  ASSERT_TRUE(parsed.has_value());
+  EXPECT_THAT(
+      parsed.value(),
+      UnorderedElementsAre(
+          ParsedIndexEntryLike(
+              "der wanderer",
+              UnorderedElementsAre(
+                  ParsedIndexLeafWithPpdBasename("d-489.ppd.gz"))),
+          ParsedIndexEntryLike(
+              "morgenlied", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
+                                "d-685.ppd.gz"))),
+          ParsedIndexEntryLike(
+              "wandrers nachtlied",
+              UnorderedElementsAre(
+                  ParsedIndexLeafWithPpdBasename("d-224.ppd.gz")))));
+}
+
+// Verifies that ParseForwardIndex() can parse forward index metadata
+// and return a partial list even when it encounters unexpected values.
+TEST(PpdMetadataParserTest, CanPartiallyParseForwardIndex) {
+  // Uses the same value as the CanParseForwardIndex test, but
+  // with garbage values mixed in.
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "garbage": "unused value",
+    "more garbage": [ "more", "unused", "values" ],
+    "der wanderer": {
+      "ppdMetadata": [ {
+        "name": "d-489.ppd.gz",
+        "more garbage still": "unused value"
+      }, {
+        "also garbage": "unused value"
+      } ],
+      "unending garbage": "unused value"
+    },
+    "morgenlied": {
+      "ppdMetadata": [ {
+        "name": "d-685.ppd.gz"
+      } ]
+    },
+    "wandrers nachtlied": {
+      "ppdMetadata": [ {
+        "name": "d-224.ppd.gz"
+      } ]
+    }
+  }
+})";
+
+  const auto parsed = ParseForwardIndex(kJsonForwardIndex);
+  ASSERT_TRUE(parsed.has_value());
+  EXPECT_THAT(
+      parsed.value(),
+      UnorderedElementsAre(
+          ParsedIndexEntryLike(
+              "der wanderer",
+              UnorderedElementsAre(
+                  ParsedIndexLeafWithPpdBasename("d-489.ppd.gz"))),
+          ParsedIndexEntryLike(
+              "morgenlied", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
+                                "d-685.ppd.gz"))),
+          ParsedIndexEntryLike(
+              "wandrers nachtlied",
+              UnorderedElementsAre(
+                  ParsedIndexLeafWithPpdBasename("d-224.ppd.gz")))));
+}
+
+// Verifies that ParseForwardIndex() can parse forward index metadata
+// in which leaf values have multiple ppdMetadata key-value pairs.
+TEST(PpdMetadataParserTest, CanParseForwardIndexWithMultiplePpdMetadataLeafs) {
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "rastlose liebe": {
+      "ppdMetadata": [ {
+        "name": "d-138.ppd.gz"
+      }, {
+        "name": "1815.ppd.gz"
+      } ]
+    }
+  }
+})";
+
+  const auto parsed = ParseForwardIndex(kJsonForwardIndex);
+  ASSERT_TRUE(parsed.has_value());
+  EXPECT_THAT(parsed.value(),
+              UnorderedElementsAre(ParsedIndexEntryLike(
+                  "rastlose liebe",
+                  UnorderedElementsAre(
+                      ParsedIndexLeafWithPpdBasename("d-138.ppd.gz"),
+                      ParsedIndexLeafWithPpdBasename("1815.ppd.gz")))));
+}
+
+// Verifies that ParseForwardIndex() can parse forward index metadata
+// and its well-formed restrictions (if any are specified).
+TEST(PpdMetadataParserTest, CanParseForwardIndexWithRestrictions) {
+  // Specifies
+  // *  a PPD metadata leaf with a minimum milestone,
+  // *  a PPD metadata leaf with a maximum milestone, and
+  // *  a PPD metadata leaf with both minimum and maximum milestones.
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "nähe des geliebten": {
+      "ppdMetadata": [ {
+        "name": "d-162.ppd.gz",
+        "restriction": {
+          "minMilestone": 25
+        }
+      } ]
+    },
+    "der fischer": {
+      "ppdMetadata": [ {
+        "name": "d-225.ppd.gz",
+        "restriction": {
+          "maxMilestone": 35
+        }
+      } ]
+    },
+    "erster verlust": {
+      "ppdMetadata": [ {
+        "name": "d-226.ppd.gz",
+        "restriction": {
+          "minMilestone": 45,
+          "maxMilestone": 46
+        }
+      } ]
+    }
+  }
+})";
+
+  const auto parsed = ParseForwardIndex(kJsonForwardIndex);
+  ASSERT_TRUE(parsed.has_value());
+  EXPECT_THAT(parsed.value(),
+              UnorderedElementsAre(
+                  ParsedIndexEntryLike(
+                      "nähe des geliebten",
+                      UnorderedElementsAre(AllOf(
+                          ParsedIndexLeafWithPpdBasename("d-162.ppd.gz"),
+                          Field(&ParsedIndexLeaf::restrictions,
+                                Optional(RestrictionsWithMinMilestone(25)))))),
+                  ParsedIndexEntryLike(
+                      "der fischer",
+                      UnorderedElementsAre(AllOf(
+                          ParsedIndexLeafWithPpdBasename("d-225.ppd.gz"),
+                          Field(&ParsedIndexLeaf::restrictions,
+                                Optional(RestrictionsWithMaxMilestone(35)))))),
+                  ParsedIndexEntryLike(
+                      "erster verlust",
+                      UnorderedElementsAre(AllOf(
+                          ParsedIndexLeafWithPpdBasename("d-226.ppd.gz"),
+                          Field(&ParsedIndexLeaf::restrictions,
+                                Optional(RestrictionsWithMinAndMaxMilestones(
+                                    45, 46))))))));
+}
+
+// Verifies that ParseForwardIndex() can parse forward index metadata
+// and ignore malformed restrictions.
+TEST(PpdMetadataParserTest, CanParseForwardIndexWithMalformedRestrictions) {
+  // Same test data as the CanParseForwardIndexWithRestrictions test
+  // above, but defines
+  // *  a PPD metadata leaf with a malformed minimum milestone,
+  // *  a PPD metadata leaf with a malformed maximum milestone, and
+  // *  a PPD metadata leaf with malformed minimum and maximum
+  //    milestones.
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "nähe des geliebten": {
+      "ppdMetadata": [ {
+        "name": "d-162.ppd.gz",
+        "restriction": {
+          "minMilestone": "garbage value",
+          "maxMilestone": 25
+        }
+      } ]
+    },
+    "der fischer": {
+      "ppdMetadata": [ {
+        "name": "d-225.ppd.gz",
+        "restriction": {
+          "minMilestone": 35,
+          "maxMilestone": "garbage value"
+        }
+      } ]
+    },
+    "erster verlust": {
+      "ppdMetadata": [ {
+        "name": "d-226.ppd.gz",
+        "restriction": {
+          "minMilestone": "garbage value",
+          "maxMilestone": "garbage value"
+        }
+      } ]
+    }
+  }
+})";
+
+  const auto parsed = ParseForwardIndex(kJsonForwardIndex);
+  ASSERT_TRUE(parsed.has_value());
+  EXPECT_THAT(
+      parsed.value(),
+      UnorderedElementsAre(
+          ParsedIndexEntryLike(
+              "nähe des geliebten",
+              UnorderedElementsAre(
+                  AllOf(ParsedIndexLeafWithPpdBasename("d-162.ppd.gz"),
+                        Field(&ParsedIndexLeaf::restrictions,
+                              Optional(RestrictionsWithMaxMilestone(25)))))),
+          ParsedIndexEntryLike(
+              "der fischer",
+              UnorderedElementsAre(
+                  AllOf(ParsedIndexLeafWithPpdBasename("d-225.ppd.gz"),
+                        Field(&ParsedIndexLeaf::restrictions,
+                              Optional(RestrictionsWithMinMilestone(35)))))),
+          ParsedIndexEntryLike(
+              "erster verlust",
+              UnorderedElementsAre(AllOf(
+                  ParsedIndexLeafWithPpdBasename("d-226.ppd.gz"),
+                  Field(&ParsedIndexLeaf::restrictions, Eq(base::nullopt)))))));
+}
+
+// Verifies that ParseForwardIndex() returns base::nullopt rather than
+// an empty container.
+TEST(PpdMetadataParserTest, ParseForwardIndexDoesNotReturnEmptyContainer) {
+  // Specifies a forward index that is valid JSON but which has
+  // no PPDs whose leaf values are non-empty.
+  constexpr base::StringPiece kJsonForwardIndex = R"({
+  "ppdIndex": {
+    "der könig in thule": {
+      "ppdMetadata": [ {
+        "garbage": "unused value"
+      } ]
+    }
+  }
+})";
+
+  EXPECT_FALSE(ParseForwardIndex(kJsonForwardIndex).has_value());
+}
+
+// Verifies that ParseForwardIndex() returns base::nullopt on
+// irrecoverable parse error.
+TEST(PpdMetadataParserTest, ParseForwardIndexFailsGracefully) {
+  EXPECT_FALSE(ParseForwardIndex(kInvalidJson).has_value());
+}
+
 // Verifies that ParseReverseIndex() can parse reverse index metadata.
 TEST(PpdMetadataParserTest, CanParseReverseIndex) {
   constexpr base::StringPiece kReverseIndexJson = R"(
diff --git a/components/autofill_assistant/browser/retry_timer.cc b/components/autofill_assistant/browser/retry_timer.cc
index 3eaf0553..b28f418e 100644
--- a/components/autofill_assistant/browser/retry_timer.cc
+++ b/components/autofill_assistant/browser/retry_timer.cc
@@ -24,8 +24,8 @@
   Reset();
   task_ = std::move(task);
   on_done_ = std::move(on_done);
-  remaining_attempts_ = base::ClampFloor<int64_t>(
-      std::max(0.0, max_wait_time.FltDiv(period_)) + 1.0);
+  remaining_attempts_ =
+      base::ClampFloor<int64_t>(std::max(0.0, max_wait_time / period_) + 1.0);
   RunTask();
 }
 
diff --git a/components/history/core/browser/expire_history_backend.cc b/components/history/core/browser/expire_history_backend.cc
index a36482c..c96520a 100644
--- a/components/history/core/browser/expire_history_backend.cc
+++ b/components/history/core/browser/expire_history_backend.cc
@@ -319,8 +319,8 @@
   if (!expire_visits_time.is_zero()) {
     UMA_HISTOGRAM_PERCENTAGE(
         "History.ExpireVisits.GetRedirectsDurationPercentage",
-        base::ClampRound<base::Histogram::Sample>(
-            get_redirects_time.FltDiv(expire_visits_time) * 100));
+        base::ClampRound<base::Histogram::Sample>(get_redirects_time /
+                                                  expire_visits_time * 100));
   }
 }
 
diff --git a/components/ntp_snippets/category_rankers/click_based_category_ranker.cc b/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
index f6708c6..289e91d 100644
--- a/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
+++ b/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
@@ -455,7 +456,8 @@
   }
   DCHECK_LE(last_decay, now);
 
-  int num_pending_decays = (now - last_decay).IntDiv(kTimeBetweenDecays);
+  int num_pending_decays =
+      base::ClampFloor((now - last_decay) / kTimeBetweenDecays);
   int executed_decays = 0;
   while (executed_decays < num_pending_decays && IsEnoughClicksToDecay()) {
     for (RankedCategory& ranked_category : ordered_categories_) {
diff --git a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc
index 7031059..5fa9bc1 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc
@@ -87,9 +87,9 @@
   int64_t available_quota = statement.ColumnInt64(1);
 
   int64_t remaining_quota =
-      available_quota + base::ClampFloor<int64_t>(
-                            GetMaxDailyQuotaBytes() *
-                            (clock_->Now() - update_time).FltDiv(kQuotaPeriod));
+      available_quota +
+      base::ClampFloor<int64_t>(GetMaxDailyQuotaBytes() *
+                                ((clock_->Now() - update_time) / kQuotaPeriod));
 
   if (remaining_quota < 0)
     SetAvailableQuotaBytes(0);
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn
index 28997d0..85a0ca8 100644
--- a/components/page_info/android/BUILD.gn
+++ b/components/page_info/android/BUILD.gn
@@ -8,8 +8,8 @@
   sources = [
     "certificate_chain_helper.cc",
     "certificate_viewer_android.cc",
-    "connection_info_popup_android.cc",
-    "connection_info_popup_android.h",
+    "connection_info_view_android.cc",
+    "connection_info_view_android.h",
     "features.cc",
     "features.h",
     "page_info_client.cc",
@@ -75,7 +75,7 @@
   sources = [
     "java/src/org/chromium/components/page_info/CertificateChainHelper.java",
     "java/src/org/chromium/components/page_info/CertificateViewer.java",
-    "java/src/org/chromium/components/page_info/ConnectionInfoPopup.java",
+    "java/src/org/chromium/components/page_info/ConnectionInfoView.java",
     "java/src/org/chromium/components/page_info/CookieControlsView.java",
     "java/src/org/chromium/components/page_info/PageInfoConnectionController.java",
     "java/src/org/chromium/components/page_info/PageInfoController.java",
@@ -133,7 +133,7 @@
   sources = [
     "java/src/org/chromium/components/page_info/CertificateChainHelper.java",
     "java/src/org/chromium/components/page_info/CertificateViewer.java",
-    "java/src/org/chromium/components/page_info/ConnectionInfoPopup.java",
+    "java/src/org/chromium/components/page_info/ConnectionInfoView.java",
     "java/src/org/chromium/components/page_info/PageInfoController.java",
     "java/src/org/chromium/components/page_info/PageInfoFeatureList.java",
   ]
diff --git a/components/page_info/android/connection_info_popup_android.cc b/components/page_info/android/connection_info_view_android.cc
similarity index 81%
rename from components/page_info/android/connection_info_popup_android.cc
rename to components/page_info/android/connection_info_view_android.cc
index afca5fa..bcea827 100644
--- a/components/page_info/android/connection_info_popup_android.cc
+++ b/components/page_info/android/connection_info_view_android.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/page_info/android/connection_info_popup_android.h"
+#include "components/page_info/android/connection_info_view_android.h"
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "components/page_info/android/jni_headers/ConnectionInfoPopup_jni.h"
+#include "components/page_info/android/jni_headers/ConnectionInfoView_jni.h"
 #include "components/page_info/android/page_info_client.h"
 #include "components/page_info/page_info.h"
 #include "components/page_info/page_info_delegate.h"
@@ -31,7 +31,7 @@
 using content::WebContents;
 
 // static
-static jlong JNI_ConnectionInfoPopup_Init(
+static jlong JNI_ConnectionInfoView_Init(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj,
     const JavaParamRef<jobject>& java_web_contents) {
@@ -40,10 +40,10 @@
   DCHECK(web_contents);
 
   return reinterpret_cast<intptr_t>(
-      new ConnectionInfoPopupAndroid(env, obj, web_contents));
+      new ConnectionInfoViewAndroid(env, obj, web_contents));
 }
 
-ConnectionInfoPopupAndroid::ConnectionInfoPopupAndroid(
+ConnectionInfoViewAndroid::ConnectionInfoViewAndroid(
     JNIEnv* env,
     jobject java_page_info_pop,
     WebContents* web_contents) {
@@ -64,21 +64,21 @@
   presenter_->InitializeUiState(this);
 }
 
-ConnectionInfoPopupAndroid::~ConnectionInfoPopupAndroid() {}
+ConnectionInfoViewAndroid::~ConnectionInfoViewAndroid() {}
 
-void ConnectionInfoPopupAndroid::Destroy(JNIEnv* env,
-                                         const JavaParamRef<jobject>& obj) {
+void ConnectionInfoViewAndroid::Destroy(JNIEnv* env,
+                                        const JavaParamRef<jobject>& obj) {
   delete this;
 }
 
-void ConnectionInfoPopupAndroid::ResetCertDecisions(
+void ConnectionInfoViewAndroid::ResetCertDecisions(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj,
     const JavaParamRef<jobject>& java_web_contents) {
   presenter_->OnRevokeSSLErrorBypassButtonPressed();
 }
 
-void ConnectionInfoPopupAndroid::SetIdentityInfo(
+void ConnectionInfoViewAndroid::SetIdentityInfo(
     const IdentityInfo& identity_info) {
   JNIEnv* env = base::android::AttachCurrentThread();
 
@@ -108,14 +108,14 @@
           l10n_util::GetStringUTF16(IDS_PAGE_INFO_CERT_INFO_BUTTON);
     }
 
-    Java_ConnectionInfoPopup_addCertificateSection(
+    Java_ConnectionInfoView_addCertificateSection(
         env, popup_jobject_, icon_id, ConvertUTF8ToJavaString(env, headline),
         description, ConvertUTF16ToJavaString(env, certificate_label));
 
     if (identity_info.show_ssl_decision_revoke_button) {
       base::string16 reset_button_label = l10n_util::GetStringUTF16(
           IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON);
-      Java_ConnectionInfoPopup_addResetCertDecisionsButton(
+      Java_ConnectionInfoView_addResetCertDecisionsButton(
           env, popup_jobject_,
           ConvertUTF16ToJavaString(env, reset_button_label));
     }
@@ -127,28 +127,28 @@
 
     ScopedJavaLocalRef<jstring> description = ConvertUTF8ToJavaString(
         env, identity_info.connection_status_description);
-    Java_ConnectionInfoPopup_addDescriptionSection(env, popup_jobject_, icon_id,
-                                                   nullptr, description);
+    Java_ConnectionInfoView_addDescriptionSection(env, popup_jobject_, icon_id,
+                                                  nullptr, description);
   }
 
-  Java_ConnectionInfoPopup_addMoreInfoLink(
+  Java_ConnectionInfoView_addMoreInfoLink(
       env, popup_jobject_,
       ConvertUTF8ToJavaString(
           env, l10n_util::GetStringUTF8(IDS_PAGE_INFO_HELP_CENTER_LINK)));
-  Java_ConnectionInfoPopup_showDialog(env, popup_jobject_);
+  Java_ConnectionInfoView_onReady(env, popup_jobject_);
 }
 
-void ConnectionInfoPopupAndroid::SetCookieInfo(
+void ConnectionInfoViewAndroid::SetCookieInfo(
     const CookieInfoList& cookie_info_list) {
   NOTIMPLEMENTED();
 }
 
-void ConnectionInfoPopupAndroid::SetPageFeatureInfo(
+void ConnectionInfoViewAndroid::SetPageFeatureInfo(
     const PageFeatureInfo& info) {
   NOTIMPLEMENTED();
 }
 
-void ConnectionInfoPopupAndroid::SetPermissionInfo(
+void ConnectionInfoViewAndroid::SetPermissionInfo(
     const PermissionInfoList& permission_info_list,
     ChosenObjectInfoList chosen_object_info_list) {
   NOTIMPLEMENTED();
diff --git a/components/page_info/android/connection_info_popup_android.h b/components/page_info/android/connection_info_view_android.h
similarity index 74%
rename from components/page_info/android/connection_info_popup_android.h
rename to components/page_info/android/connection_info_view_android.h
index 742dfb7..1202d45 100644
--- a/components/page_info/android/connection_info_popup_android.h
+++ b/components/page_info/android/connection_info_view_android.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 COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_POPUP_ANDROID_H_
-#define COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_POPUP_ANDROID_H_
+#ifndef COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_VIEW_ANDROID_H_
+#define COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_VIEW_ANDROID_H_
 
 #include <jni.h>
 
@@ -23,12 +23,12 @@
 
 // Android implementation of the page info UI which displays detailed
 // connection and certificate information for the website.
-class ConnectionInfoPopupAndroid : public PageInfoUI {
+class ConnectionInfoViewAndroid : public PageInfoUI {
  public:
-  ConnectionInfoPopupAndroid(JNIEnv* env,
-                             jobject java_page_info,
-                             content::WebContents* web_contents);
-  ~ConnectionInfoPopupAndroid() override;
+  ConnectionInfoViewAndroid(JNIEnv* env,
+                            jobject java_page_info,
+                            content::WebContents* web_contents);
+  ~ConnectionInfoViewAndroid() override;
   void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
 
   // Revokes any current user exceptions for bypassing SSL error interstitials
@@ -55,7 +55,7 @@
   // The java prompt implementation.
   base::android::ScopedJavaGlobalRef<jobject> popup_jobject_;
 
-  DISALLOW_COPY_AND_ASSIGN(ConnectionInfoPopupAndroid);
+  DISALLOW_COPY_AND_ASSIGN(ConnectionInfoViewAndroid);
 };
 
-#endif  // COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_POPUP_ANDROID_H_s
+#endif  // COMPONENTS_PAGE_INFO_ANDROID_CONNECTION_INFO_VIEW_ANDROID_H_s
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoPopup.java b/components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoView.java
similarity index 62%
rename from components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoPopup.java
rename to components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoView.java
index 6d15ce5..d1d4167d 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoPopup.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/ConnectionInfoView.java
@@ -33,21 +33,19 @@
 /**
  * Java side of Android implementation of the page info UI.
  */
-public class ConnectionInfoPopup implements OnClickListener, ModalDialogProperties.Controller {
-    private static final String TAG = "ConnectionInfoPopup";
+public class ConnectionInfoView implements OnClickListener {
+    private static final String TAG = "ConnectionInfoView";
 
     private static final String HELP_URL =
             "https://support.google.com/chrome?p=android_connection_info";
 
     private final Context mContext;
-    private final ModalDialogManager mModalDialogManager;
-    private PropertyModel mDialogModel;
+    private ConnectionInfoDelegate mDelegate;
     private final LinearLayout mContainer;
     private final WebContents mWebContents;
-    private final WebContentsObserver mWebContentsObserver;
     private final int mPaddingWide;
     private final int mPaddingThin;
-    private final long mNativeConnectionInfoPopup;
+    private final long mNativeConnectionInfoView;
     private final CertificateViewer mCertificateViewer;
     private TextView mCertificateViewerTextView;
     private TextView mMoreInfoLink;
@@ -57,10 +55,26 @@
     private String mLinkUrl;
     private VrHandler mVrHandler;
 
-    private ConnectionInfoPopup(Context context, WebContents webContents,
-            ModalDialogManager modalDialogManager, VrHandler vrHandler) {
+    /**
+     * Delegate that embeds the ConnectionInfoView. Must call ConnectionInfoView::onDismiss when
+     * the embedding view is removed.
+     */
+    interface ConnectionInfoDelegate {
+        /**
+         * Called when the ConnectionInfoView is initialized
+         */
+        void onReady(ConnectionInfoView popup);
+
+        /**
+         * Called in order to dismiss the dialog or page that is showing the ConnectionInfoView.
+         */
+        void dismiss(int actionOnContent);
+    }
+
+    private ConnectionInfoView(Context context, WebContents webContents,
+            ConnectionInfoDelegate delegate, VrHandler vrHandler) {
         mContext = context;
-        mModalDialogManager = modalDialogManager;
+        mDelegate = delegate;
         mWebContents = webContents;
         mVrHandler = vrHandler;
 
@@ -76,21 +90,7 @@
                 mPaddingWide, mPaddingWide, mPaddingWide, mPaddingWide - mPaddingThin);
 
         // This needs to come after other member initialization.
-        mNativeConnectionInfoPopup = ConnectionInfoPopupJni.get().init(this, mWebContents);
-        mWebContentsObserver = new WebContentsObserver(mWebContents) {
-            @Override
-            public void navigationEntryCommitted() {
-                // If a navigation is committed (e.g. from in-page redirect), the data we're
-                // showing is stale so dismiss the dialog.
-                dismissDialog(DialogDismissalCause.UNKNOWN);
-            }
-
-            @Override
-            public void destroy() {
-                super.destroy();
-                dismissDialog(DialogDismissalCause.UNKNOWN);
-            }
-        };
+        mNativeConnectionInfoView = ConnectionInfoViewJni.get().init(this, mWebContents);
     }
 
     /**
@@ -147,10 +147,6 @@
         mCertificateLayout.addView(mCertificateViewerTextView);
     }
 
-    private void dismissDialog(@DialogDismissalCause int dismissalCause) {
-        mModalDialogManager.dismissDialog(mDialogModel, dismissalCause);
-    }
-
     @CalledByNative
     private void addResetCertDecisionsButton(String label) {
         assert mResetCertDecisionsButton == null;
@@ -178,27 +174,18 @@
         mDescriptionLayout.addView(mMoreInfoLink);
     }
 
-    /** Displays the ConnectionInfoPopup. */
+    /** Displays the ConnectionInfoView. */
     @CalledByNative
-    private void showDialog() {
-        ScrollView scrollView = new ScrollView(mContext);
-        scrollView.addView(mContainer);
-
-        mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
-                               .with(ModalDialogProperties.CONTROLLER, this)
-                               .with(ModalDialogProperties.CUSTOM_VIEW, scrollView)
-                               .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true)
-                               .build();
-
-        mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.APP, true);
+    private void onReady() {
+        mDelegate.onReady(this);
     }
 
     @Override
     public void onClick(View v) {
         if (mResetCertDecisionsButton == v) {
-            ConnectionInfoPopupJni.get().resetCertDecisions(
-                    mNativeConnectionInfoPopup, ConnectionInfoPopup.this, mWebContents);
-            dismissDialog(DialogDismissalCause.ACTION_ON_CONTENT);
+            ConnectionInfoViewJni.get().resetCertDecisions(
+                    mNativeConnectionInfoView, ConnectionInfoView.this, mWebContents);
+            mDelegate.dismiss(DialogDismissalCause.ACTION_ON_CONTENT);
         } else if (mCertificateViewerTextView == v) {
             byte[][] certChain = CertificateChainHelper.getCertificateChain(mWebContents);
             if (certChain == null) {
@@ -223,19 +210,25 @@
         }
     }
 
-    @Override
-    public void onClick(PropertyModel model, int buttonType) {}
+    /**
+     * @return The view containing connection info.
+     */
+    public View getView() {
+        return mContainer;
+    }
 
-    @Override
-    public void onDismiss(PropertyModel model, int dismissalCause) {
-        assert mNativeConnectionInfoPopup != 0;
-        mWebContentsObserver.destroy();
-        ConnectionInfoPopupJni.get().destroy(mNativeConnectionInfoPopup, ConnectionInfoPopup.this);
-        mDialogModel = null;
+    /**
+     * Called when the embedding view is removed.
+     */
+    public void onDismiss() {
+        assert mNativeConnectionInfoView != 0;
+        org.chromium.components.page_info.ConnectionInfoViewJni.get().destroy(
+                mNativeConnectionInfoView, ConnectionInfoView.this);
     }
 
     private void showConnectionSecurityInfo() {
-        dismissDialog(DialogDismissalCause.ACTION_ON_CONTENT);
+        // TODO(crbug.com/1077766): We probably don't want to dismiss the new PageInfo UI here?
+        mDelegate.dismiss(DialogDismissalCause.ACTION_ON_CONTENT);
         try {
             Intent i = Intent.parseUri(mLinkUrl, Intent.URI_INTENT_SCHEME);
             i.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
@@ -247,6 +240,66 @@
         }
     }
 
+    static class ConnectionInfoDialogDelegate
+            implements ConnectionInfoDelegate, ModalDialogProperties.Controller {
+        private ConnectionInfoView mPopup;
+        private PropertyModel mDialogModel;
+        private final ModalDialogManager mModalDialogManager;
+        private WebContents mWebContents;
+        private final WebContentsObserver mWebContentsObserver;
+
+        ConnectionInfoDialogDelegate(
+                ModalDialogManager modalDialogManager, WebContents webContents) {
+            mModalDialogManager = modalDialogManager;
+            mWebContents = webContents;
+            mWebContentsObserver = new WebContentsObserver(mWebContents) {
+                @Override
+                public void navigationEntryCommitted() {
+                    // If a navigation is committed (e.g. from in-page redirect), the data we're
+                    // showing is stale so dismiss the dialog.
+                    dismiss(DialogDismissalCause.UNKNOWN);
+                }
+
+                @Override
+                public void destroy() {
+                    super.destroy();
+                    dismiss(DialogDismissalCause.UNKNOWN);
+                }
+            };
+        }
+
+        @Override
+        public void onClick(PropertyModel model, int buttonType) {}
+
+        @Override
+        public void dismiss(@DialogDismissalCause int dismissalCause) {
+            mModalDialogManager.dismissDialog(mDialogModel, dismissalCause);
+        }
+
+        @Override
+        public void onDismiss(PropertyModel model, @DialogDismissalCause int dismissalCause) {
+            mPopup.onDismiss();
+            mWebContentsObserver.destroy();
+            mDialogModel = null;
+        }
+
+        @Override
+        public void onReady(ConnectionInfoView popup) {
+            mPopup = popup;
+            ScrollView scrollView = new ScrollView(popup.mContext);
+            scrollView.addView(popup.getView());
+
+            mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
+                                   .with(ModalDialogProperties.CONTROLLER, this)
+                                   .with(ModalDialogProperties.CUSTOM_VIEW, scrollView)
+                                   .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true)
+                                   .build();
+
+            mModalDialogManager.showDialog(
+                    mDialogModel, ModalDialogManager.ModalDialogType.APP, true);
+        }
+    }
+
     /**
      * Shows a connection info dialog for the provided WebContents.
      *
@@ -258,14 +311,20 @@
      */
     public static void show(Context context, WebContents webContents,
             ModalDialogManager modalDialogManager, VrHandler vrHandler) {
-        new ConnectionInfoPopup(context, webContents, modalDialogManager, vrHandler);
+        new ConnectionInfoView(context, webContents,
+                new ConnectionInfoDialogDelegate(modalDialogManager, webContents), vrHandler);
+    }
+
+    public static ConnectionInfoView create(Context context, WebContents webContents,
+            ConnectionInfoDelegate delegate, VrHandler vrHandler) {
+        return new ConnectionInfoView(context, webContents, delegate, vrHandler);
     }
 
     @NativeMethods
     interface Natives {
-        long init(ConnectionInfoPopup popup, WebContents webContents);
-        void destroy(long nativeConnectionInfoPopupAndroid, ConnectionInfoPopup caller);
-        void resetCertDecisions(long nativeConnectionInfoPopupAndroid, ConnectionInfoPopup caller,
+        long init(ConnectionInfoView popup, WebContents webContents);
+        void destroy(long nativeConnectionInfoViewAndroid, ConnectionInfoView caller);
+        void resetCertDecisions(long nativeConnectionInfoViewAndroid, ConnectionInfoView caller,
                 WebContents webContents);
     }
 }
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoConnectionController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoConnectionController.java
index f70d59d..d1a51aa 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoConnectionController.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoConnectionController.java
@@ -6,18 +6,28 @@
 
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import org.chromium.content_public.browser.WebContents;
 
 /**
  * Class for controlling the page info connection section.
  */
-public class PageInfoConnectionController implements PageInfoSubpageController {
+public class PageInfoConnectionController
+        implements PageInfoSubpageController, ConnectionInfoView.ConnectionInfoDelegate {
     private PageInfoMainPageController mMainController;
+    private final WebContents mWebContents;
+    private final VrHandler mVrHandler;
     private PageInfoRowView mRowView;
     private String mTitle;
+    private ConnectionInfoView mInfoView;
+    private ViewGroup mContainer;
 
-    public PageInfoConnectionController(
-            PageInfoMainPageController mainController, PageInfoRowView view) {
+    public PageInfoConnectionController(PageInfoMainPageController mainController,
+            PageInfoRowView view, WebContents webContents, VrHandler vrHandler) {
         mMainController = mainController;
+        mWebContents = webContents;
+        mVrHandler = vrHandler;
         mRowView = view;
     }
 
@@ -32,15 +42,20 @@
 
     @Override
     public View createViewForSubpage(ViewGroup parent) {
-        // TODO(crbug.com/1077766): Create and set the connection specific view.
-        return null;
+        mContainer = new FrameLayout(mRowView.getContext());
+        mInfoView =
+                ConnectionInfoView.create(mRowView.getContext(), mWebContents, this, mVrHandler);
+        return mContainer;
     }
 
     @Override
     public void onSubPageAttached() {}
 
     @Override
-    public void onSubpageRemoved() {}
+    public void onSubpageRemoved() {
+        mContainer = null;
+        mInfoView.onDismiss();
+    }
 
     public void setConnectionInfo(PageInfoView.ConnectionInfoParams params) {
         mTitle = params.summary != null ? params.summary.toString() : null;
@@ -51,4 +66,16 @@
         rowParams.clickCallback = this::launchSubpage;
         mRowView.setParams(rowParams);
     }
+
+    @Override
+    public void onReady(ConnectionInfoView infoView) {
+        if (mContainer != null) {
+            mContainer.addView(infoView.getView());
+        }
+    }
+
+    @Override
+    public void dismiss(int actionOnContent) {
+        mMainController.exitSubpage();
+    }
 }
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
index 5e150d3..cae527c 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
@@ -267,8 +267,8 @@
             mSubpage = new PageInfoSubpage(mContext);
             mSubpage.setBackButtonOnClickListener(view -> exitSubpage());
             PageInfoViewV2 view2 = (PageInfoViewV2) mView;
-            mConnectionController =
-                    new PageInfoConnectionController(this, view2.getConnectionRowView());
+            mConnectionController = new PageInfoConnectionController(
+                    this, view2.getConnectionRowView(), mWebContents, mDelegate.getVrHandler());
             mPermissionsController = new PageInfoPermissionsController(
                     this, view2.getPermissionsRowView(), mDelegate, mDisplayUrlBuilder.toString());
             mCookiesController = new PageInfoCookiesController(
@@ -426,7 +426,7 @@
                 runAfterDismiss(() -> {
                     if (!mWebContents.isDestroyed()) {
                         recordAction(PageInfoAction.PAGE_INFO_SECURITY_DETAILS_OPENED);
-                        ConnectionInfoPopup.show(mContext, mWebContents,
+                        ConnectionInfoView.show(mContext, mWebContents,
                                 mDelegate.getModalDialogManager(), mDelegate.getVrHandler());
                     }
                 });
@@ -569,7 +569,7 @@
     }
 
     /**
-     * Launches a subpage with the specified params.
+     * Launches a subpage for the specified controller.
      */
     @Override
     public void launchSubpage(PageInfoSubpageController controller) {
@@ -581,39 +581,26 @@
         mSubpage.updateSubpage(subpageParams);
         View subview = mSubpageController.createViewForSubpage(mSubpage);
 
-        if (subview != null) {
-            ((FrameLayout) mSubpage.findViewById(R.id.placeholder)).addView(subview);
-        }
+        ((FrameLayout) mSubpage.findViewById(R.id.placeholder)).addView(subview);
         replaceView(mView, mSubpage);
         controller.onSubPageAttached();
     }
 
-    private ViewGroup getParent(View view) {
-        return (ViewGroup) view.getParent();
-    }
-
-    private void removeView(View view) {
-        ViewGroup parent = getParent(view);
-        if (parent != null) {
-            parent.removeView(view);
-        }
-    }
-
-    private void replaceView(View currentView, View newView) {
-        ViewGroup parent = getParent(currentView);
-        if (parent == null) {
-            return;
-        }
-        final int index = parent.indexOfChild(currentView);
-        removeView(currentView);
-        removeView(newView);
-        parent.addView(newView, index);
-    }
-
     @Override
     public void exitSubpage() {
         replaceView(mSubpage, mView);
+        ((FrameLayout) mSubpage.findViewById(R.id.placeholder)).removeAllViews();
         mSubpageController.onSubpageRemoved();
         mSubpageController = null;
     }
+
+    private void replaceView(View currentView, View newView) {
+        assert currentView.getParent() != null;
+        assert newView.getParent() == null;
+
+        ViewGroup parent = (ViewGroup) currentView.getParent();
+        final int index = parent.indexOfChild(currentView);
+        parent.removeView(currentView);
+        parent.addView(newView, index);
+    }
 }
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index 792319e0..1121e30 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -395,6 +395,13 @@
 }
 
 if (is_android) {
+  # Wrap the java_cpp_enum in android_library so it can be used by both
+  # chrome_java and modules.
+  android_library("password_manager_java_enums") {
+    deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ]
+    srcjar_deps = [ ":password_manager_java_enums_srcjar" ]
+  }
+
   java_cpp_enum("password_manager_java_enums_srcjar") {
     sources = [
       "biometric_authenticator.h",
diff --git a/components/prerender/browser/BUILD.gn b/components/prerender/browser/BUILD.gn
index d28b73c..2c8615f 100644
--- a/components/prerender/browser/BUILD.gn
+++ b/components/prerender/browser/BUILD.gn
@@ -6,10 +6,12 @@
   sources = [
     "prerender_config.cc",
     "prerender_config.h",
+    "prerender_contents_delegate.h",
     "prerender_histograms.cc",
     "prerender_histograms.h",
     "prerender_history.cc",
     "prerender_history.h",
+    "prerender_manager_delegate.h",
     "prerender_util.cc",
     "prerender_util.h",
   ]
@@ -18,6 +20,7 @@
     "//components/google/core/common",
     "//components/prerender/common",
     "//components/prerender/common:mojo_bindings",
+    "//content/public/browser",
     "//net",
     "//ui/gfx/geometry",
     "//ui/gfx/image/mojom:mojom_traits",
diff --git a/components/prerender/browser/DEPS b/components/prerender/browser/DEPS
index 7749285..affa3cd 100644
--- a/components/prerender/browser/DEPS
+++ b/components/prerender/browser/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+components/google/core/common",
+  "+content/public/browser",
   "+net/http/http_cache.h",
   "+ui/gfx/geometry/rect.h",
 ]
diff --git a/chrome/browser/prerender/prerender_contents_delegate.h b/components/prerender/browser/prerender_contents_delegate.h
similarity index 80%
rename from chrome/browser/prerender/prerender_contents_delegate.h
rename to components/prerender/browser/prerender_contents_delegate.h
index df22257..4d684c2 100644
--- a/chrome/browser/prerender/prerender_contents_delegate.h
+++ b/components/prerender/browser/prerender_contents_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_DELEGATE_H_
-#define CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_DELEGATE_H_
+#ifndef COMPONENTS_PRERENDER_BROWSER_PRERENDER_CONTENTS_DELEGATE_H_
+#define COMPONENTS_PRERENDER_BROWSER_PRERENDER_CONTENTS_DELEGATE_H_
 
 #include "components/prerender/common/prerender_types.mojom.h"
 #include "content/public/browser/render_frame_host.h"
@@ -30,4 +30,4 @@
 
 }  // namespace prerender
 
-#endif  // CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_DELEGATE_H_
+#endif  // COMPONENTS_PRERENDER_BROWSER_PRERENDER_CONTENTS_DELEGATE_H_
diff --git a/components/prerender/browser/prerender_manager_delegate.h b/components/prerender/browser/prerender_manager_delegate.h
new file mode 100644
index 0000000..85ebd6a
--- /dev/null
+++ b/components/prerender/browser/prerender_manager_delegate.h
@@ -0,0 +1,51 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRERENDER_BROWSER_PRERENDER_MANAGER_DELEGATE_H_
+#define COMPONENTS_PRERENDER_BROWSER_PRERENDER_MANAGER_DELEGATE_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "components/prerender/browser/prerender_contents_delegate.h"
+#include "components/prerender/common/prerender_origin.h"
+#include "url/gurl.h"
+
+namespace content_settings {
+class CookieSettings;
+}
+
+namespace prerender {
+
+// PrerenderManagerDelegate allows content embedders to override
+// PrerenderManager logic.
+class PrerenderManagerDelegate {
+ public:
+  virtual ~PrerenderManagerDelegate() = default;
+
+  // Checks whether third party cookies should be blocked.
+  virtual scoped_refptr<content_settings::CookieSettings>
+  GetCookieSettings() = 0;
+
+  // Perform preconnect, if feasible.
+  virtual void MaybePreconnect(const GURL& url) = 0;
+
+  // Get the prerender contents delegate.
+  virtual std::unique_ptr<PrerenderContentsDelegate>
+  GetPrerenderContentsDelegate() = 0;
+
+  // Check whether predictive loading of web pages is enabled for |origin|.
+  virtual bool IsPredictionEnabled(Origin origin) = 0;
+
+  // Check whether predictive loading of web pages is enabled.
+  virtual bool IsPredictionEnabled() = 0;
+
+  // Check whether predictive loading of web pages is disabled due to network.
+  virtual bool IsPredictionDisabledDueToNetwork(Origin origin) = 0;
+
+  // Gets the reason why predictive loading of web pages was disabld.
+  virtual std::string GetReasonForDisablingPrediction() = 0;
+};
+
+}  // namespace prerender
+
+#endif  // COMPONENTS_PRERENDER_BROWSER_PRERENDER_MANAGER_DELEGATE_H_
diff --git a/components/resources/android/page_info_resource_id.h b/components/resources/android/page_info_resource_id.h
index f1612bd..64f127a 100644
--- a/components/resources/android/page_info_resource_id.h
+++ b/components/resources/android/page_info_resource_id.h
@@ -22,7 +22,7 @@
 #error "DECLARE_RESOURCE_ID should be defined before including this file"
 #endif
 
-// PageInfoUI images, used in ConnectionInfoPopup
+// PageInfoUI images, used in ConnectionInfoView
 // Good:
 DECLARE_RESOURCE_ID(IDR_PAGEINFO_GOOD, R.drawable.pageinfo_good)
 // Warnings:
diff --git a/components/services/storage/public/mojom/service_worker_storage_control.mojom b/components/services/storage/public/mojom/service_worker_storage_control.mojom
index 7eed376..f653334 100644
--- a/components/services/storage/public/mojom/service_worker_storage_control.mojom
+++ b/components/services/storage/public/mojom/service_worker_storage_control.mojom
@@ -93,6 +93,7 @@
 // lifetime of user data is tied up with the registration.
 // It will be deleted when the corresponding registration is deleted.
 struct ServiceWorkerUserData {
+  int64 registration_id;
   string key;
   string value;
 };
@@ -140,15 +141,25 @@
        array<ServiceWorkerRegistrationData> registrations);
 
   // Stores |registration_data| and |resources|.
+  // TODO(crbug.com/1055677): Stop returning |deleted_version_id| and
+  // |newly_purgeable_resources|. These are used to schedule resource purging
+  // in the browser process, but it should be done in the Storage Service.
   StoreRegistration(ServiceWorkerRegistrationData registration,
                     array<ServiceWorkerResourceRecord> resources) =>
-      (ServiceWorkerDatabaseStatus status);
+      (ServiceWorkerDatabaseStatus status,
+       int64 deleted_version_id,
+       array<int64> newly_purgeable_resources);
 
   // Deletes the registration specified by |registration_id|. |origin_state| is
   // kDelete if there is no registration for |origin| after deletion.
+  // TODO(crbug.com/1055677): Stop returning |deleted_version_id| and
+  // |newly_purgeable_resources|. These are used to schedule resource purging
+  // in the browser process, but it should be done in the Storage Service.
   DeleteRegistration(int64 registration_id, url.mojom.Url origin) =>
       (ServiceWorkerDatabaseStatus status,
-       ServiceWorkerStorageOriginState origin_state);
+       ServiceWorkerStorageOriginState origin_state,
+       int64 deleted_version_id,
+       array<int64> newly_purgeable_resources);
 
   // Updates the state of the registration's stored version to active.
   UpdateToActiveState(int64 registration_id, url.mojom.Url origin) =>
@@ -238,14 +249,14 @@
       (ServiceWorkerDatabaseStatus status);
 
   // Gets the user data from all registrations that have user data for |key|.
-  // Returns a map from registration IDs to their values.
   GetUserDataForAllRegistrations(string key) =>
-      (ServiceWorkerDatabaseStatus status, map<int64, string> values);
+      (ServiceWorkerDatabaseStatus status,
+       array<ServiceWorkerUserData> values);
   // Gets the user data from all registrations that have user data for
-  // |key_prefix| where |key_prefix| is a prefix of keys. Returns a map from
-  // registration IDs to their values.
+  // |key_prefix| where |key_prefix| is a prefix of keys.
   GetUserDataForAllRegistrationsByKeyPrefix(string key_prefix) =>
-      (ServiceWorkerDatabaseStatus status, map<int64, string> values);
+      (ServiceWorkerDatabaseStatus status,
+       array<ServiceWorkerUserData> values);
   // Clears the user data from all registrations using |key_prefix| as a prefix
   // of keys.
   ClearUserDataForAllRegistrationsByKeyPrefix(string key_prefix) =>
diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc
index a9ac4739..9c57f33 100644
--- a/components/viz/common/frame_sinks/begin_frame_source.cc
+++ b/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -15,6 +15,7 @@
 #include "base/check_op.h"
 #include "base/location.h"
 #include "base/notreached.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
@@ -131,9 +132,8 @@
   // deadlines.
   constexpr double kErrorMarginIntervalPct = 0.05;
   base::TimeDelta error_margin = vsync_interval * kErrorMarginIntervalPct;
-  int ticks_since_estimated_frame_time =
-      (frame_time + error_margin - next_expected_frame_time)
-          .IntDiv(vsync_interval);
+  int ticks_since_estimated_frame_time = base::ClampFloor(
+      (frame_time + error_margin - next_expected_frame_time) / vsync_interval);
   return std::max(0, ticks_since_estimated_frame_time);
 }
 
diff --git a/content/browser/appcache/appcache_update_job_unittest.cc b/content/browser/appcache/appcache_update_job_unittest.cc
index e38e11f6..3b4ebe3f 100644
--- a/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/content/browser/appcache/appcache_update_job_unittest.cc
@@ -690,9 +690,7 @@
         interceptor_(
             base::BindRepeating(&AppCacheUpdateJobTest::InterceptRequest,
                                 base::Unretained(this))),
-        process_id_(123),
-        weak_partition_factory_(static_cast<StoragePartitionImpl*>(
-            BrowserContext::GetDefaultStoragePartition(&browser_context_))) {
+        process_id_(123) {
     appcache_require_origin_trial_feature_.InitAndDisableFeature(
         blink::features::kAppCacheRequireOriginTrial);
   }
@@ -747,13 +745,23 @@
   }
 
   void SetUp() override {
+    browser_context_ = std::make_unique<content::TestBrowserContext>();
+    weak_partition_factory_ =
+        std::make_unique<base::WeakPtrFactory<StoragePartitionImpl>>(
+            static_cast<StoragePartitionImpl*>(
+                BrowserContext::GetDefaultStoragePartition(
+                    browser_context_.get())));
+
     ChildProcessSecurityPolicyImpl::GetInstance()->Add(process_id_,
-                                                       &browser_context_);
+                                                       browser_context_.get());
     blink::TrialTokenValidator::SetOriginTrialPolicyGetter(base::BindRepeating(
         []() -> blink::OriginTrialPolicy* { return &g_origin_trial_policy; }));
   }
 
   void TearDown() override {
+    weak_partition_factory_.reset();
+    browser_context_.reset();
+
     ChildProcessSecurityPolicyImpl::GetInstance()->Remove(process_id_);
   }
   // Use a separate IO thread to run a test. Thread will be destroyed
@@ -3818,14 +3826,10 @@
   }
 
   void RequestResponseTimesAreModifiedTest() {
-    base::test::ScopedFeatureList f;
-    f.InitAndEnableFeature(kAppCacheUpdateResourceOn304Feature);
     RequestResponseTimesModified(/*feature_enabled=*/true);
   }
 
   void RequestResponseTimesAreNotModifiedTest() {
-    base::test::ScopedFeatureList f;
-    f.InitAndDisableFeature(kAppCacheUpdateResourceOn304Feature);
     RequestResponseTimesModified(/*feature_enabled=*/false);
   }
 
@@ -4242,7 +4246,7 @@
 
   void MakeService() {
     service_ = std::make_unique<MockAppCacheService>(
-        weak_partition_factory_.GetWeakPtr());
+        weak_partition_factory_->GetWeakPtr());
   }
 
   AppCache* MakeCacheForGroup(int64_t cache_id, int64_t manifest_response_id) {
@@ -5094,7 +5098,6 @@
   AppCache::EntryMap expect_extra_entries_;
   std::map<GURL, int64_t> expect_response_ids_;
 
-  content::TestBrowserContext browser_context_;
   URLLoaderInterceptor interceptor_;
   const int process_id_;
   std::map<GURL, std::unique_ptr<HttpHeadersRequestTestJob>>
@@ -5102,7 +5105,44 @@
 
   base::test::ScopedFeatureList appcache_require_origin_trial_feature_;
 
-  base::WeakPtrFactory<StoragePartitionImpl> weak_partition_factory_;
+  // Lazily create these to avoid data races in the FeatureList between
+  // service workers (reading) and appcache tests (writing).
+  std::unique_ptr<content::TestBrowserContext> browser_context_;
+  std::unique_ptr<base::WeakPtrFactory<StoragePartitionImpl>>
+      weak_partition_factory_;
+};
+
+class AppCacheUpdateJobOriginTrialTest : public AppCacheUpdateJobTest {
+ public:
+  AppCacheUpdateJobOriginTrialTest() {
+    scoped_feature_list_.InitAndEnableFeature(
+        blink::features::kAppCacheRequireOriginTrial);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+class AppCacheUpdateJobUpdateOn304Test : public AppCacheUpdateJobTest {
+ public:
+  AppCacheUpdateJobUpdateOn304Test() {
+    scoped_feature_list_.InitAndEnableFeature(
+        kAppCacheUpdateResourceOn304Feature);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+class AppCacheUpdateJobNoUpdateOn304Test : public AppCacheUpdateJobTest {
+ public:
+  AppCacheUpdateJobNoUpdateOn304Test() {
+    scoped_feature_list_.InitAndDisableFeature(
+        kAppCacheUpdateResourceOn304Feature);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(AppCacheUpdateJobTest, AlreadyChecking) {
@@ -5194,21 +5234,15 @@
   RunTestOnUIThread(&AppCacheUpdateJobTest::ManifestMissingMimeTypeTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, ManifestNotFound) {
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
+TEST_F(AppCacheUpdateJobOriginTrialTest, ManifestNotFound) {
   RunTestOnUIThread(&AppCacheUpdateJobTest::ManifestNotFoundTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, ManifestGoneFetch) {
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
+TEST_F(AppCacheUpdateJobOriginTrialTest, ManifestGoneFetch) {
   RunTestOnUIThread(&AppCacheUpdateJobTest::ManifestGoneFetchTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, ManifestGoneUpgrade) {
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
+TEST_F(AppCacheUpdateJobOriginTrialTest, ManifestGoneUpgrade) {
   RunTestOnUIThread(&AppCacheUpdateJobTest::ManifestGoneUpgradeTest);
 }
 
@@ -5414,9 +5448,7 @@
   RunTestOnUIThread(&AppCacheUpdateJobTest::UpgradeFailStoreNewestCacheTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, UpgradeFailMakeGroupObsolete) {
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
+TEST_F(AppCacheUpdateJobOriginTrialTest, UpgradeFailMakeGroupObsolete) {
   RunTestOnUIThread(&AppCacheUpdateJobTest::UpgradeFailMakeGroupObsoleteTest);
 }
 
@@ -5508,12 +5540,12 @@
   RunTestOnUIThread(&AppCacheUpdateJobTest::RequestResponseTimesAreSetTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, RequestResponseTimesAreModified) {
+TEST_F(AppCacheUpdateJobUpdateOn304Test, RequestResponseTimesAreModified) {
   RunTestOnUIThread(
       &AppCacheUpdateJobTest::RequestResponseTimesAreModifiedTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, RequestResponseTimesAreNotModified) {
+TEST_F(AppCacheUpdateJobNoUpdateOn304Test, RequestResponseTimesAreNotModified) {
   RunTestOnUIThread(
       &AppCacheUpdateJobTest::RequestResponseTimesAreNotModifiedTest);
 }
@@ -5534,23 +5566,18 @@
   RunTestOnUIThread(&AppCacheUpdateJobTest::CrossOriginHttpsDeniedTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, OriginTrialUpdateWithFeature) {
+TEST_F(AppCacheUpdateJobOriginTrialTest, OriginTrialUpdateWithFeature) {
   // Updating a manifest with a valid token should work
   // with or without the kAppCacheRequireOriginTrial feature.
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
   RunTestOnUIThread(&AppCacheUpdateJobTest::OriginTrialUpdateTest);
 }
 
 TEST_F(AppCacheUpdateJobTest, OriginTrialUpdateWithoutFeature) {
-  base::test::ScopedFeatureList f;
-  f.InitAndDisableFeature(blink::features::kAppCacheRequireOriginTrial);
+  // The default AppCacheUpdateJobTest disables the origin trial.
   RunTestOnUIThread(&AppCacheUpdateJobTest::OriginTrialUpdateTest);
 }
 
-TEST_F(AppCacheUpdateJobTest, OriginTrialRequiredNoToken) {
-  base::test::ScopedFeatureList f;
-  f.InitAndEnableFeature(blink::features::kAppCacheRequireOriginTrial);
+TEST_F(AppCacheUpdateJobOriginTrialTest, OriginTrialRequiredNoToken) {
   RunTestOnUIThread(&AppCacheUpdateJobTest::OriginTrialRequiredNoTokenTest);
 }
 
diff --git a/content/browser/appcache/appcache_url_loader.cc b/content/browser/appcache/appcache_url_loader.cc
index a734156..8a5c090 100644
--- a/content/browser/appcache/appcache_url_loader.cc
+++ b/content/browser/appcache/appcache_url_loader.cc
@@ -380,14 +380,14 @@
 
   network::URLLoaderCompletionStatus status(error_code);
   if (!error_code) {
-    const net::HttpResponseInfo* http_info =
-        is_range_request() ? range_response_info_.get()
-                           : (info_ ? &info_->http_response_info() : nullptr);
+    const net::HttpResponseInfo* http_info = is_range_request()
+                                                 ? range_response_info_.get()
+                                                 : &info_->http_response_info();
     status.exists_in_cache = http_info->was_cached;
     status.completion_time = base::TimeTicks::Now();
     status.encoded_body_length =
         is_range_request() ? range_response_info_->headers->GetContentLength()
-                           : (info_ ? info_->response_data_size() : 0);
+                           : info_->response_data_size();
     status.decoded_body_length = status.encoded_body_length;
   }
   client_->OnComplete(status);
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 4e5dab2..a1ed94e 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -899,9 +899,11 @@
 void AddIssueToIssueStorage(
     RenderFrameHost* frame,
     std::unique_ptr<protocol::Audits::InspectorIssue> issue) {
-  WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
+  // We only utilize a central storage on the main frame. Each issue is
+  // still associated with the originating |RenderFrameHost| though.
   DevToolsIssueStorage* issue_storage =
-      DevToolsIssueStorage::GetOrCreateForWebContents(web_contents);
+      DevToolsIssueStorage::GetOrCreateForCurrentDocument(
+          frame->GetMainFrame());
 
   issue_storage->AddInspectorIssue(frame->GetFrameTreeNodeId(),
                                    std::move(issue));
diff --git a/content/browser/devtools/devtools_issue_storage.cc b/content/browser/devtools/devtools_issue_storage.cc
index 45ca968..eac17f21 100644
--- a/content/browser/devtools/devtools_issue_storage.cc
+++ b/content/browser/devtools/devtools_issue_storage.cc
@@ -6,16 +6,17 @@
 
 #include "content/browser/devtools/protocol/audits.h"
 #include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/base/page_transition_types.h"
 
 namespace content {
 
 static const unsigned kMaxIssueCount = 1000;
 
-WEB_CONTENTS_USER_DATA_KEY_IMPL(DevToolsIssueStorage)
+RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(DevToolsIssueStorage)
 
-DevToolsIssueStorage::DevToolsIssueStorage(WebContents* contents)
-    : WebContentsObserver(contents) {}
+DevToolsIssueStorage::DevToolsIssueStorage(RenderFrameHost* rfh)
+    : WebContentsObserver(content::WebContents::FromRenderFrameHost(rfh)) {}
 DevToolsIssueStorage::~DevToolsIssueStorage() = default;
 
 void DevToolsIssueStorage::AddInspectorIssue(
@@ -40,20 +41,6 @@
   return issues;
 }
 
-void DevToolsIssueStorage::DidFinishNavigation(
-    NavigationHandle* navigation_handle) {
-  if (!navigation_handle->IsInMainFrame())
-    return;
-  if (!navigation_handle->HasCommitted())
-    return;
-
-  const auto transition = navigation_handle->GetPageTransition();
-  if (ui::PageTransitionIsRedirect(transition))
-    return;
-
-  issues_.clear();
-}
-
 void DevToolsIssueStorage::FrameDeleted(RenderFrameHost* render_frame_host) {
   // Deletion of the main frame causes the DevToolsIssueStorage to be cleaned
   // up. Also there would no longer be a root frame we could re-parent issues
diff --git a/content/browser/devtools/devtools_issue_storage.h b/content/browser/devtools/devtools_issue_storage.h
index 27e475a..c92d0c7 100644
--- a/content/browser/devtools/devtools_issue_storage.h
+++ b/content/browser/devtools/devtools_issue_storage.h
@@ -7,8 +7,8 @@
 
 #include "base/containers/circular_deque.h"
 #include "base/unguessable_token.h"
+#include "content/public/browser/render_document_host_user_data.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_user_data.h"
 
 namespace content {
 
@@ -18,19 +18,15 @@
 }  // namespace Audits
 }  // namespace protocol
 
+// TODO(crbug.com/1063007): Attribute issues to ongoing navigations correctly.
+// TODO(crbug.com/1090679): Replace RenderDocumentHostUserData with
+//                          PageUserData.
 class DevToolsIssueStorage
-    : public content::WebContentsUserData<DevToolsIssueStorage>,
+    : public content::RenderDocumentHostUserData<DevToolsIssueStorage>,
       public WebContentsObserver {
  public:
   ~DevToolsIssueStorage() override;
 
-  static DevToolsIssueStorage* GetOrCreateForWebContents(
-      WebContents* contents) {
-    content::WebContentsUserData<DevToolsIssueStorage>::CreateForWebContents(
-        contents);
-    return FromWebContents(contents);
-  }
-
   void AddInspectorIssue(
       int frame_tree_node_id,
       std::unique_ptr<protocol::Audits::InspectorIssue> issue);
@@ -38,12 +34,11 @@
       const base::flat_set<int>& frame_tree_node_ids) const;
 
  private:
-  explicit DevToolsIssueStorage(content::WebContents* contents);
-  friend class content::WebContentsUserData<DevToolsIssueStorage>;
-  WEB_CONTENTS_USER_DATA_KEY_DECL();
+  explicit DevToolsIssueStorage(RenderFrameHost* rfh);
+  friend class content::RenderDocumentHostUserData<DevToolsIssueStorage>;
+  RENDER_DOCUMENT_HOST_USER_DATA_KEY_DECL();
 
   // WebContentsObserver overrides.
-  void DidFinishNavigation(NavigationHandle* navigation_handle) override;
   void FrameDeleted(RenderFrameHost* render_frame_host) override;
 
   using FrameAssociatedIssue =
diff --git a/content/browser/devtools/devtools_issue_storage_browsertest.cc b/content/browser/devtools/devtools_issue_storage_browsertest.cc
index 9782b39f..0dcf3f334 100644
--- a/content/browser/devtools/devtools_issue_storage_browsertest.cc
+++ b/content/browser/devtools/devtools_issue_storage_browsertest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/command_line.h"
+#include "base/test/scoped_feature_list.h"
 #include "content/browser/devtools/devtools_instrumentation.h"
 #include "content/browser/devtools/protocol/audits.h"
 #include "content/browser/devtools/protocol/devtools_protocol_test_support.h"
@@ -13,12 +15,14 @@
 #include "content/public/browser/devtools_agent_host_client.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_base.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "net/dns/mock_host_resolver.h"
 
@@ -32,10 +36,12 @@
   }
 
  protected:
+  WebContentsImpl* web_contents() {
+    return static_cast<WebContentsImpl*>(shell()->web_contents());
+  }
+
   RenderFrameHostImpl* main_frame_host() {
-    WebContentsImpl* web_contents_impl =
-        static_cast<WebContentsImpl*>(shell()->web_contents());
-    return web_contents_impl->GetFrameTree()->GetMainFrame();
+    return web_contents()->GetFrameTree()->GetMainFrame();
   }
 };
 
@@ -145,4 +151,56 @@
   ASSERT_TRUE(notifications_.empty());
 }
 
+class DevToolsIssueStorageWithBackForwardCacheBrowserTest
+    : public DevToolsIssueStorageBrowserTest {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    std::vector<base::test::ScopedFeatureList::FeatureAndParams>
+        enabled_features;
+
+    // Enable BackForwardCache, omitting this feature results in a crash.
+    std::map<std::string, std::string> params = {
+        {"TimeToLiveInBackForwardCacheInSeconds", "3600"}};
+    enabled_features.emplace_back(features::kBackForwardCache, params);
+    feature_list_.InitWithFeaturesAndParameters(enabled_features, {});
+  }
+
+ protected:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(DevToolsIssueStorageWithBackForwardCacheBrowserTest,
+                       BackForwardCacheGoBack) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  // 1) Navigate to A.
+  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  RenderFrameHostImpl* rfh_a = main_frame_host();
+  RenderFrameDeletedObserver rfh_a_deleted(rfh_a);
+
+  // 2) Report an empty SameSite cookie issue.
+  ReportDummyIssue(rfh_a);
+
+  // 3) Navigate to B.
+  //    The previous test verifies that the issue storage is cleared at
+  //    this point.
+  EXPECT_TRUE(NavigateToURL(shell(), url_b));
+  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
+
+  // 4) Go back to A and expect that it is restored from the back-forward cache.
+  web_contents()->GetController().GoBack();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  EXPECT_FALSE(rfh_a_deleted.deleted());
+  EXPECT_EQ(main_frame_host(), rfh_a);
+
+  // 5) Open DevTools and enable Audits domain.
+  Attach();
+  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+
+  // 6) Verify we have received the SameSite issue on the main target.
+  WaitForNotification("Audits.issueAdded", true);
+}
+
 }  // namespace content
diff --git a/content/browser/devtools/protocol/audits_handler.cc b/content/browser/devtools/protocol/audits_handler.cc
index b6baeeac..99aeb89 100644
--- a/content/browser/devtools/protocol/audits_handler.cc
+++ b/content/browser/devtools/protocol/audits_handler.cc
@@ -8,6 +8,7 @@
 #include "content/browser/devtools/devtools_issue_storage.h"
 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
 #include "content/browser/frame_host/frame_tree_node.h"
+#include "content/public/browser/web_contents.h"
 
 namespace content {
 namespace protocol {
@@ -42,9 +43,8 @@
 void SendStoredIssuesForFrameToAgent(RenderFrameHostImpl* rfh,
                                      protocol::AuditsHandler* handler) {
   // Check the storage first. No need to do any work in case its empty.
-  WebContents* web_contents = WebContents::FromRenderFrameHost(rfh);
   DevToolsIssueStorage* issue_storage =
-      DevToolsIssueStorage::FromWebContents(web_contents);
+      DevToolsIssueStorage::GetForCurrentDocument(rfh->GetMainFrame());
   if (!issue_storage)
     return;
 
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index d6f57ef..76d20a57 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -54,7 +54,6 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/origin_util.h"
-#include "content/public/common/referrer.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
@@ -78,6 +77,7 @@
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "third_party/blink/public/platform/resource_request_blocked_reason.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 
@@ -360,7 +360,7 @@
     case network::mojom::ReferrerPolicy::kAlways:
       return Network::Request::ReferrerPolicyEnum::UnsafeUrl;
     case network::mojom::ReferrerPolicy::kDefault:
-      return referrerPolicy(Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+      return referrerPolicy(blink::NetToMojoReferrerPolicy(
           content::Referrer::GetDefaultReferrerPolicy()));
     case network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade:
       return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade;
@@ -382,8 +382,7 @@
 }
 
 String referrerPolicy(net::ReferrerPolicy referrer_policy) {
-  return referrerPolicy(
-      Referrer::NetReferrerPolicyToBlinkReferrerPolicy(referrer_policy));
+  return referrerPolicy(blink::NetToMojoReferrerPolicy(referrer_policy));
 }
 
 String securityState(const GURL& url, const net::CertStatus& cert_status) {
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 320bf07e..6d11f22 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -66,7 +66,6 @@
 #include "content/public/browser/web_ui_url_loader_factory.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/origin_util.h"
-#include "content/public/common/referrer.h"
 #include "content/public/common/url_utils.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -80,6 +79,7 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "third_party/blink/public/common/loader/previews_state.h"
 #include "third_party/blink/public/common/loader/throttling_url_loader.h"
 
@@ -536,9 +536,9 @@
       url_chain.pop_back();
       NavigationController::LoadURLParams params(url);
       params.has_user_gesture = info.has_user_gesture;
-      params.referrer = Referrer(
-          info.referrer_url, Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-                                 info.referrer_policy));
+      params.referrer =
+          Referrer(info.referrer_url,
+                   blink::NetToMojoReferrerPolicy(info.referrer_policy));
       params.redirect_chain = url_chain;
       params.frame_tree_node_id =
           RenderFrameHost::GetFrameTreeNodeIdForRoutingId(
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index f18cc14e..dfa6c691 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -227,6 +227,8 @@
   test_resources.MaybeCreateLoader();
   EXPECT_FALSE(test_resources.loader());
 
+  base::RunLoop().RunUntilIdle();
+
   histogram_tester.ExpectTotalCount(
       "ServiceWorker.LookupRegistration.MainResource.Time.DoesNotExist", 1);
 
@@ -249,6 +251,8 @@
   test_resources.MaybeCreateLoader();
   EXPECT_FALSE(test_resources.loader());
 
+  base::RunLoop().RunUntilIdle();
+
   histogram_tester.ExpectTotalCount(
       "ServiceWorker.LookupRegistration.MainResource.Time.Error", 1);
 
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc
index 38f3457..01a2eaf 100644
--- a/content/browser/service_worker/service_worker_database.cc
+++ b/content/browser/service_worker/service_worker_database.cc
@@ -1111,7 +1111,7 @@
 ServiceWorkerDatabase::Status
 ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
     const std::string& user_data_name,
-    std::vector<std::pair<int64_t, std::string>>* user_data) {
+    std::vector<storage::mojom::ServiceWorkerUserDataPtr>* user_data) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(user_data->empty());
 
@@ -1153,7 +1153,8 @@
         user_data->clear();
         break;
       }
-      user_data->push_back(std::make_pair(registration_id, value));
+      user_data->emplace_back(storage::mojom::ServiceWorkerUserData::New(
+          registration_id, user_data_name, value));
     }
   }
 
@@ -1164,7 +1165,7 @@
 ServiceWorkerDatabase::Status
 ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
     const std::string& user_data_name_prefix,
-    std::vector<std::pair<int64_t, std::string>>* user_data) {
+    std::vector<storage::mojom::ServiceWorkerUserDataPtr>* user_data) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(user_data->empty());
 
@@ -1221,7 +1222,8 @@
         user_data->clear();
         break;
       }
-      user_data->push_back(std::make_pair(registration_id, value));
+      user_data->push_back(storage::mojom::ServiceWorkerUserData::New(
+          registration_id, parts[0], value));
     }
   }
 
diff --git a/content/browser/service_worker/service_worker_database.h b/content/browser/service_worker/service_worker_database.h
index 3ee09fdd..49f9cd9 100644
--- a/content/browser/service_worker/service_worker_database.h
+++ b/content/browser/service_worker/service_worker_database.h
@@ -217,14 +217,14 @@
   // from the database. Returns OK if they are successfully read or not found.
   Status ReadUserDataForAllRegistrations(
       const std::string& user_data_name,
-      std::vector<std::pair<int64_t, std::string>>* user_data);
+      std::vector<storage::mojom::ServiceWorkerUserDataPtr>* user_data);
 
   // Reads user data for all registrations that have data with
   // |user_data_name_prefix| from the database. Returns OK if they are
   // successfully read or not found.
   Status ReadUserDataForAllRegistrationsByKeyPrefix(
       const std::string& user_data_name_prefix,
-      std::vector<std::pair<int64_t, std::string>>* user_data);
+      std::vector<storage::mojom::ServiceWorkerUserDataPtr>* user_data);
 
   // Deletes user data for all registrations that have data with
   // |user_data_name_prefix| from the database. Returns OK if all are
diff --git a/content/browser/service_worker/service_worker_database_unittest.cc b/content/browser/service_worker/service_worker_database_unittest.cc
index c5caaa2..0fa08fe 100644
--- a/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/content/browser/service_worker/service_worker_database_unittest.cc
@@ -106,11 +106,12 @@
 }
 
 std::vector<storage::mojom::ServiceWorkerUserDataPtr> CreateUserData(
+    int64_t registration_id,
     const std::vector<std::pair<std::string, std::string>>& key_value_pairs) {
   std::vector<storage::mojom::ServiceWorkerUserDataPtr> out;
   for (auto& kv : key_value_pairs) {
-    out.push_back(
-        storage::mojom::ServiceWorkerUserData::New(kv.first, kv.second));
+    out.push_back(storage::mojom::ServiceWorkerUserData::New(
+        registration_id, kv.first, kv.second));
   }
   return out;
 }
@@ -1083,8 +1084,9 @@
   // Write user data associated with the stored registration.
   std::vector<std::string> user_data_out;
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data.registration_id, kOrigin,
-                                    CreateUserData({{"key1", "data"}})));
+            database->WriteUserData(
+                data.registration_id, kOrigin,
+                CreateUserData(data.registration_id, {{"key1", "data"}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
@@ -1094,13 +1096,15 @@
   // Writing user data not associated with the stored registration should be
   // failed.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kErrorNotFound,
-            database->WriteUserData(300, kOrigin,
-                                    CreateUserData({{"key1", "data"}})));
+            database->WriteUserData(
+                300, kOrigin,
+                CreateUserData(data.registration_id, {{"key1", "data"}})));
 
   // Write empty user data for a different key.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(data.registration_id, kOrigin,
-                                    CreateUserData({{"key2", std::string()}})));
+                                    CreateUserData(data.registration_id,
+                                                   {{"key2", std::string()}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data.registration_id, {"key2"}, &user_data_out));
@@ -1114,8 +1118,9 @@
 
   // Overwrite the existing user data.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data.registration_id, kOrigin,
-                                    CreateUserData({{"key1", "overwrite"}})));
+            database->WriteUserData(
+                data.registration_id, kOrigin,
+                CreateUserData(data.registration_id, {{"key1", "overwrite"}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
@@ -1137,10 +1142,11 @@
 
   // Write/overwrite multiple user data keys.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data.registration_id, kOrigin,
-                                    CreateUserData({{"key2", "overwrite2"},
-                                                    {"key3", "data3"},
-                                                    {"key4", "data4"}})));
+            database->WriteUserData(
+                data.registration_id, kOrigin,
+                CreateUserData(data.registration_id, {{"key2", "overwrite2"},
+                                                      {"key3", "data3"},
+                                                      {"key4", "data4"}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kErrorNotFound,
       database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
@@ -1212,51 +1218,63 @@
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->WriteUserData(data1.registration_id, kOrigin,
-                              CreateUserData({{"key_prefix:key1", "value1"}})));
+                              CreateUserData(data1.registration_id,
+                                             {{"key_prefix:key1", "value1"}})));
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->WriteUserData(data1.registration_id, kOrigin,
-                              CreateUserData({{"key_prefix:key2", "value2"}})));
+                              CreateUserData(data1.registration_id,
+                                             {{"key_prefix:key2", "value2"}})));
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->WriteUserData(data1.registration_id, kOrigin,
-                              CreateUserData({{"key_prefix:key3", "value3"}})));
+                              CreateUserData(data1.registration_id,
+                                             {{"key_prefix:key3", "value3"}})));
 
   // Write user data associated with the registration2.
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->WriteUserData(data2.registration_id, kOrigin,
-                              CreateUserData({{"key_prefix:key1", "value1"}})));
+                              CreateUserData(data2.registration_id,
+                                             {{"key_prefix:key1", "value1"}})));
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->WriteUserData(data2.registration_id, kOrigin,
-                              CreateUserData({{"key_prefix:key2", "value2"}})));
+                              CreateUserData(data2.registration_id,
+                                             {{"key_prefix:key2", "value2"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data2.registration_id, kOrigin,
-                CreateUserData({{"another_key_prefix:key1", "value1"}})));
+                CreateUserData(data2.registration_id,
+                               {{"another_key_prefix:key1", "value1"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data2.registration_id, kOrigin,
-                CreateUserData({{"another_key_prefix:key2", "value2"}})));
+                CreateUserData(data2.registration_id,
+                               {{"another_key_prefix:key2", "value2"}})));
 
   // Get all registrations with user data by key prefix.
-  std::vector<std::pair<int64_t, std::string>> user_data_list;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data_list;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->ReadUserDataForAllRegistrationsByKeyPrefix(
                 "key_prefix:", &user_data_list));
   ASSERT_EQ(5u, user_data_list.size());
 
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("value1", user_data_list[0].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
-  EXPECT_EQ("value1", user_data_list[1].second);
-  EXPECT_EQ(data1.registration_id, user_data_list[2].first);
-  EXPECT_EQ("value2", user_data_list[2].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[3].first);
-  EXPECT_EQ("value2", user_data_list[3].second);
-  EXPECT_EQ(data1.registration_id, user_data_list[4].first);
-  EXPECT_EQ("value3", user_data_list[4].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("key_prefix:key1", user_data_list[0]->key);
+  EXPECT_EQ("value1", user_data_list[0]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[1]->registration_id);
+  EXPECT_EQ("key_prefix:key1", user_data_list[1]->key);
+  EXPECT_EQ("value1", user_data_list[1]->value);
+  EXPECT_EQ(data1.registration_id, user_data_list[2]->registration_id);
+  EXPECT_EQ("key_prefix:key2", user_data_list[2]->key);
+  EXPECT_EQ("value2", user_data_list[2]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[3]->registration_id);
+  EXPECT_EQ("key_prefix:key2", user_data_list[3]->key);
+  EXPECT_EQ("value2", user_data_list[3]->value);
+  EXPECT_EQ(data1.registration_id, user_data_list[4]->registration_id);
+  EXPECT_EQ("key_prefix:key3", user_data_list[4]->key);
+  EXPECT_EQ("value3", user_data_list[4]->value);
 }
 
 TEST(ServiceWorkerDatabaseTest, ReadUserDataByKeyPrefix) {
@@ -1280,7 +1298,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_c1"},
+                CreateUserData(data.registration_id,
+                               {{"key_prefix:key1", "value_c1"},
                                 {"key_prefix:key2", "value_c2"},
                                 {"other_key_prefix:k1", "value_d1"},
                                 {"other_key_prefix:k2", "value_d2"}})));
@@ -1325,7 +1344,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_c1"},
+                CreateUserData(data.registration_id,
+                               {{"key_prefix:key1", "value_c1"},
                                 {"key_prefix:key2", "value_c2"},
                                 {"other_key_prefix:k1", "value_d1"},
                                 {"other_key_prefix:k2", "value_d2"}})));
@@ -1387,7 +1407,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data1.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_a1"},
+                CreateUserData(data1.registration_id,
+                               {{"key_prefix:key1", "value_a1"},
                                 {"key_prefix:key2", "value_a2"},
                                 {"key_prefix:key3", "value_a3"},
                                 {"kept_key_prefix:key1", "value_b1"}})));
@@ -1396,7 +1417,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data2.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_c1"},
+                CreateUserData(data2.registration_id,
+                               {{"key_prefix:key1", "value_c1"},
                                 {"key_prefix:key2", "value_c2"},
                                 {"other_key_prefix:key1", "value_d1"},
                                 {"other_key_prefix:key2", "value_d2"},
@@ -1418,17 +1440,20 @@
                 {"key_prefix:", "other_key_prefix:", "not_found_key_prefix:"}));
 
   // User data with deleted "key_prefix:" should only remain for registration 1.
-  std::vector<std::pair<int64_t, std::string>> user_data_list;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data_list;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->ReadUserDataForAllRegistrationsByKeyPrefix(
                 "key_prefix:", &user_data_list));
   ASSERT_EQ(3u, user_data_list.size());
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("value_a1", user_data_list[0].second);
-  EXPECT_EQ(data1.registration_id, user_data_list[1].first);
-  EXPECT_EQ("value_a2", user_data_list[1].second);
-  EXPECT_EQ(data1.registration_id, user_data_list[2].first);
-  EXPECT_EQ("value_a3", user_data_list[2].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("key_prefix:key1", user_data_list[0]->key);
+  EXPECT_EQ("value_a1", user_data_list[0]->value);
+  EXPECT_EQ(data1.registration_id, user_data_list[1]->registration_id);
+  EXPECT_EQ("key_prefix:key2", user_data_list[1]->key);
+  EXPECT_EQ("value_a2", user_data_list[1]->value);
+  EXPECT_EQ(data1.registration_id, user_data_list[2]->registration_id);
+  EXPECT_EQ("key_prefix:key3", user_data_list[2]->key);
+  EXPECT_EQ("value_a3", user_data_list[2]->value);
 
   // User data for second deleted key prefix should also have been deleted.
   user_data_list.clear();
@@ -1444,12 +1469,15 @@
             database->ReadUserDataForAllRegistrationsByKeyPrefix(
                 "kept_key_prefix:", &user_data_list));
   ASSERT_EQ(3u, user_data_list.size());
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("value_b1", user_data_list[0].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
-  EXPECT_EQ("value_e1", user_data_list[1].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[2].first);
-  EXPECT_EQ("value_e2", user_data_list[2].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key1", user_data_list[0]->key);
+  EXPECT_EQ("value_b1", user_data_list[0]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[1]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key1", user_data_list[1]->key);
+  EXPECT_EQ("value_e1", user_data_list[1]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[2]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key2", user_data_list[2]->key);
+  EXPECT_EQ("value_e2", user_data_list[2]->value);
 }
 
 TEST(ServiceWorkerDatabaseTest,
@@ -1487,7 +1515,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data1.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_a1"},
+                CreateUserData(data1.registration_id,
+                               {{"key_prefix:key1", "value_a1"},
                                 {"key_prefix:key2", "value_a2"},
                                 {"key_prefix:key3", "value_a3"},
                                 {"kept_key_prefix:key1", "value_b1"}})));
@@ -1496,7 +1525,8 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteUserData(
                 data2.registration_id, kOrigin,
-                CreateUserData({{"key_prefix:key1", "value_c1"},
+                CreateUserData(data2.registration_id,
+                               {{"key_prefix:key1", "value_c1"},
                                 {"key_prefix:key2", "value_c2"},
                                 {"kept_key_prefix:key1", "value_d1"},
                                 {"kept_key_prefix:key2", "value_d2"}})));
@@ -1514,7 +1544,7 @@
       database->DeleteUserDataForAllRegistrationsByKeyPrefix("key_prefix:"));
 
   // User data with deleted "key_prefix:" should be deleted.
-  std::vector<std::pair<int64_t, std::string>> user_data_list;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data_list;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->ReadUserDataForAllRegistrationsByKeyPrefix(
                 "key_prefix:", &user_data_list));
@@ -1527,12 +1557,15 @@
                 "kept_key_prefix:", &user_data_list));
   ASSERT_EQ(3u, user_data_list.size());
 
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("value_b1", user_data_list[0].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
-  EXPECT_EQ("value_d1", user_data_list[1].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[2].first);
-  EXPECT_EQ("value_d2", user_data_list[2].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key1", user_data_list[0]->key);
+  EXPECT_EQ("value_b1", user_data_list[0]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[1]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key1", user_data_list[1]->key);
+  EXPECT_EQ("value_d1", user_data_list[1]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[2]->registration_id);
+  EXPECT_EQ("kept_key_prefix:key2", user_data_list[2]->key);
+  EXPECT_EQ("value_d2", user_data_list[2]->value);
 }
 
 TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
@@ -1569,13 +1602,14 @@
   // Write user data associated with the registration1.
   std::vector<std::string> user_data_out;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data1.registration_id, kOrigin,
-                                    CreateUserData({{"key", "data1"}})));
+            database->WriteUserData(
+                data1.registration_id, kOrigin,
+                CreateUserData(data1.registration_id, {{"key", "value1"}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data1", user_data_out[0]);
+  EXPECT_EQ("value1", user_data_out[0]);
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kErrorNotFound,
       database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));
@@ -1583,28 +1617,31 @@
   // Write user data associated with the registration2. This shouldn't overwrite
   // the data associated with registration1.
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data2.registration_id, kOrigin,
-                                    CreateUserData({{"key", "data2"}})));
+            database->WriteUserData(
+                data2.registration_id, kOrigin,
+                CreateUserData(data2.registration_id, {{"key", "value2"}})));
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data1", user_data_out[0]);
+  EXPECT_EQ("value1", user_data_out[0]);
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data2", user_data_out[0]);
+  EXPECT_EQ("value2", user_data_out[0]);
 
   // Get all registrations with user data.
-  std::vector<std::pair<int64_t, std::string>> user_data_list;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data_list;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->ReadUserDataForAllRegistrations("key", &user_data_list));
   EXPECT_EQ(2u, user_data_list.size());
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("data1", user_data_list[0].second);
-  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
-  EXPECT_EQ("data2", user_data_list[1].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("key", user_data_list[0]->key);
+  EXPECT_EQ("value1", user_data_list[0]->value);
+  EXPECT_EQ(data2.registration_id, user_data_list[1]->registration_id);
+  EXPECT_EQ("key", user_data_list[1]->key);
+  EXPECT_EQ("value2", user_data_list[1]->value);
 
   // Delete the data associated with the registration2. This shouldn't delete
   // the data associated with registration1.
@@ -1614,7 +1651,7 @@
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data1", user_data_out[0]);
+  EXPECT_EQ("value1", user_data_out[0]);
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kErrorNotFound,
       database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));
@@ -1624,8 +1661,9 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->ReadUserDataForAllRegistrations("key", &user_data_list));
   EXPECT_EQ(1u, user_data_list.size());
-  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
-  EXPECT_EQ("data1", user_data_list[0].second);
+  EXPECT_EQ(data1.registration_id, user_data_list[0]->registration_id);
+  EXPECT_EQ("key", user_data_list[0]->key);
+  EXPECT_EQ("value1", user_data_list[0]->value);
 }
 
 TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
@@ -1661,31 +1699,34 @@
   // Write user data associated with the registration1.
   std::vector<std::string> user_data_out;
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data1.registration_id, kOrigin,
-                                    CreateUserData({{"key1", "data1"}})));
+            database->WriteUserData(
+                data1.registration_id, kOrigin,
+                CreateUserData(data1.registration_id, {{"key1", "value1"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data1.registration_id, kOrigin,
-                                    CreateUserData({{"key2", "data2"}})));
+            database->WriteUserData(
+                data1.registration_id, kOrigin,
+                CreateUserData(data1.registration_id, {{"key2", "value2"}})));
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data1.registration_id, {"key1"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  ASSERT_EQ("data1", user_data_out[0]);
+  ASSERT_EQ("value1", user_data_out[0]);
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data1.registration_id, {"key2"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  ASSERT_EQ("data2", user_data_out[0]);
+  ASSERT_EQ("value2", user_data_out[0]);
 
   // Write user data associated with the registration2.
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data2.registration_id, kOrigin,
-                                    CreateUserData({{"key3", "data3"}})));
+            database->WriteUserData(
+                data2.registration_id, kOrigin,
+                CreateUserData(data2.registration_id, {{"key3", "value3"}})));
   ASSERT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data2.registration_id, {"key3"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  ASSERT_EQ("data3", user_data_out[0]);
+  ASSERT_EQ("value3", user_data_out[0]);
 
   // Delete all data associated with the registration1. This shouldn't delete
   // the data associated with registration2.
@@ -1702,7 +1743,7 @@
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data2.registration_id, {"key3"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data3", user_data_out[0]);
+  EXPECT_EQ("value3", user_data_out[0]);
 }
 
 TEST(ServiceWorkerDatabaseTest, UserData_UninitializedDatabase) {
@@ -1715,9 +1756,9 @@
             database->ReadUserData(100, {"key"}, &user_data_out));
 
   // Should be failed because the associated registration does not exist.
-  EXPECT_EQ(
-      ServiceWorkerDatabase::Status::kErrorNotFound,
-      database->WriteUserData(100, kOrigin, CreateUserData({{"key", "data"}})));
+  EXPECT_EQ(ServiceWorkerDatabase::Status::kErrorNotFound,
+            database->WriteUserData(100, kOrigin,
+                                    CreateUserData(100, {{"key", "value"}})));
 
   // Deleting non-existent entry should succeed.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
@@ -1731,9 +1772,9 @@
             database->state_);
   EXPECT_EQ(ServiceWorkerDatabase::Status::kErrorNotFound,
             database->ReadUserData(100, {"key"}, &user_data_out));
-  EXPECT_EQ(
-      ServiceWorkerDatabase::Status::kErrorNotFound,
-      database->WriteUserData(100, kOrigin, CreateUserData({{"key", "data"}})));
+  EXPECT_EQ(ServiceWorkerDatabase::Status::kErrorNotFound,
+            database->WriteUserData(100, kOrigin,
+                                    CreateUserData(100, {{"key", "value"}})));
 
   // Deleting non-existent entry should succeed.
   EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
@@ -1926,11 +1967,13 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteRegistration(data1, resources1, &deleted_version));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data1.registration_id, origin1,
-                                    CreateUserData({{"key1", "data1"}})));
+            database->WriteUserData(
+                data1.registration_id, origin1,
+                CreateUserData(data1.registration_id, {{"key1", "value1"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data1.registration_id, origin1,
-                                    CreateUserData({{"key2", "data2"}})));
+            database->WriteUserData(
+                data1.registration_id, origin1,
+                CreateUserData(data1.registration_id, {{"key2", "value2"}})));
 
   RegistrationData data2;
   data2.registration_id = 11;
@@ -1945,11 +1988,13 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteRegistration(data2, resources2, &deleted_version));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data2.registration_id, origin1,
-                                    CreateUserData({{"key3", "data3"}})));
+            database->WriteUserData(
+                data2.registration_id, origin1,
+                CreateUserData(data2.registration_id, {{"key3", "value3"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data2.registration_id, origin1,
-                                    CreateUserData({{"key4", "data4"}})));
+            database->WriteUserData(
+                data2.registration_id, origin1,
+                CreateUserData(data2.registration_id, {{"key4", "value4"}})));
 
   // |origin2| has one registration (registration3).
   RegistrationData data3;
@@ -1965,11 +2010,13 @@
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
             database->WriteRegistration(data3, resources3, &deleted_version));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data3.registration_id, origin2,
-                                    CreateUserData({{"key5", "data5"}})));
+            database->WriteUserData(
+                data3.registration_id, origin2,
+                CreateUserData(data3.registration_id, {{"key5", "value5"}})));
   ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
-            database->WriteUserData(data3.registration_id, origin2,
-                                    CreateUserData({{"key6", "data6"}})));
+            database->WriteUserData(
+                data3.registration_id, origin2,
+                CreateUserData(data3.registration_id, {{"key6", "value6"}})));
 
   std::set<GURL> origins_to_delete;
   std::vector<int64_t> newly_purgeable_resources;
@@ -2039,12 +2086,12 @@
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data3.registration_id, {"key5"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data5", user_data_out[0]);
+  EXPECT_EQ("value5", user_data_out[0]);
   EXPECT_EQ(
       ServiceWorkerDatabase::Status::kOk,
       database->ReadUserData(data3.registration_id, {"key6"}, &user_data_out));
   ASSERT_EQ(1u, user_data_out.size());
-  EXPECT_EQ("data6", user_data_out[0]);
+  EXPECT_EQ("value6", user_data_out[0]);
 }
 
 TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 3b29f0d..e05d68a 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -625,10 +625,6 @@
 void ServiceWorkerFetchDispatcher::DidFailToDispatch(
     std::unique_ptr<ResponseCallback> response_callback,
     blink::ServiceWorkerStatusCode status) {
-  // Fetch dispatcher can be completed at this point due to a failure of
-  // starting up a worker. In that case, let's simply ignore it.
-  if (IsCompleted())
-    return;
   DidFail(status);
 }
 
@@ -639,9 +635,9 @@
       "ServiceWorker", "ServiceWorkerFetchDispatcher::DidFail",
       TRACE_ID_LOCAL(this),
       TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status", status);
-  Complete(status, FetchEventResult::kShouldFallback,
-           blink::mojom::FetchAPIResponse::New(), nullptr /* body_as_stream */,
-           nullptr /* timing */);
+  RunCallback(status, FetchEventResult::kShouldFallback,
+              blink::mojom::FetchAPIResponse::New(),
+              nullptr /* body_as_stream */, nullptr /* timing */);
 }
 
 void ServiceWorkerFetchDispatcher::DidFinish(
@@ -654,17 +650,21 @@
                          "ServiceWorkerFetchDispatcher::DidFinish",
                          TRACE_ID_LOCAL(this),
                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
-  Complete(blink::ServiceWorkerStatusCode::kOk, fetch_result,
-           std::move(response), std::move(body_as_stream), std::move(timing));
+  RunCallback(blink::ServiceWorkerStatusCode::kOk, fetch_result,
+              std::move(response), std::move(body_as_stream),
+              std::move(timing));
 }
 
-void ServiceWorkerFetchDispatcher::Complete(
+void ServiceWorkerFetchDispatcher::RunCallback(
     blink::ServiceWorkerStatusCode status,
     FetchEventResult fetch_result,
     blink::mojom::FetchAPIResponsePtr response,
     blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
     blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
-  DCHECK(fetch_callback_);
+  // Fetch dispatcher can be completed at this point due to a failure of
+  // starting up a worker. In that case, let's simply ignore it.
+  if (!fetch_callback_)
+    return;
 
   std::move(fetch_callback_)
       .Run(status, fetch_result, std::move(response), std::move(body_as_stream),
@@ -776,10 +776,6 @@
   return request_.is_null();
 }
 
-bool ServiceWorkerFetchDispatcher::IsCompleted() const {
-  return fetch_callback_.is_null();
-}
-
 // static
 void ServiceWorkerFetchDispatcher::OnFetchEventFinished(
     ServiceWorkerVersion* version,
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h
index dfc319b..b7756b7 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -91,11 +91,11 @@
                  blink::mojom::FetchAPIResponsePtr response,
                  blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
                  blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
-  void Complete(blink::ServiceWorkerStatusCode status,
-                FetchEventResult fetch_result,
-                blink::mojom::FetchAPIResponsePtr response,
-                blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
-                blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
+  void RunCallback(blink::ServiceWorkerStatusCode status,
+                   FetchEventResult fetch_result,
+                   blink::mojom::FetchAPIResponsePtr response,
+                   blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+                   blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
 
   // The fetch event stays open until all respondWith() and waitUntil() promises
   // are settled. This function is called once the renderer signals that
@@ -110,7 +110,6 @@
   ServiceWorkerMetrics::EventType GetEventType() const;
 
   bool IsEventDispatched() const;
-  bool IsCompleted() const;
 
   blink::mojom::FetchAPIRequestPtr request_;
   std::string client_id_;
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc
index 5bd3a64..413fc91c 100644
--- a/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -446,6 +446,7 @@
   RunUnregisterJob(options.scope);
 
   WaitForVersionRunningStatus(version, EmbeddedWorkerStatus::STOPPED);
+  registry()->GetRemoteStorageControl().FlushForTesting();
 
   // The service worker registration object host and service worker object host
   // have been destroyed together with |worker_host| by the above
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc
index 5c5fb60b..1272149 100644
--- a/content/browser/service_worker/service_worker_registry.cc
+++ b/content/browser/service_worker/service_worker_registry.cc
@@ -182,7 +182,7 @@
   TRACE_EVENT_ASYNC_BEGIN1(
       "ServiceWorker", "ServiceWorkerRegistry::FindRegistrationForClientUrl",
       trace_event_id, "URL", client_url.spec());
-  storage()->FindRegistrationForClientUrl(
+  GetRemoteStorageControl()->FindRegistrationForClientUrl(
       client_url,
       base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForClientUrl,
                      weak_factory_.GetWeakPtr(), client_url, trace_event_id,
@@ -210,7 +210,7 @@
     return;
   }
 
-  storage()->FindRegistrationForScope(
+  GetRemoteStorageControl()->FindRegistrationForScope(
       scope, base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForScope,
                             weak_factory_.GetWeakPtr(), std::move(callback)));
 }
@@ -239,7 +239,7 @@
     return;
   }
 
-  storage()->FindRegistrationForId(
+  GetRemoteStorageControl()->FindRegistrationForId(
       registration_id, origin,
       base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForId,
                      weak_factory_.GetWeakPtr(), registration_id,
@@ -269,8 +269,8 @@
     return;
   }
 
-  storage()->FindRegistrationForIdOnly(
-      registration_id,
+  GetRemoteStorageControl()->FindRegistrationForId(
+      registration_id, /*origin=*/base::nullopt,
       base::BindOnce(&ServiceWorkerRegistry::DidFindRegistrationForId,
                      weak_factory_.GetWeakPtr(), registration_id,
                      std::move(callback)));
@@ -402,7 +402,7 @@
   }
   data->resources_total_size_bytes = resources_total_size_bytes;
 
-  storage()->StoreRegistrationData(
+  GetRemoteStorageControl()->StoreRegistration(
       std::move(data), std::move(resources),
       base::BindOnce(&ServiceWorkerRegistry::DidStoreRegistration,
                      weak_factory_.GetWeakPtr(), registration->id(),
@@ -425,7 +425,7 @@
   DCHECK(!registration->is_deleted())
       << "attempt to delete a registration twice";
 
-  storage()->DeleteRegistration(
+  GetRemoteStorageControl()->DeleteRegistration(
       registration->id(), origin,
       base::BindOnce(&ServiceWorkerRegistry::DidDeleteRegistration,
                      weak_factory_.GetWeakPtr(), registration->id(), origin,
@@ -625,8 +625,8 @@
                              blink::ServiceWorkerStatusCode::kErrorFailed));
       return;
     }
-    user_data.push_back(
-        storage::mojom::ServiceWorkerUserData::New(kv.first, kv.second));
+    user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+        registration_id, kv.first, kv.second));
   }
 
   GetRemoteStorageControl()->StoreUserData(
@@ -717,7 +717,7 @@
     return;
   }
 
-  storage()->GetUserDataForAllRegistrations(
+  GetRemoteStorageControl()->GetUserDataForAllRegistrations(
       key,
       base::BindOnce(&ServiceWorkerRegistry::DidGetUserDataForAllRegistrations,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
@@ -735,7 +735,7 @@
     return;
   }
 
-  storage()->GetUserDataForAllRegistrationsByKeyPrefix(
+  GetRemoteStorageControl()->GetUserDataForAllRegistrationsByKeyPrefix(
       key_prefix,
       base::BindOnce(&ServiceWorkerRegistry::DidGetUserDataForAllRegistrations,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
@@ -812,7 +812,9 @@
 scoped_refptr<ServiceWorkerRegistration>
 ServiceWorkerRegistry::GetOrCreateRegistration(
     const storage::mojom::ServiceWorkerRegistrationData& data,
-    const ResourceList& resources) {
+    const ResourceList& resources,
+    mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+        version_reference) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   scoped_refptr<ServiceWorkerRegistration> registration =
       context_->GetLiveRegistration(data.registration_id);
@@ -831,11 +833,9 @@
   scoped_refptr<ServiceWorkerVersion> version =
       context_->GetLiveVersion(data.version_id);
   if (!version) {
-    // TODO(crbug.com/1055677): Pass ServiceWorkerLiveVersionRef
     version = base::MakeRefCounted<ServiceWorkerVersion>(
         registration.get(), data.script, data.script_type, data.version_id,
-        mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>(),
-        context_->AsWeakPtr());
+        std::move(version_reference), context_->AsWeakPtr());
     version->set_fetch_handler_existence(
         data.has_fetch_handler
             ? ServiceWorkerVersion::FetchHandlerExistence::EXISTS
@@ -892,9 +892,8 @@
     const GURL& client_url,
     int64_t trace_event_id,
     FindRegistrationCallback callback,
-    storage::mojom::ServiceWorkerRegistrationDataPtr data,
-    std::unique_ptr<ResourceList> resources,
-    storage::mojom::ServiceWorkerDatabaseStatus database_status) {
+    storage::mojom::ServiceWorkerDatabaseStatus database_status,
+    storage::mojom::ServiceWorkerFindRegistrationResultPtr result) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk &&
       database_status !=
@@ -929,9 +928,12 @@
 
   scoped_refptr<ServiceWorkerRegistration> registration;
   if (status == blink::ServiceWorkerStatusCode::kOk) {
-    DCHECK(data);
-    DCHECK(resources);
-    registration = GetOrCreateRegistration(*data, *resources);
+    DCHECK(result);
+    DCHECK(result->registration);
+    DCHECK(result->version_reference);
+    registration =
+        GetOrCreateRegistration(*(result->registration), result->resources,
+                                std::move(result->version_reference));
   }
 
   TRACE_EVENT_ASYNC_END1(
@@ -942,9 +944,8 @@
 
 void ServiceWorkerRegistry::DidFindRegistrationForScope(
     FindRegistrationCallback callback,
-    storage::mojom::ServiceWorkerRegistrationDataPtr data,
-    std::unique_ptr<ResourceList> resources,
-    storage::mojom::ServiceWorkerDatabaseStatus database_status) {
+    storage::mojom::ServiceWorkerDatabaseStatus database_status,
+    storage::mojom::ServiceWorkerFindRegistrationResultPtr result) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk &&
       database_status !=
@@ -957,9 +958,12 @@
 
   scoped_refptr<ServiceWorkerRegistration> registration;
   if (status == blink::ServiceWorkerStatusCode::kOk) {
-    DCHECK(data);
-    DCHECK(resources);
-    registration = GetOrCreateRegistration(*data, *resources);
+    DCHECK(result);
+    DCHECK(result->registration);
+    DCHECK(result->version_reference);
+    registration =
+        GetOrCreateRegistration(*(result->registration), result->resources,
+                                std::move(result->version_reference));
   }
 
   CompleteFindNow(std::move(registration), status, std::move(callback));
@@ -968,9 +972,8 @@
 void ServiceWorkerRegistry::DidFindRegistrationForId(
     int64_t registration_id,
     FindRegistrationCallback callback,
-    storage::mojom::ServiceWorkerRegistrationDataPtr data,
-    std::unique_ptr<ResourceList> resources,
-    storage::mojom::ServiceWorkerDatabaseStatus database_status) {
+    storage::mojom::ServiceWorkerDatabaseStatus database_status,
+    storage::mojom::ServiceWorkerFindRegistrationResultPtr result) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
   if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk &&
       database_status !=
@@ -994,9 +997,12 @@
 
   scoped_refptr<ServiceWorkerRegistration> registration;
   if (status == blink::ServiceWorkerStatusCode::kOk) {
-    DCHECK(data);
-    DCHECK(resources);
-    registration = GetOrCreateRegistration(*data, *resources);
+    DCHECK(result);
+    DCHECK(result->registration);
+    DCHECK(result->version_reference);
+    registration =
+        GetOrCreateRegistration(*(result->registration), result->resources,
+                                std::move(result->version_reference));
   }
 
   CompleteFindNow(std::move(registration), status, std::move(callback));
@@ -1025,9 +1031,13 @@
   std::set<int64_t> registration_ids;
   std::vector<scoped_refptr<ServiceWorkerRegistration>> registrations;
   for (const auto& entry : entries) {
+    DCHECK(entry->registration);
+    DCHECK(entry->version_reference);
     registration_ids.insert(entry->registration->registration_id);
+    // TODO(crbug.com/1055677): Pass ServiceWorkerLiveVersionRef.
     registrations.push_back(
-        GetOrCreateRegistration(*entry->registration, entry->resources));
+        GetOrCreateRegistration(*entry->registration, entry->resources,
+                                std::move(entry->version_reference)));
   }
 
   // Add unstored registrations that are being installed.
@@ -1299,11 +1309,18 @@
 
 void ServiceWorkerRegistry::DidGetUserDataForAllRegistrations(
     GetUserDataForAllRegistrationsCallback callback,
-    const std::vector<std::pair<int64_t, std::string>>& user_data,
-    storage::mojom::ServiceWorkerDatabaseStatus status) {
+    storage::mojom::ServiceWorkerDatabaseStatus status,
+    std::vector<storage::mojom::ServiceWorkerUserDataPtr> entries) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+  // TODO(crbug.com/1055677): Update call sites of
+  // GetUserDataForAllRegistrations so that we can avoid converting mojo struct
+  // to a pair.
+  std::vector<std::pair<int64_t, std::string>> user_data;
   if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk)
     ScheduleDeleteAndStartOver();
+  for (auto& entry : entries) {
+    user_data.emplace_back(entry->registration_id, entry->value);
+  }
   std::move(callback).Run(user_data, DatabaseStatusToStatusCode(status));
 }
 
diff --git a/content/browser/service_worker/service_worker_registry.h b/content/browser/service_worker/service_worker_registry.h
index 01d7c59..992f53fd 100644
--- a/content/browser/service_worker/service_worker_registry.h
+++ b/content/browser/service_worker/service_worker_registry.h
@@ -260,7 +260,9 @@
 
   scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration(
       const storage::mojom::ServiceWorkerRegistrationData& data,
-      const ResourceList& resources);
+      const ResourceList& resources,
+      mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+          version_reference);
 
   // Looks up live registrations and returns an optional value which may contain
   // a "findable" registration. See the implementation of this method for
@@ -272,20 +274,17 @@
       const GURL& client_url,
       int64_t trace_event_id,
       FindRegistrationCallback callback,
-      storage::mojom::ServiceWorkerRegistrationDataPtr data,
-      std::unique_ptr<ResourceList> resources,
-      storage::mojom::ServiceWorkerDatabaseStatus database_status);
+      storage::mojom::ServiceWorkerDatabaseStatus database_status,
+      storage::mojom::ServiceWorkerFindRegistrationResultPtr result);
   void DidFindRegistrationForScope(
       FindRegistrationCallback callback,
-      storage::mojom::ServiceWorkerRegistrationDataPtr data,
-      std::unique_ptr<ResourceList> resources,
-      storage::mojom::ServiceWorkerDatabaseStatus database_status);
+      storage::mojom::ServiceWorkerDatabaseStatus database_status,
+      storage::mojom::ServiceWorkerFindRegistrationResultPtr result);
   void DidFindRegistrationForId(
       int64_t registration_id,
       FindRegistrationCallback callback,
-      storage::mojom::ServiceWorkerRegistrationDataPtr data,
-      std::unique_ptr<ResourceList> resources,
-      storage::mojom::ServiceWorkerDatabaseStatus database_status);
+      storage::mojom::ServiceWorkerDatabaseStatus database_status,
+      storage::mojom::ServiceWorkerFindRegistrationResultPtr result);
 
   void DidGetRegistrationsForOrigin(
       GetRegistrationsCallback callback,
@@ -337,8 +336,8 @@
                         storage::mojom::ServiceWorkerDatabaseStatus status);
   void DidGetUserDataForAllRegistrations(
       GetUserDataForAllRegistrationsCallback callback,
-      const std::vector<std::pair<int64_t, std::string>>& user_data,
-      storage::mojom::ServiceWorkerDatabaseStatus status);
+      storage::mojom::ServiceWorkerDatabaseStatus status,
+      std::vector<storage::mojom::ServiceWorkerUserDataPtr> entries);
 
   void DidGetNewRegistrationId(
       blink::mojom::ServiceWorkerRegistrationOptions options,
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index 06af36d..a759815 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -768,9 +768,10 @@
   switch (state_) {
     case STORAGE_STATE_DISABLED:
       RunSoon(FROM_HERE,
-              base::BindOnce(std::move(callback),
-                             std::vector<std::pair<int64_t, std::string>>(),
-                             ServiceWorkerDatabase::Status::kErrorDisabled));
+              base::BindOnce(
+                  std::move(callback),
+                  ServiceWorkerDatabase::Status::kErrorDisabled,
+                  std::vector<storage::mojom::ServiceWorkerUserDataPtr>()));
       return;
     case STORAGE_STATE_INITIALIZING:  // Fall-through.
     case STORAGE_STATE_UNINITIALIZED:
@@ -799,9 +800,10 @@
   switch (state_) {
     case STORAGE_STATE_DISABLED:
       RunSoon(FROM_HERE,
-              base::BindOnce(std::move(callback),
-                             std::vector<std::pair<int64_t, std::string>>(),
-                             ServiceWorkerDatabase::Status::kErrorDisabled));
+              base::BindOnce(
+                  std::move(callback),
+                  ServiceWorkerDatabase::Status::kErrorDisabled,
+                  std::vector<storage::mojom::ServiceWorkerUserDataPtr>()));
       return;
     case STORAGE_STATE_INITIALIZING:  // Fall-through.
     case STORAGE_STATE_UNINITIALIZED:
@@ -1556,11 +1558,12 @@
     scoped_refptr<base::SequencedTaskRunner> original_task_runner,
     const std::string& key,
     GetUserDataForAllRegistrationsInDBCallback callback) {
-  std::vector<std::pair<int64_t, std::string>> user_data;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
   ServiceWorkerDatabase::Status status =
       database->ReadUserDataForAllRegistrations(key, &user_data);
   original_task_runner->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback), user_data, status));
+      FROM_HERE,
+      base::BindOnce(std::move(callback), status, std::move(user_data)));
 }
 
 void ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefixInDB(
@@ -1568,12 +1571,13 @@
     scoped_refptr<base::SequencedTaskRunner> original_task_runner,
     const std::string& key_prefix,
     GetUserDataForAllRegistrationsInDBCallback callback) {
-  std::vector<std::pair<int64_t, std::string>> user_data;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
   ServiceWorkerDatabase::Status status =
       database->ReadUserDataForAllRegistrationsByKeyPrefix(key_prefix,
                                                            &user_data);
   original_task_runner->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback), user_data, status));
+      FROM_HERE,
+      base::BindOnce(std::move(callback), status, std::move(user_data)));
 }
 
 void ServiceWorkerStorage::DeleteAllDataForOriginsFromDB(
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
index 30a53c4..6cb186e 100644
--- a/content/browser/service_worker/service_worker_storage.h
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -107,8 +107,8 @@
   using GetUserKeysAndDataInDBCallback = storage::mojom::
       ServiceWorkerStorageControl::GetUserKeysAndDataByKeyPrefixCallback;
   using GetUserDataForAllRegistrationsInDBCallback = base::OnceCallback<void(
-      const std::vector<std::pair<int64_t, std::string>>& user_data,
-      ServiceWorkerDatabase::Status)>;
+      ServiceWorkerDatabase::Status,
+      std::vector<storage::mojom::ServiceWorkerUserDataPtr>)>;
 
   ~ServiceWorkerStorage();
 
diff --git a/content/browser/service_worker/service_worker_storage_control_impl.cc b/content/browser/service_worker/service_worker_storage_control_impl.cc
index 084aadf5..56ed554d 100644
--- a/content/browser/service_worker/service_worker_storage_control_impl.cc
+++ b/content/browser/service_worker/service_worker_storage_control_impl.cc
@@ -13,20 +13,6 @@
 
 namespace {
 
-void DidGetUserDataForAllRegistrations(
-    ServiceWorkerStorageControlImpl::GetUserDataForAllRegistrationsCallback
-        callback,
-    const std::vector<std::pair<int64_t, std::string>>& user_data,
-    storage::mojom::ServiceWorkerDatabaseStatus status) {
-  // TODO(bashi): Change ServiceWorkerStorage::GetUserDataForAllRegistrations()
-  // to return base::flat_map.
-  base::flat_map<int64_t, std::string> values;
-  for (auto& entry : user_data) {
-    values[entry.first] = entry.second;
-  }
-  std::move(callback).Run(status, std::move(values));
-}
-
 void DidGetAllRegistrations(
     ServiceWorkerStorageControlImpl::GetAllRegistrationsDeprecatedCallback
         callback,
@@ -346,17 +332,14 @@
 void ServiceWorkerStorageControlImpl::GetUserDataForAllRegistrations(
     const std::string& key,
     GetUserDataForAllRegistrationsCallback callback) {
-  storage_->GetUserDataForAllRegistrations(
-      key,
-      base::BindOnce(&DidGetUserDataForAllRegistrations, std::move(callback)));
+  storage_->GetUserDataForAllRegistrations(key, std::move(callback));
 }
 
 void ServiceWorkerStorageControlImpl::GetUserDataForAllRegistrationsByKeyPrefix(
     const std::string& key_prefix,
     GetUserDataForAllRegistrationsByKeyPrefixCallback callback) {
-  storage_->GetUserDataForAllRegistrationsByKeyPrefix(
-      key_prefix,
-      base::BindOnce(&DidGetUserDataForAllRegistrations, std::move(callback)));
+  storage_->GetUserDataForAllRegistrationsByKeyPrefix(key_prefix,
+                                                      std::move(callback));
 }
 
 void ServiceWorkerStorageControlImpl::
@@ -438,7 +421,8 @@
     int64_t deleted_version_id,
     const std::vector<int64_t>& newly_purgeable_resources) {
   MaybePurgeResources(deleted_version_id, newly_purgeable_resources);
-  std::move(callback).Run(status);
+  std::move(callback).Run(status, deleted_version_id,
+                          newly_purgeable_resources);
 }
 
 void ServiceWorkerStorageControlImpl::DidDeleteRegistration(
@@ -448,7 +432,8 @@
     int64_t deleted_version_id,
     const std::vector<int64_t>& newly_purgeable_resources) {
   MaybePurgeResources(deleted_version_id, newly_purgeable_resources);
-  std::move(callback).Run(status, origin_state);
+  std::move(callback).Run(status, origin_state, deleted_version_id,
+                          newly_purgeable_resources);
 }
 
 void ServiceWorkerStorageControlImpl::DidGetNewVersionId(
diff --git a/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc b/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
index 84c18897..c3cf229 100644
--- a/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
@@ -84,7 +84,7 @@
 
 struct GetUserDataForAllRegistrationsResult {
   DatabaseStatus status;
-  base::flat_map<int64_t, std::string> values;
+  std::vector<storage::mojom::ServiceWorkerUserDataPtr> values;
 };
 
 ReadResponseHeadResult ReadResponseHead(
@@ -282,10 +282,12 @@
     base::RunLoop loop;
     storage()->StoreRegistration(
         std::move(registration), std::move(resources),
-        base::BindLambdaForTesting([&](DatabaseStatus status) {
-          out_status = status;
-          loop.Quit();
-        }));
+        base::BindLambdaForTesting(
+            [&](DatabaseStatus status, int64_t /*=deleted_version_id*/,
+                const std::vector<int64_t>& /*=newly_purgeable_resources*/) {
+              out_status = status;
+              loop.Quit();
+            }));
     loop.Run();
     return out_status;
   }
@@ -298,7 +300,9 @@
         registration_id, origin,
         base::BindLambdaForTesting(
             [&](DatabaseStatus status,
-                storage::mojom::ServiceWorkerStorageOriginState origin_state) {
+                storage::mojom::ServiceWorkerStorageOriginState origin_state,
+                int64_t /*=deleted_version_id*/,
+                const std::vector<int64_t>& /*=newly_purgeable_resources*/) {
               result.status = status;
               result.origin_state = origin_state;
               loop.Quit();
@@ -533,13 +537,14 @@
     GetUserDataForAllRegistrationsResult result;
     base::RunLoop loop;
     storage()->GetUserDataForAllRegistrations(
-        key, base::BindLambdaForTesting(
-                 [&](DatabaseStatus status,
-                     const base::flat_map<int64_t, std::string>& values) {
-                   result.status = status;
-                   result.values = values;
-                   loop.Quit();
-                 }));
+        key,
+        base::BindLambdaForTesting(
+            [&](DatabaseStatus status,
+                std::vector<storage::mojom::ServiceWorkerUserDataPtr> values) {
+              result.status = status;
+              result.values = std::move(values);
+              loop.Quit();
+            }));
     loop.Run();
     return result;
   }
@@ -552,9 +557,9 @@
         key_prefix,
         base::BindLambdaForTesting(
             [&](DatabaseStatus status,
-                const base::flat_map<int64_t, std::string>& values) {
+                std::vector<storage::mojom::ServiceWorkerUserDataPtr> values) {
               result.status = status;
-              result.values = values;
+              result.values = std::move(values);
               loop.Quit();
             }));
     loop.Run();
@@ -1159,10 +1164,10 @@
   // Store user data with two entries.
   {
     std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
-    user_data.push_back(
-        storage::mojom::ServiceWorkerUserData::New("key1", "value1"));
-    user_data.push_back(
-        storage::mojom::ServiceWorkerUserData::New("key2", "value2"));
+    user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+        registration_id, "key1", "value1"));
+    user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+        registration_id, "key2", "value2"));
 
     status = StoreUserData(registration_id, kScope.GetOrigin(),
                            std::move(user_data));
@@ -1249,14 +1254,14 @@
 
   // Store some user data with prefixes.
   std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
-  user_data.push_back(
-      storage::mojom::ServiceWorkerUserData::New("prefixA", "value1"));
-  user_data.push_back(
-      storage::mojom::ServiceWorkerUserData::New("prefixA2", "value2"));
-  user_data.push_back(
-      storage::mojom::ServiceWorkerUserData::New("prefixB", "value3"));
-  user_data.push_back(
-      storage::mojom::ServiceWorkerUserData::New("prefixC", "value4"));
+  user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+      registration_id, "prefixA", "value1"));
+  user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+      registration_id, "prefixA2", "value2"));
+  user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+      registration_id, "prefixB", "value3"));
+  user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
+      registration_id, "prefixC", "value4"));
   status =
       StoreUserData(registration_id, kScope.GetOrigin(), std::move(user_data));
   ASSERT_EQ(status, DatabaseStatus::kOk);
@@ -1337,11 +1342,11 @@
   {
     std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "key1", "registration1_value1"));
+        registration_id1, "key1", "registration1_value1"));
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "key2", "registration1_value2"));
+        registration_id1, "key2", "registration1_value2"));
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "prefix1", "registration1_prefix_value1"));
+        registration_id1, "prefix1", "registration1_prefix_value1"));
     status = StoreUserData(registration_id1, kScope1.GetOrigin(),
                            std::move(user_data));
     ASSERT_EQ(status, DatabaseStatus::kOk);
@@ -1349,11 +1354,11 @@
   {
     std::vector<storage::mojom::ServiceWorkerUserDataPtr> user_data;
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "key1", "registration2_value1"));
+        registration_id1, "key1", "registration2_value1"));
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "key3", "registration2_value3"));
+        registration_id1, "key3", "registration2_value3"));
     user_data.push_back(storage::mojom::ServiceWorkerUserData::New(
-        "prefix2", "registration2_prefix_value2"));
+        registration_id1, "prefix2", "registration2_prefix_value2"));
     status = StoreUserData(registration_id2, kScope2.GetOrigin(),
                            std::move(user_data));
     ASSERT_EQ(status, DatabaseStatus::kOk);
@@ -1364,19 +1369,23 @@
   result = GetUserDataForAllRegistrations("key1");
   ASSERT_EQ(result.status, DatabaseStatus::kOk);
   ASSERT_EQ(result.values.size(), 2UL);
-  EXPECT_EQ(result.values[registration_id1], "registration1_value1");
-  EXPECT_EQ(result.values[registration_id2], "registration2_value1");
+  EXPECT_EQ(result.values[0]->registration_id, registration_id1);
+  EXPECT_EQ(result.values[0]->value, "registration1_value1");
+  EXPECT_EQ(result.values[1]->registration_id, registration_id2);
+  EXPECT_EQ(result.values[1]->value, "registration2_value1");
 
   // Get uncommon user data.
   result = GetUserDataForAllRegistrations("key2");
   ASSERT_EQ(result.status, DatabaseStatus::kOk);
   ASSERT_EQ(result.values.size(), 1UL);
-  EXPECT_EQ(result.values[registration_id1], "registration1_value2");
+  EXPECT_EQ(result.values[0]->registration_id, registration_id1);
+  EXPECT_EQ(result.values[0]->value, "registration1_value2");
 
   result = GetUserDataForAllRegistrations("key3");
   ASSERT_EQ(result.status, DatabaseStatus::kOk);
   ASSERT_EQ(result.values.size(), 1UL);
-  EXPECT_EQ(result.values[registration_id2], "registration2_value3");
+  EXPECT_EQ(result.values[0]->registration_id, registration_id2);
+  EXPECT_EQ(result.values[0]->value, "registration2_value3");
 
   // Getting unknown key succeeds but returns an empty value.
   // TODO(bashi): Make sure this is an intentional behavior. The existing
@@ -1392,14 +1401,17 @@
   result = GetUserDataForAllRegistrations("key1");
   ASSERT_EQ(result.status, DatabaseStatus::kOk);
   ASSERT_EQ(result.values.size(), 1UL);
-  EXPECT_EQ(result.values[registration_id2], "registration2_value1");
+  EXPECT_EQ(result.values[0]->registration_id, registration_id2);
+  EXPECT_EQ(result.values[0]->value, "registration2_value1");
 
   // Get prefixed user data.
   result = GetUserDataForAllRegistrationsByKeyPrefix("prefix");
   ASSERT_EQ(result.status, DatabaseStatus::kOk);
   ASSERT_EQ(result.values.size(), 2UL);
-  EXPECT_EQ(result.values[registration_id1], "registration1_prefix_value1");
-  EXPECT_EQ(result.values[registration_id2], "registration2_prefix_value2");
+  EXPECT_EQ(result.values[0]->registration_id, registration_id1);
+  EXPECT_EQ(result.values[0]->value, "registration1_prefix_value1");
+  EXPECT_EQ(result.values[1]->registration_id, registration_id2);
+  EXPECT_EQ(result.values[1]->value, "registration2_prefix_value2");
 
   // Clear prefixed user data.
   status = ClearUserDataForAllRegistrationsByKeyPrefix("prefix");
diff --git a/content/common/fetch/fetch_request_type_converters.cc b/content/common/fetch/fetch_request_type_converters.cc
index b4193c1..edb4772 100644
--- a/content/common/fetch/fetch_request_type_converters.cc
+++ b/content/common/fetch/fetch_request_type_converters.cc
@@ -5,7 +5,7 @@
 #include "content/common/fetch/fetch_request_type_converters.h"
 
 #include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/common/referrer.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "ui/base/page_transition_types.h"
 
 namespace mojo {
@@ -28,8 +28,7 @@
   if (input.request_body)
     output->body = input.request_body;
   output->referrer = blink::mojom::Referrer::New(
-      input.referrer, content::Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-                          input.referrer_policy));
+      input.referrer, blink::NetToMojoReferrerPolicy(input.referrer_policy));
   output->mode = input.mode;
   output->is_main_resource_load =
       content::ServiceWorkerUtils::IsMainRequestDestination(input.destination);
diff --git a/content/public/common/referrer.cc b/content/public/common/referrer.cc
index c306204..264634a 100644
--- a/content/public/common/referrer.cc
+++ b/content/public/common/referrer.cc
@@ -93,14 +93,6 @@
 }
 
 // static
-// TODO(minggang): Let the callers of this static method call
-// blink::NetToMojoReferrerPolicy() directly.
-network::mojom::ReferrerPolicy Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-    net::ReferrerPolicy net_policy) {
-  return blink::NetToMojoReferrerPolicy(net_policy);
-}
-
-// static
 net::ReferrerPolicy Referrer::GetDefaultReferrerPolicy() {
   // The ReducedReferrerGranularity feature sets the default referrer
   // policy to strict-origin-when-cross-origin unless forbidden
diff --git a/content/public/common/referrer.h b/content/public/common/referrer.h
index a6ef571..989b372 100644
--- a/content/public/common/referrer.h
+++ b/content/public/common/referrer.h
@@ -50,9 +50,6 @@
   static net::ReferrerPolicy ReferrerPolicyForUrlRequest(
       network::mojom::ReferrerPolicy referrer_policy);
 
-  static network::mojom::ReferrerPolicy NetReferrerPolicyToBlinkReferrerPolicy(
-      net::ReferrerPolicy net_policy);
-
   static net::ReferrerPolicy GetDefaultReferrerPolicy();
 
   // Configures retaining the pre-M80 default referrer
diff --git a/content/public/test/referrer_unittest.cc b/content/public/test/referrer_unittest.cc
index 0637fe79..fe243d2 100644
--- a/content/public/test/referrer_unittest.cc
+++ b/content/public/test/referrer_unittest.cc
@@ -9,6 +9,7 @@
 #include "content/public/common/content_features.h"
 #include "net/url_request/referrer_policy.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 
 namespace content {
 
@@ -104,7 +105,7 @@
 
   for (auto policy : policies) {
     EXPECT_EQ(Referrer::ReferrerPolicyForUrlRequest(
-                  Referrer::NetReferrerPolicyToBlinkReferrerPolicy(policy)),
+                  blink::NetToMojoReferrerPolicy(policy)),
               policy);
   }
 }
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index a5403d6..aa9c757 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -102,8 +102,6 @@
     "loader/child_url_loader_factory_bundle.h",
     "loader/navigation_body_loader.cc",
     "loader/navigation_body_loader.h",
-    "loader/navigation_response_override_parameters.cc",
-    "loader/navigation_response_override_parameters.h",
     "loader/request_extra_data.cc",
     "loader/request_extra_data.h",
     "loader/resource_dispatcher.cc",
diff --git a/content/renderer/loader/navigation_body_loader.cc b/content/renderer/loader/navigation_body_loader.cc
index de92640..230a8c0 100644
--- a/content/renderer/loader/navigation_body_loader.cc
+++ b/content/renderer/loader/navigation_body_loader.cc
@@ -6,11 +6,11 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "content/public/common/referrer.h"
 #include "content/renderer/loader/resource_load_stats.h"
 #include "content/renderer/loader/web_url_loader_impl.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "third_party/blink/public/platform/web_code_cache_loader.h"
 #include "third_party/blink/public/web/web_navigation_params.h"
 
@@ -68,8 +68,7 @@
     redirect.new_referrer =
         blink::WebString::FromUTF8(redirect_info.new_referrer);
     redirect.new_referrer_policy =
-        Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-            redirect_info.new_referrer_policy);
+        blink::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy);
     redirect.new_http_method =
         blink::WebString::FromLatin1(redirect_info.new_method);
     url = redirect_info.new_url;
diff --git a/content/renderer/loader/navigation_response_override_parameters.cc b/content/renderer/loader/navigation_response_override_parameters.cc
deleted file mode 100644
index 91be543..0000000
--- a/content/renderer/loader/navigation_response_override_parameters.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/loader/navigation_response_override_parameters.h"
-
-#include "base/callback.h"
-
-namespace content {
-
-NavigationResponseOverrideParameters::NavigationResponseOverrideParameters() =
-    default;
-
-NavigationResponseOverrideParameters::~NavigationResponseOverrideParameters() =
-    default;
-
-}  // namespace content
diff --git a/content/renderer/loader/navigation_response_override_parameters.h b/content/renderer/loader/navigation_response_override_parameters.h
deleted file mode 100644
index 78a2f3c..0000000
--- a/content/renderer/loader/navigation_response_override_parameters.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
-#define CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
-
-#include <vector>
-
-#include "content/common/content_export.h"
-#include "mojo/public/cpp/system/data_pipe.h"
-#include "net/url_request/redirect_info.h"
-#include "services/network/public/mojom/url_loader.mojom.h"
-#include "services/network/public/mojom/url_response_head.mojom-forward.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// Used to override parameters of the navigation request.
-struct CONTENT_EXPORT NavigationResponseOverrideParameters {
- public:
-  NavigationResponseOverrideParameters();
-  ~NavigationResponseOverrideParameters();
-
-  std::vector<GURL> redirects;
-  std::vector<network::mojom::URLResponseHeadPtr> redirect_responses;
-  std::vector<net::RedirectInfo> redirect_infos;
-  network::mojom::URLResponseHeadPtr response_head =
-      network::mojom::URLResponseHead::New();
-  mojo::ScopedDataPipeConsumerHandle response_body;
-  network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
diff --git a/content/renderer/loader/request_extra_data.h b/content/renderer/loader/request_extra_data.h
index c616553..c7e4451 100644
--- a/content/renderer/loader/request_extra_data.h
+++ b/content/renderer/loader/request_extra_data.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "content/common/content_export.h"
 #include "content/common/navigation_params.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/web_url_loader_impl.h"
 #include "third_party/blink/public/common/loader/url_loader_throttle.h"
 #include "third_party/blink/public/platform/web_frame_request_blocker.h"
@@ -42,18 +41,6 @@
     custom_user_agent_ = custom_user_agent;
   }
 
-  // |navigation_response_override| is used to override certain parameters of
-  // navigation requests.
-  std::unique_ptr<NavigationResponseOverrideParameters>
-  TakeNavigationResponseOverrideOwnership() {
-    return std::move(navigation_response_override_);
-  }
-
-  void set_navigation_response_override(
-      std::unique_ptr<NavigationResponseOverrideParameters> response_override) {
-    navigation_response_override_ = std::move(response_override);
-  }
-
   std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
   TakeURLLoaderThrottles() {
     return std::move(url_loader_throttles_);
@@ -82,8 +69,6 @@
   ~RequestExtraData() override;
 
   blink::WebString custom_user_agent_;
-  std::unique_ptr<NavigationResponseOverrideParameters>
-      navigation_response_override_;
   std::vector<std::unique_ptr<blink::URLLoaderThrottle>> url_loader_throttles_;
   scoped_refptr<blink::WebFrameRequestBlocker> frame_request_blocker_;
   bool allow_cross_origin_auth_prompt_ = false;
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc
index 4baa207..e0c5d36 100644
--- a/content/renderer/loader/resource_dispatcher.cc
+++ b/content/renderer/loader/resource_dispatcher.cc
@@ -148,7 +148,6 @@
   PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
   if (!request_info)
     return;
-  DCHECK(!request_info->navigation_response_override);
   request_info->local_response_start = base::TimeTicks::Now();
   request_info->remote_request_start = response_head->load_timing.request_start;
   // Now that response_start has been set, we can properly set the TimeTicks in
@@ -416,17 +415,13 @@
     std::unique_ptr<RequestPeer> peer,
     network::mojom::RequestDestination request_destination,
     int render_frame_id,
-    const GURL& request_url,
-    std::unique_ptr<NavigationResponseOverrideParameters>
-        navigation_response_override_params)
+    const GURL& request_url)
     : peer(std::move(peer)),
       request_destination(request_destination),
       render_frame_id(render_frame_id),
       url(request_url),
       response_url(request_url),
-      local_request_start(base::TimeTicks::Now()),
-      navigation_response_override(
-          std::move(navigation_response_override_params)) {}
+      local_request_start(base::TimeTicks::Now()) {}
 
 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {
 }
@@ -507,9 +502,7 @@
     uint32_t loader_options,
     std::unique_ptr<RequestPeer> peer,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-    std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
-    std::unique_ptr<NavigationResponseOverrideParameters>
-        response_override_params) {
+    std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles) {
   CheckSchemeForReferrerPolicy(*request);
 
 #if defined(OS_ANDROID)
@@ -521,15 +514,11 @@
   }
 #endif
 
-  bool override_url_loader =
-      !!response_override_params &&
-      !!response_override_params->url_loader_client_endpoints;
-
   // Compute a unique request_id for this renderer process.
   int request_id = MakeRequestID();
   pending_requests_[request_id] = std::make_unique<PendingRequestInfo>(
       std::move(peer), request->destination, request->render_frame_id,
-      request->url, std::move(response_override_params));
+      request->url);
   PendingRequestInfo* pending_request = pending_requests_[request_id].get();
 
   pending_request->resource_load_info = NotifyResourceLoadInitiated(
@@ -539,25 +528,6 @@
 
   pending_request->previews_state = request->previews_state;
 
-  if (override_url_loader) {
-    DCHECK(request->destination ==
-               network::mojom::RequestDestination::kWorker ||
-           request->destination ==
-               network::mojom::RequestDestination::kSharedWorker)
-        << request->destination;
-
-    // Redirect checks are handled by NavigationURLLoaderImpl, so it's safe to
-    // pass true for |bypass_redirect_checks|.
-    pending_request->url_loader_client = std::make_unique<URLLoaderClientImpl>(
-        request_id, this, loading_task_runner,
-        true /* bypass_redirect_checks */, request->url);
-
-    loading_task_runner->PostTask(
-        FROM_HERE, base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
-                                  weak_factory_.GetWeakPtr(), request_id));
-    return request_id;
-  }
-
   std::unique_ptr<URLLoaderClientImpl> client(new URLLoaderClientImpl(
       request_id, this, loading_task_runner,
       url_loader_factory->BypassRedirectChecks(), request->url));
@@ -614,52 +584,4 @@
                          &load_timing->service_worker_respond_with_settled);
 }
 
-// TODO(dgozman): this is not used for navigation anymore, only for worker
-// main script. Rename all related entities accordingly.
-void ResourceDispatcher::ContinueForNavigation(int request_id) {
-  PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
-  if (!request_info)
-    return;
-
-  std::unique_ptr<NavigationResponseOverrideParameters> response_override =
-      std::move(request_info->navigation_response_override);
-  DCHECK(response_override);
-
-  // Mark the request so we do not attempt to follow the redirects, they already
-  // happened.
-  request_info->should_follow_redirect = false;
-
-  URLLoaderClientImpl* client_ptr = request_info->url_loader_client.get();
-  // During navigations, the Response has already been received on the
-  // browser side, and has been passed down to the renderer. Replay the
-  // redirects that happened during navigation.
-  DCHECK_EQ(response_override->redirect_responses.size(),
-            response_override->redirect_infos.size());
-  for (size_t i = 0; i < response_override->redirect_responses.size(); ++i) {
-    client_ptr->OnReceiveRedirect(
-        response_override->redirect_infos[i],
-        std::move(response_override->redirect_responses[i]));
-    // The request might have been cancelled while processing the redirect.
-    if (!GetPendingRequestInfo(request_id))
-      return;
-  }
-
-  client_ptr->OnReceiveResponse(std::move(response_override->response_head));
-
-  // Abort if the request is cancelled.
-  if (!GetPendingRequestInfo(request_id))
-    return;
-
-  DCHECK(response_override->response_body.is_valid());
-  client_ptr->OnStartLoadingResponseBody(
-      std::move(response_override->response_body));
-
-  // Abort if the request is cancelled.
-  if (!GetPendingRequestInfo(request_id))
-    return;
-
-  DCHECK(response_override->url_loader_client_endpoints);
-  client_ptr->Bind(std::move(response_override->url_loader_client_endpoints));
-}
-
 }  // namespace content
diff --git a/content/renderer/loader/resource_dispatcher.h b/content/renderer/loader/resource_dispatcher.h
index 645c402..17466e2 100644
--- a/content/renderer/loader/resource_dispatcher.h
+++ b/content/renderer/loader/resource_dispatcher.h
@@ -57,7 +57,6 @@
 }
 
 namespace content {
-struct NavigationResponseOverrideParameters;
 class RequestPeer;
 class ResourceDispatcherDelegate;
 struct SyncLoadResponse;
@@ -123,9 +122,7 @@
       uint32_t loader_options,
       std::unique_ptr<RequestPeer> peer,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-      std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
-      std::unique_ptr<NavigationResponseOverrideParameters>
-          response_override_params);
+      std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles);
 
   // Removes a request from the |pending_requests_| list, returning true if the
   // request was found and removed.
@@ -183,9 +180,7 @@
     PendingRequestInfo(std::unique_ptr<RequestPeer> peer,
                        network::mojom::RequestDestination request_destination,
                        int render_frame_id,
-                       const GURL& request_url,
-                       std::unique_ptr<NavigationResponseOverrideParameters>
-                           response_override_params);
+                       const GURL& request_url);
 
     ~PendingRequestInfo();
 
@@ -203,8 +198,6 @@
     base::TimeTicks local_response_start;
     base::TimeTicks remote_request_start;
     net::LoadTimingInfo load_timing_info;
-    std::unique_ptr<NavigationResponseOverrideParameters>
-        navigation_response_override;
     bool should_follow_redirect = true;
     bool redirect_requires_loader_restart = false;
     // Network error code the request completed with, or net::ERR_IO_PENDING if
@@ -251,8 +244,6 @@
       const PendingRequestInfo& request_info,
       network::mojom::URLResponseHead& response_head) const;
 
-  void ContinueForNavigation(int request_id);
-
   // All pending requests issued to the host
   PendingRequestMap pending_requests_;
 
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc
index 12b4870..44c74d5 100644
--- a/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -23,7 +23,6 @@
 #include "content/public/common/referrer.h"
 #include "content/public/renderer/request_peer.h"
 #include "content/public/renderer/resource_dispatcher_delegate.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/request_extra_data.h"
 #include "content/renderer/loader/test_request_peer.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -145,8 +144,7 @@
         blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
         TRAFFIC_ANNOTATION_FOR_TESTS, false, std::move(peer),
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(this),
-        std::vector<std::unique_ptr<blink::URLLoaderThrottle>>(),
-        nullptr /* navigation_response_override_params */);
+        std::vector<std::unique_ptr<blink::URLLoaderThrottle>>());
     peer_context->request_id = request_id;
     return request_id;
   }
diff --git a/content/renderer/loader/sync_load_context.cc b/content/renderer/loader/sync_load_context.cc
index b246fe3e..929df29 100644
--- a/content/renderer/loader/sync_load_context.cc
+++ b/content/renderer/loader/sync_load_context.cc
@@ -12,7 +12,6 @@
 #include "base/optional.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/sync_load_response.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "net/url_request/redirect_info.h"
@@ -111,8 +110,7 @@
   context->request_id_ = context->resource_dispatcher_->StartAsync(
       std::move(request), routing_id, std::move(loading_task_runner),
       traffic_annotation, loader_options, base::WrapUnique(context),
-      context->url_loader_factory_, std::move(throttles),
-      nullptr /* navigation_response_override_params */);
+      context->url_loader_factory_, std::move(throttles));
 }
 
 SyncLoadContext::SyncLoadContext(
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc
index 0569dc79..e0890e5 100644
--- a/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -7,7 +7,6 @@
 #include <vector>
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/loader/test_request_peer.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -59,8 +58,7 @@
         std::make_unique<TestRequestPeer>(dispatcher_.get(),
                                           &request_peer_context_),
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(this),
-        std::vector<std::unique_ptr<blink::URLLoaderThrottle>>(),
-        nullptr /* navigation_response_override_params */);
+        std::vector<std::unique_ptr<blink::URLLoaderThrottle>>());
     request_peer_context_.request_id = request_id_;
 
     base::RunLoop().RunUntilIdle();
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 2064537..bbe0d38 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -36,7 +36,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/navigation_policy.h"
 #include "content/public/common/origin_util.h"
-#include "content/public/common/referrer.h"
 #include "content/public/renderer/request_peer.h"
 #include "content/renderer/loader/request_extra_data.h"
 #include "content/renderer/loader/resource_dispatcher.h"
@@ -66,6 +65,7 @@
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/loader/mime_sniffing_throttle.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "third_party/blink/public/common/loader/previews_state.h"
 #include "third_party/blink/public/common/loader/resource_type_util.h"
 #include "third_party/blink/public/common/mime_util/mime_util.h"
@@ -617,13 +617,6 @@
   url_ = request->url;
   report_raw_headers_ = request->report_raw_headers;
 
-  std::unique_ptr<NavigationResponseOverrideParameters> response_override;
-  if (passed_extra_data) {
-    RequestExtraData* extra_data =
-        static_cast<RequestExtraData*>(passed_extra_data.get());
-    response_override = extra_data->TakeNavigationResponseOverrideOwnership();
-  }
-
   // TODO(horo): Check credentials flag is unset when credentials mode is omit.
   //             Check credentials flag is set when credentials mode is include.
 
@@ -645,13 +638,6 @@
     request->load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   }
 
-  // The network request has already been made by the browser. The renderer
-  // should bind the URLLoaderClientEndpoints stored in |response_override| to
-  // an implementation of a URLLoaderClient to get the response body.
-  if (response_override) {
-    DCHECK(!sync_load_response);
-  }
-
   scoped_refptr<RequestExtraData> empty_extra_data;
   RequestExtraData* extra_data;
   if (passed_extra_data) {
@@ -721,7 +707,7 @@
   request_id_ = resource_dispatcher_->StartAsync(
       std::move(request), requestor_id, task_runner_,
       GetTrafficAnnotationTag(resource_type), loader_options, std::move(peer),
-      url_loader_factory_, std::move(throttles), std::move(response_override));
+      url_loader_factory_, std::move(throttles));
 
   if (defers_loading_ != NOT_DEFERRING)
     resource_dispatcher_->SetDefersLoading(request_id_, true);
@@ -751,8 +737,7 @@
   return client_->WillFollowRedirect(
       url_, redirect_info.new_site_for_cookies,
       WebString::FromUTF8(redirect_info.new_referrer),
-      Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-          redirect_info.new_referrer_policy),
+      blink::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy),
       WebString::FromUTF8(redirect_info.new_method), response,
       report_raw_headers_, removed_headers);
 }
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc
index 738a244..df27110 100644
--- a/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -20,7 +20,6 @@
 #include "base/time/time.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/renderer/request_peer.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/request_extra_data.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/loader/sync_load_response.h"
@@ -87,16 +86,13 @@
       uint32_t loader_options,
       std::unique_ptr<RequestPeer> peer,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-      std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles,
-      std::unique_ptr<NavigationResponseOverrideParameters>
-          navigation_response_override_params) override {
+      std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles)
+      override {
     EXPECT_FALSE(peer_);
     if (sync_load_response_.head->encoded_body_length != -1)
       EXPECT_TRUE(loader_options & network::mojom::kURLLoadOptionSynchronous);
     peer_ = std::move(peer);
     url_ = request->url;
-    navigation_response_override_params_ =
-        std::move(navigation_response_override_params);
     return 1;
   }
 
@@ -123,11 +119,6 @@
     sync_load_response_ = std::move(sync_load_response);
   }
 
-  std::unique_ptr<NavigationResponseOverrideParameters>
-  TakeNavigationResponseOverrideParams() {
-    return std::move(navigation_response_override_params_);
-  }
-
  private:
   std::unique_ptr<RequestPeer> peer_;
   bool canceled_;
@@ -135,8 +126,6 @@
   GURL url_;
   GURL stream_url_;
   SyncLoadResponse sync_load_response_;
-  std::unique_ptr<NavigationResponseOverrideParameters>
-      navigation_response_override_params_;
 
   DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher);
 };
@@ -466,47 +455,6 @@
   EXPECT_TRUE(dispatcher()->defers_loading());
 }
 
-// Checks that the response override parameters are properly applied.
-TEST_F(WebURLLoaderImplTest, ResponseOverride) {
-  // Initialize the request and the stream override.
-  const GURL kRequestURL = GURL(kTestURL);
-  const std::string kMimeType = "application/javascript";
-  auto response_override =
-      std::make_unique<NavigationResponseOverrideParameters>();
-  response_override->response_head->mime_type = kMimeType;
-  auto extra_data = base::MakeRefCounted<RequestExtraData>();
-  extra_data->set_navigation_response_override(std::move(response_override));
-
-  auto request = std::make_unique<network::ResourceRequest>();
-  request->url = kRequestURL;
-  request->resource_type =
-      static_cast<int>(blink::mojom::ResourceType::kScript);
-
-  client()->loader()->LoadAsynchronously(
-      std::move(request), std::move(extra_data), /*requestor_id=*/0,
-      /*download_to_network_cache_only=*/false, /*no_mime_sniffing=*/false,
-      client());
-
-  ASSERT_TRUE(peer());
-  EXPECT_EQ(kRequestURL, dispatcher()->url());
-  EXPECT_FALSE(client()->did_receive_response());
-
-  response_override = dispatcher()->TakeNavigationResponseOverrideParams();
-  ASSERT_TRUE(response_override);
-  peer()->OnReceivedResponse(std::move(response_override->response_head));
-
-  EXPECT_TRUE(client()->did_receive_response());
-
-  // The response info should have been overriden.
-  ASSERT_FALSE(client()->response().IsNull());
-  EXPECT_EQ(kMimeType, client()->response().MimeType().Latin1());
-
-  DoStartLoadingResponseBody();
-  DoCompleteRequest();
-  EXPECT_FALSE(dispatcher()->canceled());
-  EXPECT_TRUE(client()->did_receive_response_body());
-}
-
 TEST_F(WebURLLoaderImplTest, ResponseIPAddress) {
   GURL url("http://example.test/");
 
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.cc b/content/renderer/loader/web_worker_fetch_context_impl.cc
index 33bddb9..21a437d 100644
--- a/content/renderer/loader/web_worker_fetch_context_impl.cc
+++ b/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -467,15 +467,6 @@
     extra_data->set_url_loader_throttles(
         throttle_provider_->CreateThrottles(ancestor_frame_id_, request));
   }
-  if (response_override_) {
-    using RequestContextType = blink::mojom::RequestContextType;
-    DCHECK(
-        (base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker) &&
-         request.GetRequestContext() == RequestContextType::WORKER) ||
-        request.GetRequestContext() == RequestContextType::SHARED_WORKER)
-        << request.GetRequestContext();
-    extra_data->set_navigation_response_override(std::move(response_override_));
-  }
   request.SetExtraData(std::move(extra_data));
 
   if (g_rewrite_url)
@@ -579,12 +570,6 @@
   client_id_ = client_id;
 }
 
-void WebWorkerFetchContextImpl::SetResponseOverrideForMainScript(
-    std::unique_ptr<NavigationResponseOverrideParameters> response_override) {
-  DCHECK(!response_override_);
-  response_override_ = std::move(response_override);
-}
-
 void WebWorkerFetchContextImpl::OnControllerChanged(
     blink::mojom::ControllerServiceWorkerMode mode) {
   set_controller_service_worker_mode(mode);
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.h b/content/renderer/loader/web_worker_fetch_context_impl.h
index 7db9c68..a86b313 100644
--- a/content/renderer/loader/web_worker_fetch_context_impl.h
+++ b/content/renderer/loader/web_worker_fetch_context_impl.h
@@ -49,7 +49,6 @@
 class ThreadSafeSender;
 class URLLoaderThrottleProvider;
 class WebSocketHandshakeThrottleProvider;
-struct NavigationResponseOverrideParameters;
 
 // This class is used for fetching resource requests from workers (dedicated
 // worker and shared worker). This class is created on the main thread and
@@ -171,11 +170,6 @@
 
   void set_client_id(const std::string& client_id);
 
-  // PlzWorker with off-the-main-thread worker script fetch:
-  // Sets the response for the worker main script loaded by the browser process.
-  void SetResponseOverrideForMainScript(
-      std::unique_ptr<NavigationResponseOverrideParameters> response_override);
-
   using RewriteURLFunction = blink::WebURL (*)(base::StringPiece, bool);
   static void InstallRewriteURLFunction(RewriteURLFunction rewrite_url);
 
@@ -374,14 +368,11 @@
 
   std::vector<std::string> cors_exempt_header_list_;
 
-  std::unique_ptr<NavigationResponseOverrideParameters> response_override_;
-
   mojo::PendingRemote<blink::mojom::ResourceLoadInfoNotifier>
       pending_resource_load_info_notifier_;
 
   // Used to send the ResourceLoadInfo of the main script for dedicated
-  // workers only when
-  // IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled() is true.
+  // workers only when PlzDedicatedWorker is enabled.
   mojo::Remote<blink::mojom::ResourceLoadInfoNotifier>
       resource_load_info_notifier_;
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index cc5f3bb7..23b8582 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4628,7 +4628,6 @@
   // agent. This needs to be done here, after WebKit is through with setting the
   // user agent on its own.
   WebString custom_user_agent;
-  std::unique_ptr<NavigationResponseOverrideParameters> response_override;
   if (request.GetExtraData()) {
     RequestExtraData* old_extra_data =
         static_cast<RequestExtraData*>(request.GetExtraData().get());
@@ -4640,8 +4639,6 @@
       else
         request.SetHttpHeaderField("User-Agent", custom_user_agent);
     }
-    response_override =
-        old_extra_data->TakeNavigationResponseOverrideOwnership();
   }
 
   WebDocument frame_document = frame_->GetDocument();
@@ -4653,7 +4650,6 @@
   extra_data->set_render_frame_id(routing_id_);
   extra_data->set_is_main_frame(IsMainFrame());
   extra_data->set_transition_type(transition_type);
-  extra_data->set_navigation_response_override(std::move(response_override));
   bool is_for_no_state_prefetch =
       GetContentClient()->renderer()->IsPrefetchOnly(this, request);
   extra_data->set_is_for_no_state_prefetch(is_for_no_state_prefetch);
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 8bd0812e..6780010 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -491,7 +491,7 @@
                         const int32_t flags) override;
 
   // These are called for dedicated workers only when
-  // IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled() is true.
+  // PlzDedicatedWorker is enabled.
   // blink::mojom::ResourceLoadInfoNotifier implementation:
   void NotifyResourceRedirectReceived(
       const net::RedirectInfo& redirect_info,
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 07c7e50..c0200aa 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1323,7 +1323,7 @@
 RenderThreadImpl::GetCleanupTaskRunner() {
   return current_blink_platform_impl()
       ->main_thread_scheduler()
-      ->CleanupTaskRunner();
+      ->DefaultTaskRunner();
 }
 
 gpu::GpuMemoryBufferManager* RenderThreadImpl::GetGpuMemoryBufferManager() {
diff --git a/content/renderer/worker/dedicated_worker_host_factory_client.cc b/content/renderer/worker/dedicated_worker_host_factory_client.cc
index 98506b7..75e7ef8 100644
--- a/content/renderer/worker/dedicated_worker_host_factory_client.cc
+++ b/content/renderer/worker/dedicated_worker_host_factory_client.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 #include "content/renderer/loader/child_url_loader_factory_bundle.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/loader/web_worker_fetch_context_impl.h"
 #include "content/renderer/render_thread_impl.h"
@@ -14,7 +13,6 @@
 #include "content/renderer/worker/fetch_client_settings_object_helpers.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/loader/feature_utils.h"
 #include "third_party/blink/public/common/loader/worker_main_script_load_parameters.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
 #include "third_party/blink/public/common/tokens/tokens_mojom_traits.h"
@@ -83,8 +81,6 @@
                     ->CloneWithoutAppCacheFactory(),
                 std::move(pending_subresource_loader_updater_),
                 std::move(task_runner));
-    worker_fetch_context->SetResponseOverrideForMainScript(
-        std::move(response_override_for_main_script_));
   } else {
     worker_fetch_context =
         static_cast<WebWorkerFetchContextImpl*>(web_worker_fetch_context)
@@ -113,8 +109,6 @@
               ->resource_dispatcher()
               ->cors_exempt_header_list(),
           std::move(pending_resource_load_info_notifier));
-  worker_fetch_context->SetResponseOverrideForMainScript(
-      std::move(response_override_for_main_script_));
   return worker_fetch_context;
 }
 
@@ -159,37 +153,19 @@
 
   // Initialize the loading parameters for the main worker script loaded by
   // the browser process.
-  if (blink::IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled()) {
-    auto worker_main_script_load_params =
-        std::make_unique<blink::WorkerMainScriptLoadParameters>();
-    worker_main_script_load_params->response_head =
-        std::move(main_script_load_params->response_head);
-    worker_main_script_load_params->response_body =
-        std::move(main_script_load_params->response_body);
-    worker_main_script_load_params->redirect_responses =
-        std::move(main_script_load_params->redirect_response_heads);
-    worker_main_script_load_params->redirect_infos =
-        main_script_load_params->redirect_infos;
-    worker_main_script_load_params->url_loader_client_endpoints =
-        std::move(main_script_load_params->url_loader_client_endpoints);
-    worker_->OnScriptLoadStarted(std::move(worker_main_script_load_params));
-  } else {
-    DCHECK(!response_override_for_main_script_);
-    response_override_for_main_script_ =
-        std::make_unique<NavigationResponseOverrideParameters>();
-    response_override_for_main_script_->url_loader_client_endpoints =
-        std::move(main_script_load_params->url_loader_client_endpoints);
-    response_override_for_main_script_->response_head =
-        std::move(main_script_load_params->response_head);
-    response_override_for_main_script_->response_body =
-        std::move(main_script_load_params->response_body);
-    response_override_for_main_script_->redirect_responses =
-        std::move(main_script_load_params->redirect_response_heads);
-    response_override_for_main_script_->redirect_infos =
-        main_script_load_params->redirect_infos;
-
-    worker_->OnScriptLoadStarted(/*worker_main_script_load_params=*/nullptr);
-  }
+  auto worker_main_script_load_params =
+      std::make_unique<blink::WorkerMainScriptLoadParameters>();
+  worker_main_script_load_params->response_head =
+      std::move(main_script_load_params->response_head);
+  worker_main_script_load_params->response_body =
+      std::move(main_script_load_params->response_body);
+  worker_main_script_load_params->redirect_responses =
+      std::move(main_script_load_params->redirect_response_heads);
+  worker_main_script_load_params->redirect_infos =
+      main_script_load_params->redirect_infos;
+  worker_main_script_load_params->url_loader_client_endpoints =
+      std::move(main_script_load_params->url_loader_client_endpoints);
+  worker_->OnScriptLoadStarted(std::move(worker_main_script_load_params));
 }
 
 void DedicatedWorkerHostFactoryClient::OnScriptLoadStartFailed() {
diff --git a/content/renderer/worker/dedicated_worker_host_factory_client.h b/content/renderer/worker/dedicated_worker_host_factory_client.h
index a7601a45..315b658 100644
--- a/content/renderer/worker/dedicated_worker_host_factory_client.h
+++ b/content/renderer/worker/dedicated_worker_host_factory_client.h
@@ -26,7 +26,6 @@
 class ChildURLLoaderFactoryBundle;
 class ServiceWorkerProviderContext;
 class WebWorkerFetchContextImpl;
-struct NavigationResponseOverrideParameters;
 
 // DedicatedWorkerHostFactoryClient intermediates between
 // blink::(Web)DedicatedWorker and content::DedicatedWorkerHostFactory. This
@@ -89,8 +88,6 @@
       pending_subresource_loader_updater_;
 
   scoped_refptr<ServiceWorkerProviderContext> service_worker_provider_context_;
-  std::unique_ptr<NavigationResponseOverrideParameters>
-      response_override_for_main_script_;
 
   mojo::Remote<blink::mojom::DedicatedWorkerHostFactory> factory_;
   mojo::Receiver<blink::mojom::DedicatedWorkerHostFactoryClient> receiver_{
diff --git a/content/renderer/worker/embedded_shared_worker_stub.cc b/content/renderer/worker/embedded_shared_worker_stub.cc
index 01b4966..c8ce967 100644
--- a/content/renderer/worker/embedded_shared_worker_stub.cc
+++ b/content/renderer/worker/embedded_shared_worker_stub.cc
@@ -11,7 +11,6 @@
 #include "base/feature_list.h"
 #include "content/public/common/network_service_util.h"
 #include "content/renderer/loader/child_url_loader_factory_bundle.h"
-#include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/web_worker_fetch_context_impl.h"
 #include "content/renderer/worker/fetch_client_settings_object_helpers.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -64,36 +63,18 @@
 
   // Initialize the loading parameters for the main worker script loaded by
   // the browser process.
-  std::unique_ptr<blink::WorkerMainScriptLoadParameters>
-      worker_main_script_load_params;
-  std::unique_ptr<NavigationResponseOverrideParameters> response_override;
-  if (base::FeatureList::IsEnabled(
-          blink::features::kLoadMainScriptForPlzDedicatedWorkerByParams)) {
-    worker_main_script_load_params =
-        std::make_unique<blink::WorkerMainScriptLoadParameters>();
-    worker_main_script_load_params->response_head =
-        std::move(main_script_load_params->response_head);
-    worker_main_script_load_params->response_body =
-        std::move(main_script_load_params->response_body);
-    worker_main_script_load_params->redirect_responses =
-        std::move(main_script_load_params->redirect_response_heads);
-    worker_main_script_load_params->redirect_infos =
-        main_script_load_params->redirect_infos;
-    worker_main_script_load_params->url_loader_client_endpoints =
-        std::move(main_script_load_params->url_loader_client_endpoints);
-  } else {
-    response_override =
-        std::make_unique<NavigationResponseOverrideParameters>();
-    response_override->url_loader_client_endpoints =
-        std::move(main_script_load_params->url_loader_client_endpoints);
-    response_override->response_head =
-        std::move(main_script_load_params->response_head);
-    response_override->response_body =
-        std::move(main_script_load_params->response_body);
-    response_override->redirect_responses =
-        std::move(main_script_load_params->redirect_response_heads);
-    response_override->redirect_infos = main_script_load_params->redirect_infos;
-  }
+  auto worker_main_script_load_params =
+      std::make_unique<blink::WorkerMainScriptLoadParameters>();
+  worker_main_script_load_params->response_head =
+      std::move(main_script_load_params->response_head);
+  worker_main_script_load_params->response_body =
+      std::move(main_script_load_params->response_body);
+  worker_main_script_load_params->redirect_responses =
+      std::move(main_script_load_params->redirect_response_heads);
+  worker_main_script_load_params->redirect_infos =
+      main_script_load_params->redirect_infos;
+  worker_main_script_load_params->url_loader_client_endpoints =
+      std::move(main_script_load_params->url_loader_client_endpoints);
 
   // If the network service crashes, then self-destruct so clients don't get
   // stuck with a worker with a broken loader. Self-destruction is effectively
@@ -128,8 +109,7 @@
   scoped_refptr<blink::WebWorkerFetchContext> worker_fetch_context =
       CreateWorkerFetchContext(info->url, std::move(renderer_preferences),
                                std::move(preference_watcher_receiver),
-                               cors_exempt_header_list,
-                               std::move(response_override));
+                               cors_exempt_header_list);
 
   impl_ = blink::WebSharedWorker::CreateAndStart(
       token, info->url, info->options->type, info->options->credentials,
@@ -165,8 +145,7 @@
     const blink::mojom::RendererPreferences& renderer_preferences,
     mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
         preference_watcher_receiver,
-    const std::vector<std::string>& cors_exempt_header_list,
-    std::unique_ptr<NavigationResponseOverrideParameters> response_override) {
+    const std::vector<std::string>& cors_exempt_header_list) {
   // Make the factory used for service worker network fallback (that should
   // skip AppCache if it is provided).
   std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory =
@@ -191,13 +170,6 @@
   // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-07#section-2.1.2
   worker_fetch_context->set_site_for_cookies(net::SiteForCookies::FromUrl(url));
 
-  if (!base::FeatureList::IsEnabled(
-          blink::features::kLoadMainScriptForPlzDedicatedWorkerByParams)) {
-    DCHECK(response_override);
-    worker_fetch_context->SetResponseOverrideForMainScript(
-        std::move(response_override));
-  }
-
   return worker_fetch_context;
 }
 
diff --git a/content/renderer/worker/embedded_shared_worker_stub.h b/content/renderer/worker/embedded_shared_worker_stub.h
index 7ba6c8e..81d768d 100644
--- a/content/renderer/worker/embedded_shared_worker_stub.h
+++ b/content/renderer/worker/embedded_shared_worker_stub.h
@@ -46,7 +46,6 @@
 namespace content {
 
 class ChildURLLoaderFactoryBundle;
-struct NavigationResponseOverrideParameters;
 
 // A stub class to receive IPC from browser process and talk to
 // blink::WebSharedWorker. Implements blink::WebSharedWorkerClient.
@@ -100,8 +99,7 @@
       const blink::mojom::RendererPreferences& renderer_preferences,
       mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
           preference_watcher_receiver,
-      const std::vector<std::string>& cors_exempt_header_list,
-      std::unique_ptr<NavigationResponseOverrideParameters> response_override);
+      const std::vector<std::string>& cors_exempt_header_list);
 
   mojo::Receiver<blink::mojom::SharedWorker> receiver_;
   std::unique_ptr<blink::WebSharedWorker> impl_;
diff --git a/content/shell/renderer/web_test/web_frame_test_proxy.cc b/content/shell/renderer/web_test/web_frame_test_proxy.cc
index f2709d4c..9562666 100644
--- a/content/shell/renderer/web_test/web_frame_test_proxy.cc
+++ b/content/shell/renderer/web_test/web_frame_test_proxy.cc
@@ -18,6 +18,7 @@
 #include "content/shell/renderer/web_test/test_runner.h"
 #include "content/shell/renderer/web_test/web_view_test_proxy.h"
 #include "content/shell/renderer/web_test/web_widget_test_proxy.h"
+#include "third_party/blink/public/common/loader/network_utils.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_plugin_params.h"
 #include "third_party/blink/public/web/web_testing_support.h"
@@ -445,9 +446,8 @@
 
   if (test_runner()->ClearReferrer()) {
     request.SetReferrerString(blink::WebString());
-    request.SetReferrerPolicy(
-        content::Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-            content::Referrer::GetDefaultReferrerPolicy()));
+    request.SetReferrerPolicy(blink::NetToMojoReferrerPolicy(
+        content::Referrer::GetDefaultReferrerPolicy()));
   }
 
   std::string host = url.host();
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
index 168e0c13..42fb379 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
@@ -9,6 +9,7 @@
 #include "base/debug/dump_without_crashing.h"
 #include "base/logging.h"
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
+#include "gpu/ipc/common/gpu_client_ids.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/mac/io_surface.h"
 #include "ui/gl/buffer_format_utils.h"
@@ -117,17 +118,27 @@
 
   base::AutoLock lock(io_surfaces_lock_);
 
-  IOSurfaceMapKey key(handle.id, client_id);
-  IOSurfaceMap::iterator it = io_surfaces_.find(key);
-  if (it == io_surfaces_.end()) {
-    DLOG(ERROR) << "Failed to find IOSurface based on key.";
+  base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
+  if (handle.id.is_valid()) {
+    // Look up by the handle's ID, if one was specified.
+    IOSurfaceMapKey key(handle.id, client_id);
+    IOSurfaceMap::iterator it = io_surfaces_.find(key);
+    if (it != io_surfaces_.end())
+      io_surface = it->second;
+  } else if (gpu::IsReservedClientId(client_id) && handle.mach_port) {
+    // Use the handle's Mach port, if it was specified by an internal
+    // client.
+    io_surface.reset(IOSurfaceLookupFromMachPort(handle.mach_port.get()));
+  }
+  if (!io_surface) {
+    DLOG(ERROR) << "Failed to find IOSurface based on key or handle.";
     return scoped_refptr<gl::GLImage>();
   }
 
   unsigned internalformat = gl::BufferFormatToGLInternalFormat(format);
   scoped_refptr<gl::GLImageIOSurface> image(
       gl::GLImageIOSurface::Create(size, internalformat));
-  if (!image->Initialize(it->second.get(), handle.id, format)) {
+  if (!image->Initialize(io_surface, handle.id, format)) {
     DLOG(ERROR) << "Failed to initialize GLImage for IOSurface.";
     return scoped_refptr<gl::GLImage>();
   }
diff --git a/gpu/ipc/service/gpu_watchdog_thread_v2.cc b/gpu/ipc/service/gpu_watchdog_thread_v2.cc
index 063c5817..198c6f5 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_v2.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread_v2.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/native_library.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/process/process.h"
 #include "base/strings/string_number_conversions.h"
@@ -849,12 +850,14 @@
 }
 
 bool GpuWatchdogThreadImplV2::WithinOneMinFromPowerResumed() {
-  size_t count = base::TimeDelta::FromMinutes(1).IntDiv(watchdog_timeout_);
+  size_t count = base::ClampFloor<size_t>(base::TimeDelta::FromMinutes(1) /
+                                          watchdog_timeout_);
   return power_resumed_event_ && num_of_timeout_after_power_resume_ <= count;
 }
 
 bool GpuWatchdogThreadImplV2::WithinOneMinFromForegrounded() {
-  size_t count = base::TimeDelta::FromMinutes(1).IntDiv(watchdog_timeout_);
+  size_t count = base::ClampFloor<size_t>(base::TimeDelta::FromMinutes(1) /
+                                          watchdog_timeout_);
   return foregrounded_event_ && num_of_timeout_after_foregrounded_ <= count;
 }
 
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn
index cca72bc..2559225 100644
--- a/ios/chrome/app/application_delegate/BUILD.gn
+++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -69,6 +69,7 @@
     "//ios/chrome/browser/ui/safe_mode",
     "//ios/chrome/browser/ui/settings",
     "//ios/chrome/browser/ui/settings:settings_root",
+    "//ios/chrome/browser/ui/util:multiwindow_util",
     "//ios/chrome/browser/url_loading",
     "//ios/chrome/browser/web:tab_id_tab_helper",
     "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/app/application_delegate/app_state.h b/ios/chrome/app/application_delegate/app_state.h
index c0d157b..b6c63673 100644
--- a/ios/chrome/app/application_delegate/app_state.h
+++ b/ios/chrome/app/application_delegate/app_state.h
@@ -69,6 +69,12 @@
 // is shown. When there is no blocking UI shown in any scene, this is nil.
 @property(nonatomic, weak, readonly) SceneState* sceneShowingBlockingUI;
 
+// Indicates that this app launch is one after a crash.
+@property(nonatomic, assign) BOOL postCrashLaunch;
+
+// Indicates that session restoration might be required for connecting scenes.
+@property(nonatomic, assign) BOOL sessionRestorationRequired;
+
 // The last window which received a tap.
 @property(nonatomic, weak) UIWindow* lastTappedWindow;
 
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 4177c91..84586b3 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -575,11 +575,7 @@
 #pragma mark - SafeModeCoordinatorDelegate Implementation
 
 - (void)coordinatorDidExitSafeMode:(nonnull SafeModeCoordinator*)coordinator {
-  if (_safeModeBlocker) {
-    _safeModeBlocker.reset();
-  }
-  self.safeModeCoordinator = nil;
-  self.inSafeMode = NO;
+  [self stopSafeMode];
   [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
   [self.observers appStateDidExitSafeMode:self];
 
@@ -612,6 +608,14 @@
   }
 }
 
+- (void)stopSafeMode {
+  if (_safeModeBlocker) {
+    _safeModeBlocker.reset();
+  }
+  self.safeModeCoordinator = nil;
+  self.inSafeMode = NO;
+}
+
 - (void)initializeUI {
   _userInteracted = YES;
   [self saveLaunchDetailsToDefaults];
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index a00db0e..cb887a6 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -44,6 +44,7 @@
 #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h"
 #import "ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
+#import "ios/chrome/browser/ui/util/multi_window_support.h"
 #include "ios/chrome/test/block_cleanup_test.h"
 #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h"
 #include "ios/public/provider/chrome/browser/distribution/app_distribution_provider.h"
@@ -60,6 +61,12 @@
 #error "This file requires ARC support."
 #endif
 
+// Exposes private safe mode start/stop methods.
+@interface AppState (Private)
+- (void)startSafeMode;
+- (void)stopSafeMode;
+@end
+
 #pragma mark - Class definition.
 
 namespace {
@@ -74,6 +81,8 @@
     id<ConnectionInformation> connectionInformation,
     id<StartupInformation> startupInformation,
     ChromeBrowserState* browserState);
+// A block ths returns values of AppState connectedScenes.
+typedef NSArray<SceneState*>* (^ScenesBlock)(id self);
 
 class FakeAppDistributionProvider : public AppDistributionProvider {
  public:
@@ -207,6 +216,15 @@
     metrics_mediator_called_ = NO;
   }
 
+  void swizzleConnectedScenes(NSArray<SceneState*>* connectedScenes) {
+    connected_scenes_swizzle_block_ = ^NSArray<SceneState*>*(id self) {
+      return connectedScenes;
+    };
+    connected_scenes_swizzler_.reset(
+        new ScopedBlockSwizzler([AppState class], @selector(connectedScenes),
+                                connected_scenes_swizzle_block_));
+  }
+
   void swizzleSafeModeShouldStart(BOOL shouldStart) {
     safe_mode_swizzle_block_ = ^BOOL(id self) {
       return shouldStart;
@@ -278,9 +296,7 @@
                              metricsMediator:metricsMediator
                                 memoryHelper:memoryHelper
                                    tabOpener:tabOpener];
-    // TODO(crbug.com/1065815): Inject scene states for multiwindow as well.
-    app_state_.mainSceneState =
-        [[FakeSceneState alloc] initWithAppState:app_state_];
+
     initializeIncognitoBlocker(window);
 
     return appState;
@@ -288,26 +304,41 @@
 
   AppState* getAppStateWithMock() {
     if (!app_state_) {
+      // The swizzle block needs the scene state before app_state is create, but
+      // the scene state needs the app state. So this alloc before swizzling
+      // and initiate after app state is created.
+      main_scene_state_ = [FakeSceneState alloc];
+      swizzleConnectedScenes(@[ main_scene_state_ ]);
+
       app_state_ =
           [[AppState alloc] initWithBrowserLauncher:browser_launcher_mock_
                                  startupInformation:startup_information_mock_
                                 applicationDelegate:main_application_delegate_];
-      // TODO(crbug.com/1065815): Inject scene states for multiwindow as well.
-      app_state_.mainSceneState =
-          [[FakeSceneState alloc] initWithAppState:app_state_];
+      app_state_.mainSceneState = main_scene_state_;
+
+      main_scene_state_ = [main_scene_state_ initWithAppState:app_state_];
+      main_scene_state_.window = getWindowMock();
     }
     return app_state_;
   }
 
   AppState* getAppStateWithRealWindow(UIWindow* window) {
     if (!app_state_) {
+      // The swizzle block needs the scene state before app_state is create, but
+      // the scene state needs the app state. So this alloc before swizzling
+      // and initiate after app state is created.
+      main_scene_state_ = [FakeSceneState alloc];
+      swizzleConnectedScenes(@[ main_scene_state_ ]);
+
       app_state_ =
           [[AppState alloc] initWithBrowserLauncher:browser_launcher_mock_
                                  startupInformation:startup_information_mock_
                                 applicationDelegate:main_application_delegate_];
-      // TODO(crbug.com/1065815): Inject scene states for multiwindow as well.
-      app_state_.mainSceneState =
-          [[FakeSceneState alloc] initWithAppState:app_state_];
+      app_state_.mainSceneState = main_scene_state_;
+
+      main_scene_state_ = [main_scene_state_ initWithAppState:app_state_];
+      main_scene_state_.window = window;
+
       [window makeKeyAndVisible];
     }
     return app_state_;
@@ -334,16 +365,19 @@
  private:
   web::WebTaskEnvironment task_environment_;
   AppState* app_state_;
+  FakeSceneState* main_scene_state_;
   id browser_launcher_mock_;
   id connection_information_mock_;
   id startup_information_mock_;
   id main_application_delegate_;
   id window_;
   StubBrowserInterfaceProvider* interface_provider_;
+  ScenesBlock connected_scenes_swizzle_block_;
   DecisionBlock safe_mode_swizzle_block_;
   HandleStartupParam handle_startup_swizzle_block_;
   ProceduralBlock metrics_mediator_swizzle_block_;
   std::unique_ptr<ScopedBlockSwizzler> safe_mode_swizzler_;
+  std::unique_ptr<ScopedBlockSwizzler> connected_scenes_swizzler_;
   std::unique_ptr<ScopedBlockSwizzler> handle_startup_swizzler_;
   std::unique_ptr<ScopedBlockSwizzler> metrics_mediator_swizzler_;
   __block BOOL metrics_mediator_called_;
@@ -414,17 +448,24 @@
 
   appState.mainSceneState.activationLevel =
       SceneActivationLevelForegroundActive;
-  appState.mainSceneState.window = getWindowMock();
 
   // Action.
   BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
                                                  stateBackground:NO];
 
+  if (IsMultiwindowSupported()) {
+    [appState startSafeMode];
+  }
+
   // Test.
   EXPECT_TRUE(result);
   EXPECT_TRUE([appState isInSafeMode]);
   EXPECT_OCMOCK_VERIFY(browserLauncherMock);
   EXPECT_OCMOCK_VERIFY(windowMock);
+
+  if (IsMultiwindowSupported()) {
+    [appState stopSafeMode];
+  }
 }
 
 // Tests that if the application is active
@@ -545,6 +586,10 @@
 // Test that -resumeSessionWithTabOpener removes incognito blocker,
 // restart metrics and launchs from StartupParameters if they exist.
 TEST_F(AppStateTest, resumeSessionWithStartupParameters) {
+  if (IsSceneStartupSupported()) {
+    // TODO(crbug.com/1045579): Session restoration not available yet in MW.
+    return;
+  }
   // Setup.
 
   // BrowserLauncher.
@@ -596,6 +641,11 @@
 // restart metrics and creates a new tab from tab switcher if shouldOpenNTP is
 // YES.
 TEST_F(AppStateTest, resumeSessionShouldOpenNTPTabSwitcher) {
+  if (IsSceneStartupSupported()) {
+    // TODO(crbug.com/1045579): Session restoration not available yet in MW.
+    return;
+  }
+
   // Setup.
   // BrowserLauncher.
   StubBrowserInterfaceProvider* interfaceProvider = getInterfaceProvider();
@@ -642,6 +692,10 @@
 // Test that -resumeSessionWithTabOpener removes incognito blocker,
 // restart metrics and creates a new tab if shouldOpenNTP is YES.
 TEST_F(AppStateTest, resumeSessionShouldOpenNTPNoTabSwitcher) {
+  if (IsSceneStartupSupported()) {
+    // TODO(crbug.com/1045579): Session restoration not available yet in MW.
+    return;
+  }
   // Setup.
   // BrowserLauncher.
   StubBrowserInterfaceProvider* interfaceProvider = getInterfaceProvider();
@@ -790,6 +844,10 @@
 // application is in background.
 TEST_F(AppStateTest,
        applicationWillEnterForegroundFromBackgroundShouldStartSafeMode) {
+  if (IsMultiwindowSupported()) {
+    // In Multi Window, this is not the case. Skip this test.
+    return;
+  }
   // Setup.
   id application = [OCMockObject mockForClass:[UIApplication class]];
   id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 4baebba..f09fe31d 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -571,10 +571,10 @@
 }
 
 - (void)startUpBrowserForegroundInitialization {
-  BOOL postCrashLaunch = [self mustShowRestoreInfobar];
-  BOOL needRestore =
+  self.appState.postCrashLaunch = [self mustShowRestoreInfobar];
+  self.appState.sessionRestorationRequired =
       [self startUpBeforeFirstWindowCreatedAndPrepareForRestorationPostCrash:
-                postCrashLaunch];
+                self.appState.postCrashLaunch];
 
   if (@available(iOS 13, *)) {
     if (IsSceneStartupSupported()) {
@@ -585,8 +585,7 @@
   }
 
   SceneState* sceneState = self.appState.connectedScenes.firstObject;
-  [sceneState.controller startUpChromeUIPostCrash:postCrashLaunch
-                                  needRestoration:needRestore];
+  [sceneState.controller startUpChromeUI];
   [self startUpAfterFirstWindowCreated];
 }
 
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index ae7b10ee..692e15b 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -484,7 +484,7 @@
   if (IsSceneStartupSupported()) {
     // TODO(crbug.com/1012697): This should probably be the only code path for
     // UIScene and non-UIScene cases.
-    [self startUpChromeUIPostCrash:NO needRestoration:NO];
+    [self startUpChromeUI];
   }
 
   self.hasInitializedUI = YES;
@@ -493,8 +493,7 @@
 #pragma mark - private
 
 // Starts up a single chrome window and its UI.
-- (void)startUpChromeUIPostCrash:(BOOL)isPostCrashLaunch
-                 needRestoration:(BOOL)needsRestoration {
+- (void)startUpChromeUI {
   DCHECK(!self.browserViewWrangler);
   DCHECK(self.sceneURLLoadingService);
   DCHECK(self.mainController);
@@ -511,7 +510,7 @@
 
   // Only create the restoration helper if the browser state was backed up
   // successfully.
-  if (needsRestoration) {
+  if (self.sceneState.appState.sessionRestorationRequired) {
     self.mainController.restoreHelper =
         [[CrashRestoreHelper alloc] initWithBrowser:self.mainInterface.browser];
   }
@@ -523,7 +522,7 @@
   BOOL switchFromIncognito =
       startInIncognito && ![self.mainController canLaunchInIncognito];
 
-  if (isPostCrashLaunch || switchFromIncognito) {
+  if (self.sceneState.appState.postCrashLaunch || switchFromIncognito) {
     [self clearIOSSpecificIncognitoData];
     if (switchFromIncognito)
       [self.browserViewWrangler
diff --git a/ios/chrome/browser/ui/main/scene_controller_guts.h b/ios/chrome/browser/ui/main/scene_controller_guts.h
index 859227c..7f5e3489 100644
--- a/ios/chrome/browser/ui/main/scene_controller_guts.h
+++ b/ios/chrome/browser/ui/main/scene_controller_guts.h
@@ -7,17 +7,11 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/app/application_delegate/tab_opening.h"
-#import "ios/chrome/browser/procedural_block_types.h"
-#import "ios/chrome/browser/ui/tab_grid/tab_switcher.h"
-#import "ios/chrome/browser/url_loading/url_loading_params.h"
-
 @protocol SceneControllerGuts
 
 #pragma mark - iOS 12 compat
 
-- (void)startUpChromeUIPostCrash:(BOOL)isPostCrashLaunch
-                 needRestoration:(BOOL)needsRestoration;
+- (void)startUpChromeUI;
 
 @end
 
diff --git a/ios/chrome/browser/ui/main/test/fake_scene_state.mm b/ios/chrome/browser/ui/main/test/fake_scene_state.mm
index f6435bd..8e9f9dc 100644
--- a/ios/chrome/browser/ui/main/test/fake_scene_state.mm
+++ b/ios/chrome/browser/ui/main/test/fake_scene_state.mm
@@ -25,6 +25,7 @@
 @implementation FakeSceneState {
   // Owning pointer for the browser that backs the interface provider.
   std::unique_ptr<TestBrowser> _browser;
+  UIWindow* _window;
 }
 
 @synthesize interfaceProvider = _interfaceProvider;
@@ -65,4 +66,12 @@
   }
 }
 
+- (UIWindow*)window {
+  return _window;
+}
+
+- (void)setWindow:(UIWindow*)window {
+  _window = window;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.mm
index dab857c..10b0716 100644
--- a/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.mm
+++ b/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.mm
@@ -37,11 +37,11 @@
     return;
 
   if (self.repeatedFailure) {
-    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabReloadHistogramKey,
+    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabFeedbackHistogramKey,
                               ui_metrics::SadTabEvent::DISPLAYED,
                               ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
   } else {
-    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabFeedbackHistogramKey,
+    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabReloadHistogramKey,
                               ui_metrics::SadTabEvent::DISPLAYED,
                               ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
   }
diff --git a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
index 98d534b5..546903a 100644
--- a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
@@ -32,6 +32,7 @@
   ]
   deps = [
     ":safety_check_ui",
+    "//components/password_manager/core/browser",
     "//components/password_manager/core/common",
     "//components/prefs",
     "//components/safe_browsing/core:features",
@@ -41,6 +42,7 @@
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/content_settings",
     "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/passwords",
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h
index a855ad7..7772866 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h
@@ -7,10 +7,11 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_consumer.h"
 #import "ios/chrome/browser/ui/table_view/table_view_model.h"
 
 // Consumer protocol for safety check.
-@protocol SafetyCheckConsumer <NSObject>
+@protocol SafetyCheckConsumer <ChromeTableViewConsumer>
 
 // Initializes the check types section with |items|.
 - (void)setCheckItems:(NSArray<TableViewItem*>*)items;
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
index ca76dfc..7af06c58 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
@@ -7,6 +7,8 @@
 #include "base/mac/foundation_util.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/main/browser.h"
+#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
+#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
 #import "ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h"
 #import "ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h"
 #import "ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.h"
@@ -52,10 +54,13 @@
   self.viewController = viewController;
 
   self.mediator = [[SafetyCheckMediator alloc]
-      initWithUserPrefService:self.browser->GetBrowserState()->GetPrefs()];
+      initWithUserPrefService:self.browser->GetBrowserState()->GetPrefs()
+         passwordCheckManager:IOSChromePasswordCheckManagerFactory::
+                                  GetForBrowserState(
+                                      self.browser->GetBrowserState())];
   self.mediator.consumer = self.viewController;
-  [self.mediator updateConsumerCheckState];
-  viewController.serviceDelegate = self.mediator.delegate;
+  self.viewController.serviceDelegate = self.mediator;
+  self.viewController.presentationDelegate = self;
 
   DCHECK(self.baseNavigationController);
   [self.baseNavigationController pushViewController:self.viewController
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h
index 3d3684e..86b6f6d 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h
@@ -5,31 +5,34 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SAFETY_CHECK_SAFETY_CHECK_MEDIATOR_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_SAFETY_CHECK_SAFETY_CHECK_MEDIATOR_H_
 
+#import "ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h"
+
+#include "base/memory/scoped_refptr.h"
+
 #import <UIKit/UIKit.h>
 
+class IOSChromePasswordCheckManager;
 class PrefService;
 @protocol SafetyCheckConsumer;
-@protocol SafetyCheckServiceDelegate;
+
 @class SafetyCheckTableViewController;
 
 // The mediator is pushing the data for the safety check to the consumer.
-@interface SafetyCheckMediator : NSObject
-
-// The consumer for the Safety Check mediator.
-@property(nonatomic, weak) id<SafetyCheckConsumer> consumer;
-
-// The delegate for the Safety Check mediator, handles row taps.
-@property(nonatomic, weak) id<SafetyCheckServiceDelegate> delegate;
+@interface SafetyCheckMediator : NSObject <SafetyCheckServiceDelegate>
 
 // Designated initializer. All the parameters should not be null.
-// |userPrefService|: preference service from the browser state.
+// |userPrefService|: Preference service to access safe browsing state.
+// |passwordCheckManager|: Password check manager to enable use of the password
+// check service.
 - (instancetype)initWithUserPrefService:(PrefService*)userPrefService
-    NS_DESIGNATED_INITIALIZER;
+                   passwordCheckManager:
+                       (scoped_refptr<IOSChromePasswordCheckManager>)
+                           passwordCheckManager NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
 
-// Updates the consumer with the current check state.
-- (void)updateConsumerCheckState;
+// The consumer for the Safety Check mediator.
+@property(nonatomic, weak) id<SafetyCheckConsumer> consumer;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm
index 02321f2..d3857fb 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm
@@ -9,11 +9,14 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/core/features.h"
+#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
+#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
+#include "ios/chrome/browser/passwords/password_check_observer_bridge.h"
+#include "ios/chrome/browser/passwords/password_store_observer_bridge.h"
 #include "ios/chrome/browser/pref_names.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_check_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_multiline_detail_item.h"
 #import "ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h"
-#import "ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h"
 #import "ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/utils/observable_boolean.h"
 #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h"
@@ -50,45 +53,47 @@
 };
 
 // Enum with all possible states of the update check.
-typedef NS_ENUM(NSInteger, UpdateCheckStates) {
+typedef NS_ENUM(NSInteger, UpdateCheckRowStates) {
   // When the user is up to date.
-  UpdateCheckStateUpToDate,
+  UpdateCheckRowStateUpToDate,
   // When the check has not been run yet.
-  UpdateCheckStateDefault,
+  UpdateCheckRowStateDefault,
   // When the user is out of date.
-  UpdateCheckStateOutOfDate,
+  UpdateCheckRowStateOutOfDate,
   // When the user is managed.
-  UpdateCheckStateManaged,
+  UpdateCheckRowStateManaged,
+  // When the check is running.
+  UpdateCheckRowStateRunning,
 };
 
 // Enum with all possible states of the password check.
-typedef NS_ENUM(NSInteger, PasswordCheckStates) {
+typedef NS_ENUM(NSInteger, PasswordCheckRowStates) {
   // When no compromised passwords were detected.
-  PasswordCheckStateSafe,
+  PasswordCheckRowStateSafe,
   // When user has compromised passwords.
-  PasswordCheckStateUnSafe,
+  PasswordCheckRowStateUnSafe,
   // When check has not been run yet.
-  PasswordCheckStateDefault,
+  PasswordCheckRowStateDefault,
   // When password check is running.
-  PasswordCheckStateRunning,
+  PasswordCheckRowStateRunning,
   // When user has no passwords and check can't be performed.
-  PasswordCheckStateDisabled,
+  PasswordCheckRowStateDisabled,
   // When password check failed due to network issues, quota limit or others.
-  PasswordCheckStateError,
+  PasswordCheckRowStateError,
 };
 
 // Enum with all possible states of the Safe Browsing check.
-typedef NS_ENUM(NSInteger, SafeBrowsingCheckStates) {
+typedef NS_ENUM(NSInteger, SafeBrowsingCheckRowStates) {
   // When check was not run yet.
-  SafeBrowsingCheckStateDefault,
+  SafeBrowsingCheckRowStateDefault,
   // When Safe Browsing is managed by admin.
-  SafeBrowsingCheckStateManged,
+  SafeBrowsingCheckRowStateManged,
   // When the Safe Browsing check is running.
-  SafeBrowsingCheckStateRunning,
+  SafeBrowsingCheckRowStateRunning,
   // When Safe Browsing is enabled.
-  SafeBrowsingCheckStateSafe,
+  SafeBrowsingCheckRowStateSafe,
   // When Safe Browsing is disabled.
-  SafeBrowsingCheckStateUnsafe,
+  SafeBrowsingCheckRowStateUnsafe,
 };
 
 // Enum with all possible states of the button to start the check.
@@ -101,95 +106,131 @@
 
 }  // namespace
 
-@interface SafetyCheckMediator () <BooleanObserver>
+@interface SafetyCheckMediator () <BooleanObserver, PasswordCheckObserver> {
+  // A helper object for observing changes in the password check status
+  // and changes to the compromised credentials list.
+  std::unique_ptr<PasswordCheckObserverBridge> _passwordCheckObserver;
+}
 
 // SettingsCheckItem used to display the state of the Safe Browsing check.
 @property(nonatomic, strong) SettingsCheckItem* safeBrowsingCheckItem;
 
 // Current state of the Safe Browsing check.
-@property(nonatomic, assign) SafeBrowsingCheckStates safeBrowsingCheckState;
+@property(nonatomic, assign)
+    SafeBrowsingCheckRowStates safeBrowsingCheckRowState;
 
 // SettingsCheckItem used to display the state of the update check.
 @property(nonatomic, strong) SettingsCheckItem* updateCheckItem;
 
 // Current state of the update check.
-@property(nonatomic, assign) UpdateCheckStates updateCheckState;
+@property(nonatomic, assign) UpdateCheckRowStates updateCheckRowState;
 
 // SettingsCheckItem used to display the state of the password check.
 @property(nonatomic, strong) SettingsCheckItem* passwordCheckItem;
 
 // Current state of the password check.
-@property(nonatomic, assign) PasswordCheckStates passwordCheckState;
+@property(nonatomic, assign) PasswordCheckRowStates passwordCheckRowState;
 
 // Row button to start the safety check.
-@property(nonatomic, strong) SettingsMultilineDetailItem* startCheckItem;
+@property(nonatomic, strong) SettingsMultilineDetailItem* checkStartItem;
 
 // Current state of the start safety check row button.
-@property(nonatomic, assign) CheckStartStates startCheckState;
+@property(nonatomic, assign) CheckStartStates checkStartState;
 
 // Preference value for the "Safe Browsing" feature.
 @property(nonatomic, strong, readonly)
     PrefBackedBoolean* safeBrowsingPreference;
 
+// The service responsible for password check feature.
+@property(nonatomic, assign) scoped_refptr<IOSChromePasswordCheckManager>
+    passwordCheckManager;
+
+// Current state of password check.
+@property(nonatomic, assign) PasswordCheckState currentPasswordCheckState;
+
+// How many safety check items are still running (max 3).
+@property(nonatomic, assign) int checkRunningRemaining;
+
 @end
 
 @implementation SafetyCheckMediator
 
-- (instancetype)initWithUserPrefService:(PrefService*)userPrefService {
+- (instancetype)initWithUserPrefService:(PrefService*)userPrefService
+                   passwordCheckManager:
+                       (scoped_refptr<IOSChromePasswordCheckManager>)
+                           passwordCheckManager {
   self = [super init];
   if (self) {
     DCHECK(userPrefService);
+    DCHECK(passwordCheckManager);
+
+    _passwordCheckManager = passwordCheckManager;
+    _currentPasswordCheckState = _passwordCheckManager->GetPasswordCheckState();
+
+    _passwordCheckObserver = std::make_unique<PasswordCheckObserverBridge>(
+        self, _passwordCheckManager.get());
+
     _safeBrowsingPreference = [[PrefBackedBoolean alloc]
         initWithPrefService:userPrefService
                    prefName:prefs::kSafeBrowsingEnabled];
     _safeBrowsingPreference.observer = self;
 
-    _updateCheckState = UpdateCheckStateDefault;
-    _updateCheckItem = [[SettingsCheckItem alloc] initWithType:UpdateItemType];
+    _checkRunningRemaining = 0;
 
-    _passwordCheckState = PasswordCheckStateDefault;
+    _updateCheckRowState = UpdateCheckRowStateDefault;
+    _updateCheckItem = [[SettingsCheckItem alloc] initWithType:UpdateItemType];
+    _updateCheckItem.text =
+        l10n_util::GetNSString(IDS_IOS_SETTINGS_SAFETY_CHECK_UPDATES_TITLE);
+
+    _passwordCheckRowState = PasswordCheckRowStateDefault;
     _passwordCheckItem =
         [[SettingsCheckItem alloc] initWithType:PasswordItemType];
+    _passwordCheckItem.text =
+        l10n_util::GetNSString(IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE);
 
-    _safeBrowsingCheckState = SafeBrowsingCheckStateDefault;
+    _safeBrowsingCheckRowState = SafeBrowsingCheckRowStateDefault;
     _safeBrowsingCheckItem =
         [[SettingsCheckItem alloc] initWithType:SafeBrowsingItemType];
+    _safeBrowsingCheckItem.text = l10n_util::GetNSString(
+        IDS_IOS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_TITLE);
 
-    _startCheckState = CheckStartStateDefault;
-    _startCheckItem =
+    _checkStartState = CheckStartStateDefault;
+    _checkStartItem =
         [[SettingsMultilineDetailItem alloc] initWithType:CheckStartItemType];
+    _checkStartItem.text = GetNSString(IDS_IOS_CHECK_PASSWORDS_NOW_BUTTON);
   }
   return self;
 }
 
-#pragma mark - Private
-
-// Loads SectionIdentifierCheckTypes section.
-- (void)loadCheckTypesSection {
-  NSMutableArray* items = [NSMutableArray array];
-
-  self.updateCheckItem.text =
-      l10n_util::GetNSString(IDS_IOS_SETTINGS_SAFETY_CHECK_UPDATES_TITLE);
-  self.updateCheckItem.enabled = NO;
-  [items addObject:self.updateCheckItem];
-
-  self.passwordCheckItem.text =
-      l10n_util::GetNSString(IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE);
-  self.passwordCheckItem.enabled = NO;
-  [items addObject:self.passwordCheckItem];
-
-  self.safeBrowsingCheckItem.text =
-      l10n_util::GetNSString(IDS_IOS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_TITLE);
-  self.safeBrowsingCheckItem.enabled = NO;
-  [items addObject:self.safeBrowsingCheckItem];
-
-  [self.consumer setCheckItems:items];
+- (void)setConsumer:(id<SafetyCheckConsumer>)consumer {
+  if (_consumer == consumer)
+    return;
+  _consumer = consumer;
+  NSArray* checkItems = @[
+    self.updateCheckItem, self.passwordCheckItem, self.safeBrowsingCheckItem
+  ];
+  [_consumer setCheckItems:checkItems];
+  [_consumer setCheckStartItem:self.checkStartItem];
 }
 
-// Loads SectionIdentifierCheckStart section.
-- (void)loadCheckStartSection {
-  self.startCheckItem.text = GetNSString(IDS_IOS_CHECK_PASSWORDS_NOW_BUTTON);
-  [self.consumer setCheckStartItem:self.startCheckItem];
+#pragma mark - PasswordCheckObserver
+
+- (void)passwordCheckStateDidChange:(PasswordCheckState)state {
+  if (state == self.currentPasswordCheckState)
+    return;
+
+  self.passwordCheckRowState = [self computePasswordCheckRowState:state];
+  // Push update to the display.
+  [self reconfigurePasswordCheckItem];
+}
+
+- (void)compromisedCredentialsDidChange:
+    (password_manager::CompromisedCredentialsManager::CredentialsView)
+        credentials {
+  self.passwordCheckRowState =
+      [self computePasswordCheckRowState:self.currentPasswordCheckState];
+  // Push update to the display.
+  [self reconfigurePasswordCheckItem];
 }
 
 #pragma mark - SafetyCheckServiceDelegate
@@ -198,31 +239,238 @@
   ItemType type = static_cast<ItemType>(item.type);
   switch (type) {
     // TODO(crbug.com/1078782): Handle row taps.
-    case UpdateItemType:
+    case UpdateItemType: {
+      switch (self.updateCheckRowState) {
+        case UpdateCheckRowStateDefault:   // No tap action.
+        case UpdateCheckRowStateRunning:   // No tap action.
+        case UpdateCheckRowStateUpToDate:  // No tap action.
+          break;
+        case UpdateCheckRowStateManaged:
+          // Show popover.
+          break;
+        case UpdateCheckRowStateOutOfDate:
+          // Show popover and link to update page.
+          break;
+      }
       break;
-    case SafeBrowsingItemType:
+    }
+    case PasswordItemType: {
+      switch (self.passwordCheckRowState) {
+        case PasswordCheckRowStateDefault:  // No tap action.
+        case PasswordCheckRowStateRunning:  // No tap action.
+        case PasswordCheckRowStateSafe:     // No tap action.
+          break;
+        case PasswordCheckRowStateUnSafe:
+          // Link to compromised password page.
+          break;
+        case PasswordCheckRowStateDisabled:
+          // Popover for no passwords.
+          break;
+        case PasswordCheckRowStateError:
+          // Various popover states
+          break;
+      }
       break;
-    case PasswordItemType:
+    }
+    case SafeBrowsingItemType: {
+      switch (self.safeBrowsingCheckRowState) {
+        case SafeBrowsingCheckRowStateDefault:  // No tap action.
+        case SafeBrowsingCheckRowStateRunning:  // No tap action.
+        case SafeBrowsingCheckRowStateSafe:     // No tap action.
+          break;
+        case SafeBrowsingCheckRowStateManged:
+          // Managed state popover.
+          break;
+        case SafeBrowsingCheckRowStateUnsafe:
+          // Subtext about non advised, i state (sans popover) links to
+          // safebrowsing page.
+          break;
+      }
       break;
-    case CheckStartItemType:
+    }
+    case CheckStartItemType: {
+      [self checkStartOrCancel];
       break;
+    }
   }
 }
 
-#pragma mark - Public
-
-// Update the consumer with the current state of the safety check.
-// TODO(crbug.com/1078782): Have this handle more than the initial loading.
-- (void)updateConsumerCheckState {
-  [self loadCheckTypesSection];
-  [self loadCheckStartSection];
-}
-
 #pragma mark - BooleanObserver
 
 - (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean {
-  // TODO(crbug.com/1078782): Handle safe browsing state changes.
+  // TODO(crbug.com/1078782): Handle safe browsing state changes to reward user
+  // for fixing state.
   return;
 }
 
+#pragma mark - Private methods
+
+// Computes the appropriate display state of the password check row based on
+// currentPasswordCheckState.
+- (PasswordCheckRowStates)computePasswordCheckRowState:
+    (PasswordCheckState)newState {
+  BOOL wasRunning =
+      self.currentPasswordCheckState == PasswordCheckState::kRunning;
+  self.currentPasswordCheckState = newState;
+
+  switch (self.currentPasswordCheckState) {
+    case PasswordCheckState::kRunning:
+      return PasswordCheckRowStateRunning;
+    case PasswordCheckState::kNoPasswords:
+      return PasswordCheckRowStateDisabled;
+    case PasswordCheckState::kSignedOut:
+    case PasswordCheckState::kOffline:
+    case PasswordCheckState::kQuotaLimit:
+    case PasswordCheckState::kOther:
+      return self.passwordCheckManager->GetCompromisedCredentials().empty()
+                 ? PasswordCheckRowStateError
+                 : PasswordCheckRowStateUnSafe;
+    case PasswordCheckState::kCanceled:
+    case PasswordCheckState::kIdle: {
+      if (!self.passwordCheckManager->GetCompromisedCredentials().empty()) {
+        return PasswordCheckRowStateUnSafe;
+      } else if (self.currentPasswordCheckState == PasswordCheckState::kIdle) {
+        // Safe state is only possible after the state transitioned from
+        // kRunning to kIdle.
+        return (wasRunning) ? PasswordCheckRowStateSafe
+                            : PasswordCheckRowStateDefault;
+      }
+      return PasswordCheckRowStateDefault;
+    }
+  }
+}
+
+// Upon a tap of checkStartItem either starts or cancels a safety check.
+- (void)checkStartOrCancel {
+  // If a check is already running cancel it.
+  if (self.checkRunningRemaining > 0) {
+    // Reset check items to default.
+    self.updateCheckRowState = UpdateCheckRowStateDefault;
+    self.passwordCheckRowState = PasswordCheckRowStateDefault;
+    self.safeBrowsingCheckRowState = SafeBrowsingCheckRowStateDefault;
+
+    // Change checkStartItem to default state.
+    self.checkStartState = CheckStartStateDefault;
+
+    // Set remaining check running counter to 0.
+    self.checkRunningRemaining = 0;
+
+  } else {
+    // Otherwise start a check.
+
+    // Set check items to spinning wheel.
+    self.updateCheckRowState = UpdateCheckRowStateRunning;
+    self.passwordCheckRowState = PasswordCheckRowStateRunning;
+    self.safeBrowsingCheckRowState = SafeBrowsingCheckRowStateRunning;
+
+    // Change checkStartItem to cancel state.
+    self.checkStartState = CheckStartStateCancel;
+
+    // Set remaining check running counter to 3.
+    self.checkRunningRemaining = 3;
+  }
+
+  // Update the display.
+  [self reconfigureUpdateCheckItem];
+  [self reconfigurePasswordCheckItem];
+  [self reconfigureSafeBrowsingCheckItem];
+  [self reconfigureCheckStartSection];
+}
+
+// Reconfigures the display of the |updateCheckItem| based on current state of
+// |updateCheckRowState|.
+- (void)reconfigureUpdateCheckItem {
+  // Reset state to prevent conflicts.
+  self.updateCheckItem.enabled = YES;
+  self.updateCheckItem.indicatorHidden = YES;
+  self.updateCheckItem.infoButtonHidden = YES;
+  self.updateCheckItem.detailText = nil;
+  self.updateCheckItem.trailingImage = nil;
+
+  switch (self.updateCheckRowState) {
+    case UpdateCheckRowStateDefault: {
+      self.updateCheckItem.enabled = NO;
+      break;
+    }
+    case UpdateCheckRowStateRunning: {
+      self.updateCheckItem.indicatorHidden = NO;
+      break;
+    }
+    case UpdateCheckRowStateManaged:
+    case UpdateCheckRowStateUpToDate:
+    case UpdateCheckRowStateOutOfDate:
+      break;
+  }
+
+  [self.consumer reconfigureCellsForItems:@[ self.updateCheckItem ]];
+}
+
+// Reconfigures the display of the |passwordCheckItem| based on current state of
+// |passwordCheckRowState|.
+- (void)reconfigurePasswordCheckItem {
+  // Reset state to prevent conflicts.
+  self.passwordCheckItem.enabled = YES;
+  self.passwordCheckItem.indicatorHidden = YES;
+  self.passwordCheckItem.infoButtonHidden = YES;
+  self.passwordCheckItem.detailText = nil;
+  self.passwordCheckItem.trailingImage = nil;
+
+  switch (self.passwordCheckRowState) {
+    case PasswordCheckRowStateDefault: {
+      self.passwordCheckItem.enabled = NO;
+      break;
+    }
+    case PasswordCheckRowStateRunning: {
+      self.passwordCheckItem.indicatorHidden = NO;
+      break;
+    }
+    case PasswordCheckRowStateSafe:
+    case PasswordCheckRowStateUnSafe:
+    case PasswordCheckRowStateDisabled:
+    case PasswordCheckRowStateError:
+      break;
+  }
+
+  [self.consumer reconfigureCellsForItems:@[ self.passwordCheckItem ]];
+}
+
+// Reconfigures the display of the |safeBrowsingCheckItem| based on current
+// state of |safeBrowsingCheckRowState|.
+- (void)reconfigureSafeBrowsingCheckItem {
+  // Reset state to prevent conflicts.
+  self.safeBrowsingCheckItem.enabled = YES;
+  self.safeBrowsingCheckItem.indicatorHidden = YES;
+  self.safeBrowsingCheckItem.infoButtonHidden = YES;
+  self.safeBrowsingCheckItem.detailText = nil;
+  self.safeBrowsingCheckItem.trailingImage = nil;
+
+  switch (self.safeBrowsingCheckRowState) {
+    case SafeBrowsingCheckRowStateDefault: {
+      self.safeBrowsingCheckItem.enabled = NO;
+      break;
+    }
+    case SafeBrowsingCheckRowStateRunning: {
+      self.safeBrowsingCheckItem.indicatorHidden = NO;
+      break;
+    }
+    case SafeBrowsingCheckRowStateManged:
+    case SafeBrowsingCheckRowStateSafe:
+    case SafeBrowsingCheckRowStateUnsafe:
+      break;
+  }
+
+  [self.consumer reconfigureCellsForItems:@[ self.safeBrowsingCheckItem ]];
+}
+
+// Updates the display of checkStartItem based on its current state.
+- (void)reconfigureCheckStartSection {
+  if (self.checkStartState == CheckStartStateDefault) {
+    self.checkStartItem.text = GetNSString(IDS_IOS_CHECK_PASSWORDS_NOW_BUTTON);
+  } else {
+    self.checkStartItem.text =
+        GetNSString(IDS_IOS_CANCEL_PASSWORD_CHECK_BUTTON);
+  }
+  [self.consumer reconfigureCellsForItems:@[ self.checkStartItem ]];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h
index 64cad8ea..267b2de9 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h
@@ -5,6 +5,8 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SAFETY_CHECK_SAFETY_CHECK_SERVICE_DELEGATE_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_SAFETY_CHECK_SAFETY_CHECK_SERVICE_DELEGATE_H_
 
+#import <UIKit/UIKit.h>
+
 @class TableViewItem;
 
 // Protocol to handle user actions from the safety check view.
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.mm
index 0aef5fa..c460bf30 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.mm
@@ -78,6 +78,15 @@
   }
 }
 
+#pragma mark - UIViewController
+
+- (void)didMoveToParentViewController:(UIViewController*)parent {
+  [super didMoveToParentViewController:parent];
+  if (!parent) {
+    [self.presentationDelegate safetyCheckTableViewControllerDidRemove:self];
+  }
+}
+
 #pragma mark - UITableViewDelegate
 
 - (void)tableView:(UITableView*)tableView
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index b2ef430..c7ca81d 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -446,6 +446,7 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser:chrome_url_constants",
     "//ios/chrome/browser/ui/popup_menu:constants",
+    "//ios/chrome/browser/ui/util:multiwindow_util",
     "//ios/chrome/test:eg_test_support+eg2",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/net:test_support",
diff --git a/ios/chrome/browser/web/restore_egtest.mm b/ios/chrome/browser/web/restore_egtest.mm
index 65574a7c..408fd8d 100644
--- a/ios/chrome/browser/web/restore_egtest.mm
+++ b/ios/chrome/browser/web/restore_egtest.mm
@@ -5,6 +5,7 @@
 #include "base/bind.h"
 #include "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
+#import "ios/chrome/browser/ui/util/multi_window_support.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
@@ -200,6 +201,10 @@
 // Tests that only the selected web state is loaded Restore-after-Crash.  This
 // is only possible in EG2.
 - (void)testRestoreOneWebstateOnlyAfterCrash {
+  if (IsSceneStartupSupported()) {
+    // TODO(crbug.com/1108433): Session restoration not available yet in MW.
+    EARL_GREY_TEST_DISABLED(@"Disabled in Multiwindow.");
+  }
 #if defined(CHROME_EARL_GREY_2)
   // Visit the background page.
   int visitCounter = 0;
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index 46464e8..b878822 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -197,6 +197,7 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser:pref_names",
     "//ios/chrome/browser/ui:feature_flags",
+    "//ios/chrome/browser/ui/util:multiwindow_util",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//ios/third_party/earl_grey2:test_lib",
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm
index 3e0a993..4122e7b 100644
--- a/ios/chrome/test/earl_grey2/smoke_egtest.mm
+++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -7,6 +7,7 @@
 
 #include "ios/chrome/browser/pref_names.h"
 #import "ios/chrome/browser/ui/ui_feature_flags.h"
+#import "ios/chrome/browser/ui/util/multi_window_support.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_actions.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
@@ -258,6 +259,10 @@
 
 // Tests hard kill(crash) through AppLaunchManager.
 - (void)testAppLaunchManagerForceRelaunchByKilling {
+  if (IsSceneStartupSupported()) {
+    // TODO(crbug.com/1108395): Session restoration not available yet in MW.
+    EARL_GREY_TEST_DISABLED(@"Disabled in Multiwindow.");
+  }
   [ChromeEarlGrey openNewTab];
   [[AppLaunchManager sharedManager] ensureAppLaunchedWithFeaturesEnabled:{}
       disabled:{}
diff --git a/media/base/android/media_service_throttler_unittest.cc b/media/base/android/media_service_throttler_unittest.cc
index 78a9dcb..af3b45a 100644
--- a/media/base/android/media_service_throttler_unittest.cc
+++ b/media/base/android/media_service_throttler_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "media/base/android/media_service_throttler.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/test/task_environment.h"
 #include "media/base/android/media_server_crash_listener.h"
@@ -139,7 +140,8 @@
 // reset.
 TEST_F(MediaServiceThrottlerTest, NoCrash_LongInactivity_ShouldReset) {
   // Schedule two minutes' worth of clients.
-  SimulateClientCreations(base::TimeDelta::FromMinutes(2).IntDiv(base_delay_));
+  SimulateClientCreations(
+      base::ClampFloor(base::TimeDelta::FromMinutes(2) / base_delay_));
 
   // Advance the time so the scheduler perceived a full minute of inactivity.
   clock_.Advance(base::TimeDelta::FromSeconds(61));
@@ -263,7 +265,8 @@
   // Schedule many minutes worth of clients. This is to prove that the
   // MediaServerCrashListener's clean up happens after lack of requests, as
   // opposed to lack of actually scheduled clients.
-  SimulateClientCreations(base::TimeDelta::FromMinutes(3).IntDiv(base_delay_));
+  SimulateClientCreations(
+      base::ClampFloor(base::TimeDelta::FromMinutes(3) / base_delay_));
 
   // The MediaServerCrashListener should be alive, with 1s second to spare.
   clock_.Advance(base::TimeDelta::FromSeconds(59));
@@ -292,7 +295,8 @@
   // Schedule many minutes worth of clients. This is to prove that the
   // MediaServerCrashListener's clean up happens after lack of requests, as
   // opposed to lack of actually scheduled clients.
-  SimulateClientCreations(base::TimeDelta::FromMinutes(3).IntDiv(base_delay_));
+  SimulateClientCreations(
+      base::ClampFloor(base::TimeDelta::FromMinutes(3) / base_delay_));
 
   // The MediaServerCrashListener should be alive, with 1s second to spare.
   clock_.Advance(base::TimeDelta::FromSeconds(59));
diff --git a/media/base/stream_parser_buffer.h b/media/base/stream_parser_buffer.h
index a41e678..55b2fbe 100644
--- a/media/base/stream_parser_buffer.h
+++ b/media/base/stream_parser_buffer.h
@@ -62,9 +62,8 @@
     return DecodeTimestamp(ts_ - rhs);
   }
 
-  int64_t operator/(base::TimeDelta rhs) const = delete;
+  double operator/(base::TimeDelta rhs) const { return ts_ / rhs; }
   int64_t IntDiv(base::TimeDelta rhs) const { return ts_.IntDiv(rhs); }
-  double FltDiv(base::TimeDelta rhs) const { return ts_.FltDiv(rhs); }
 
   static DecodeTimestamp FromSecondsD(double seconds) {
     return DecodeTimestamp(base::TimeDelta::FromSecondsD(seconds));
diff --git a/media/capture/content/animated_content_sampler_unittest.cc b/media/capture/content/animated_content_sampler_unittest.cc
index ef17134..9ed778d 100644
--- a/media/capture/content/animated_content_sampler_unittest.cc
+++ b/media/capture/content/animated_content_sampler_unittest.cc
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/rect.h"
@@ -611,8 +612,8 @@
   base::TimeTicks last_present_time = frame_timestamps.front();
   for (Timestamps::const_iterator i = frame_timestamps.begin() + 1;
        i != frame_timestamps.end(); ++i) {
-    const size_t num_vsync_intervals = static_cast<size_t>(
-        (*i - last_present_time).IntDiv(GetParam().vsync_interval));
+    const size_t num_vsync_intervals = base::ClampFloor<size_t>(
+        (*i - last_present_time) / GetParam().vsync_interval);
     ASSERT_LT(0u, num_vsync_intervals);
     ASSERT_GT(display_counts.size(), num_vsync_intervals);  // Quit early.
     ++display_counts[num_vsync_intervals];
diff --git a/media/cast/sender/frame_sender.cc b/media/cast/sender/frame_sender.cc
index 00f61fac..e00b080 100644
--- a/media/cast/sender/frame_sender.cc
+++ b/media/cast/sender/frame_sender.cc
@@ -463,8 +463,8 @@
   if (VLOG_IS_ON(1)) {
     const int64_t percent =
         allowed_in_flight > base::TimeDelta()
-            ? base::ClampRound<int64_t>(
-                  duration_would_be_in_flight.FltDiv(allowed_in_flight) * 100)
+            ? base::ClampRound<int64_t>(duration_would_be_in_flight /
+                                        allowed_in_flight * 100)
             : std::numeric_limits<int64_t>::max();
     VLOG_IF(1, percent > 50)
         << SENDER_SSRC
diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc
index d2374c7..a7b81d9 100644
--- a/media/filters/source_buffer_stream_unittest.cc
+++ b/media/filters/source_buffer_stream_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/bind_helpers.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -305,8 +306,9 @@
         }
       }
 
-      EXPECT_EQ(buffer->GetDecodeTimestamp().IntDiv(frame_duration_),
-                current_position);
+      EXPECT_EQ(
+          base::ClampFloor(buffer->GetDecodeTimestamp() / frame_duration_),
+          current_position);
     }
 
     EXPECT_EQ(ending_position + 1, current_position);
diff --git a/media/filters/video_cadence_estimator_unittest.cc b/media/filters/video_cadence_estimator_unittest.cc
index 9e76b1a..c2a4e7f 100644
--- a/media/filters/video_cadence_estimator_unittest.cc
+++ b/media/filters/video_cadence_estimator_unittest.cc
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
@@ -307,7 +308,7 @@
   const base::TimeDelta acceptable_drift =
       frame_interval < render_interval ? render_interval : frame_interval;
   const base::TimeDelta test_runtime = base::TimeDelta::FromSeconds(10 * 60);
-  const int test_frames = test_runtime.IntDiv(frame_interval);
+  const int test_frames = base::ClampFloor(test_runtime / frame_interval);
 
   estimator->Reset();
   EXPECT_TRUE(estimator->UpdateCadenceEstimate(
diff --git a/net/cert/cert_verify_proc_builtin_unittest.cc b/net/cert/cert_verify_proc_builtin_unittest.cc
index 7b67087..43b2d2d 100644
--- a/net/cert/cert_verify_proc_builtin_unittest.cc
+++ b/net/cert/cert_verify_proc_builtin_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/cert/cert_verify_proc_builtin.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
@@ -176,7 +177,8 @@
       CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
       base::TimeDelta::FromMilliseconds(1);
   const int expected_request_count =
-      GetCertVerifyProcBuiltinTimeLimitForTesting().IntDiv(timeout_increment) +
+      base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
+                       timeout_increment) +
       1;
 
   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
@@ -248,7 +250,8 @@
       CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
       base::TimeDelta::FromMilliseconds(1);
   const int expected_request_count =
-      GetCertVerifyProcBuiltinTimeLimitForTesting().IntDiv(timeout_increment) +
+      base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
+                       timeout_increment) +
       1;
 
   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
@@ -326,7 +329,8 @@
       CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
       base::TimeDelta::FromMilliseconds(1);
   const int expected_request_count =
-      GetCertVerifyProcBuiltinTimeLimitForTesting().IntDiv(timeout_increment) +
+      base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
+                       timeout_increment) +
       1;
 
   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
diff --git a/net/dns/httpssvc_metrics.cc b/net/dns/httpssvc_metrics.cc
index 77b3bfcd..58a033a 100644
--- a/net/dns/httpssvc_metrics.cc
+++ b/net/dns/httpssvc_metrics.cc
@@ -208,8 +208,8 @@
   // Computation happens on TimeDelta objects, which use CheckedNumeric. This
   // will crash if the system clock leaps forward several hundred millennia
   // (numeric_limits<int64_t>::max() microseconds ~= 292,000 years).
-  const int64_t resolve_time_percent =
-      (100 * *integrity_resolve_time_).IntDiv(*slowest_non_integrity_resolve);
+  const int64_t resolve_time_percent = base::ClampFloor<int64_t>(
+      *integrity_resolve_time_ / *slowest_non_integrity_resolve * 100);
 
   // Scale the value of |resolve_time_percent| by dividing by |kPercentScale|.
   // Sample values are bounded between 1 and 20. A recorded sample of 10 means
diff --git a/net/dns/resolve_context.cc b/net/dns/resolve_context.cc
index d33504af..57b75f656 100644
--- a/net/dns/resolve_context.cc
+++ b/net/dns/resolve_context.cc
@@ -408,7 +408,7 @@
       // continue in parallel with new attempts made by the transaction. Scale
       // the ratio up by 10 for sub-integer granularity.
       // TODO(crbug.com/1105138): Remove after determining good timeout logic.
-      int timeout_ratio = (10 * rtt).IntDiv(base_timeout);
+      int timeout_ratio = base::ClampFloor(rtt / base_timeout * 10);
       UMA_HISTOGRAM_COUNTS_1000(
           "Net.DNS.DnsTransaction.SecureValidated.SuccessTimeoutRatio",
           timeout_ratio);
diff --git a/remoting/test/cyclic_frame_generator.cc b/remoting/test/cyclic_frame_generator.cc
index 7f12451..dc9a4a7 100644
--- a/remoting/test/cyclic_frame_generator.cc
+++ b/remoting/test/cyclic_frame_generator.cc
@@ -4,6 +4,7 @@
 
 #include "remoting/test/cyclic_frame_generator.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "base/time/default_tick_clock.h"
 #include "remoting/test/frame_generator_util.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
@@ -49,9 +50,10 @@
     webrtc::SharedMemoryFactory* shared_memory_factory) {
   base::TimeTicks now = clock_->NowTicks();
 
-  int frame_id = (now - started_time_).IntDiv(cursor_blink_period_);
-  int reference_frame = (now - started_time_).IntDiv(frame_cycle_period_) %
-                        reference_frames_.size();
+  int frame_id = base::ClampFloor((now - started_time_) / cursor_blink_period_);
+  int reference_frame =
+      base::ClampFloor((now - started_time_) / frame_cycle_period_) %
+      reference_frames_.size();
   bool cursor_state = frame_id % 2;
 
   auto frame = std::make_unique<webrtc::BasicDesktopFrame>(screen_size_);
@@ -88,11 +90,13 @@
 
 CyclicFrameGenerator::ChangeInfoList CyclicFrameGenerator::GetChangeList(
     base::TimeTicks timestamp) {
-  int frame_id = (timestamp - started_time_).IntDiv(cursor_blink_period_);
+  int frame_id =
+      base::ClampFloor((timestamp - started_time_) / cursor_blink_period_);
   CHECK_GE(frame_id, last_identifier_frame_);
 
   ChangeInfoList result;
-  const int frames_in_cycle = frame_cycle_period_.IntDiv(cursor_blink_period_);
+  const int frames_in_cycle =
+      base::ClampFloor(frame_cycle_period_ / cursor_blink_period_);
   for (int i = last_identifier_frame_ + 1; i <= frame_id; ++i) {
     ChangeType type =
         (i % frames_in_cycle == 0) ? ChangeType::FULL : ChangeType::CURSOR;
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json
index 553e4a3..57578f8d 100644
--- a/testing/buildbot/chromium.ci.json
+++ b/testing/buildbot/chromium.ci.json
@@ -76879,6 +76879,26 @@
         "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/"
       },
       {
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
         "args": [
           "--gtest_filter=-*UsingRealWebcam*"
         ],
@@ -77621,6 +77641,25 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
+        "test": "nacl_loader_unittests",
+        "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/"
+      },
+      {
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
         "test": "native_theme_unittests",
         "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/"
       },
@@ -78341,6 +78380,31 @@
       },
       {
         "args": [
+          "--extra-browser-args=--enable-crashpad"
+        ],
+        "isolate_name": "telemetry_perf_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "telemetry_perf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/"
+      },
+      {
+        "args": [
           "--jobs=1",
           "--extra-browser-args=--disable-gpu"
         ],
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index f6d71a5..26e8488 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -8625,6 +8625,26 @@
         "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/"
       },
       {
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
         "args": [
           "--gtest_filter=-*UsingRealWebcam*"
         ],
@@ -9367,6 +9387,25 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
+        "test": "nacl_loader_unittests",
+        "test_id_prefix": "ninja://components/nacl/loader:nacl_loader_unittests/"
+      },
+      {
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
         "test": "native_theme_unittests",
         "test_id_prefix": "ninja://ui/native_theme:native_theme_unittests/"
       },
@@ -10087,6 +10126,31 @@
       },
       {
         "args": [
+          "--extra-browser-args=--enable-crashpad"
+        ],
+        "isolate_name": "telemetry_perf_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "telemetry_perf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "none",
+              "os": "Mac-10.13.6"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 12
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/"
+      },
+      {
+        "args": [
           "--jobs=1",
           "--extra-browser-args=--disable-gpu"
         ],
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index c7761625..d7599c4 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -443,7 +443,6 @@
       'ToTLinuxTSan',  # https://crbug.com/368525
       'Mac10.10 Tests',  # https://crbug.com/828031
       'Mac10.13 Tests',  # https://crbug.com/1042757
-      'Mac10.13 Tests Code Coverage',
       'Linux TSan Tests',  # https://crbug.com/368525
       'Win10 Tests x64 (dbg)',
       'linux-lacros-tester-rel', # https://crbug.com/1111979
@@ -1763,7 +1762,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Mac ASan 64 Tests (1)',
       'ToTMacASan',
     ],
@@ -1811,7 +1809,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Mac ASan 64 Tests (1)',
       'ToTMacASan',
     ],
@@ -1829,7 +1826,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Mac ASan 64 Tests (1)',
       'ToTMacASan',
     ],
@@ -1846,7 +1842,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Mac ASan 64 Tests (1)',
       'ToTMacASan',
     ],
@@ -1868,7 +1863,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Mac ASan 64 Tests (1)',
       'ToTMacASan',
     ],
@@ -2477,7 +2471,6 @@
       'Mac10.11 Tests',
       'Mac10.13 Tests',
       'Mac10.13 Tests (dbg)',
-      'Mac10.13 Tests Code Coverage',
       'Linux - Future (dbg)',  # client.v8.chromium
       'Win10 Tests x64',
       'Win10 Tests x64 (dbg)',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 084a6e8..4495481 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -4340,7 +4340,7 @@
             'no_gpu',
         ],
         'test_suites': {
-          'gtest_tests': 'chromium_mac_gtests_no_nacl',
+          'gtest_tests': 'chromium_mac_gtests',
           'isolated_scripts': 'chromium_mac_rel_isolated_scripts',
         },
       },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index e3d7a88c..c200eb2 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4224,6 +4224,21 @@
             ]
         }
     ],
+    "MediaApp": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "MediaApp"
+                    ]
+                }
+            ]
+        }
+    ],
     "MediaFoundationAsyncH264Encoding": [
         {
             "platforms": [
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index cb4beff..076f0b2 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -20,21 +20,14 @@
 
 2. Copy the content of the Abseil git repo to //third_party/abseil-cpp.
 
-3. From //third_party/abseil-cpp/ launch ./rename_annotations.sh.
-   This script will rewrite dynamic_annotations and thread_annotations
-   macros and function inside Abseil in order to avoid ODR violations
-   and macro clashing with Chromium
-   (see: https://github.com/abseil/abseil-cpp/issues/122).
+3. From your source root run third_party/abseil-cpp/generate_def_files.py to
+   regenerate Windows symbol definition files.
 
 Local Modifications:
 
 * absl/copts.bzl has been translated to //third_party/absl-cpp/BUILD.gn. Both
   files contain lists of compiler flags in order to reduce duplication.
 
-* All the BUILD.bazel files has been translated to BUILD.gn files.
-
-* Functions and macros in absl/base/dynamic_annotations.{h,cc} and
-  absl/base/thread_annotations.h have been renamed to avoid ODR
-  violations and macro clashes with Chromium (see step 3).
+* All the BUILD.bazel files have been translated to BUILD.gn files.
 
 * Patches from //third_party/abseil-cpp/patches have been applied.
diff --git a/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/third_party/abseil-cpp/absl/base/internal/raw_logging.h
index 51551ba..4d93a22 100644
--- a/third_party/abseil-cpp/absl/base/internal/raw_logging.h
+++ b/third_party/abseil-cpp/absl/base/internal/raw_logging.h
@@ -72,10 +72,11 @@
 //
 // The API is a subset of the above: each macro only takes two arguments.  Use
 // StrCat if you need to build a richer message.
-#define ABSL_INTERNAL_LOG(severity, message)                                \
-  do {                                                                      \
-    ::absl::raw_logging_internal::internal_log_function(                    \
-        ABSL_RAW_LOGGING_INTERNAL_##severity, __FILE__, __LINE__, message); \
+#define ABSL_INTERNAL_LOG(severity, message)                    \
+  do {                                                          \
+    ::absl::raw_logging_internal::internal_log_function(        \
+        ABSL_RAW_LOGGING_INTERNAL_##severity,                   \
+        static_cast<const char*>(__FILE__), __LINE__, message); \
   } while (0)
 
 #define ABSL_INTERNAL_CHECK(condition, message)                    \
diff --git a/third_party/abseil-cpp/generate_def_file.py b/third_party/abseil-cpp/generate_def_files.py
old mode 100644
new mode 100755
similarity index 90%
rename from third_party/abseil-cpp/generate_def_file.py
rename to third_party/abseil-cpp/generate_def_files.py
index 996baf09..1961ac42
--- a/third_party/abseil-cpp/generate_def_file.py
+++ b/third_party/abseil-cpp/generate_def_files.py
@@ -1,6 +1,10 @@
-"""Script to generate Chromium's Abseil .def file at roll time.
+#!/usr/bin/env python
 
-This script generates //third_party/abseil-app/absl/symbols_x64.def at Abseil
+# NOTE: This script requires python 3.
+
+"""Script to generate Chromium's Abseil .def files at roll time.
+
+This script generates //third_party/abseil-app/absl/symbols_*.def at Abseil
 roll time.
 
 Since Abseil doesn't export symbols, Chromium is forced to consider all
@@ -11,6 +15,9 @@
 Unless you are on a Windows machine, you need to set up your Chromium
 checkout for cross-compilation by following the instructions at
 https://chromium.googlesource.com/chromium/src.git/+/master/docs/win_cross.md.
+If you are on Windows, you may need to tweak this script to run, e.g. by
+changing "gn" to "gn.bat", changing "llvm-nm-9" to the name of your copy of
+llvm-nm, etc.
 """
 
 import fnmatch
diff --git a/third_party/abseil-cpp/patches/0002-deterministic-logging-invocation.patch b/third_party/abseil-cpp/patches/0002-deterministic-logging-invocation.patch
new file mode 100644
index 0000000..798d55d2
--- /dev/null
+++ b/third_party/abseil-cpp/patches/0002-deterministic-logging-invocation.patch
@@ -0,0 +1,20 @@
+diff --git a/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/third_party/abseil-cpp/absl/base/internal/raw_logging.h
+index 51551bafff48..4d93a22fe628 100644
+--- a/third_party/abseil-cpp/absl/base/internal/raw_logging.h
++++ b/third_party/abseil-cpp/absl/base/internal/raw_logging.h
+@@ -72,10 +72,11 @@
+ //
+ // The API is a subset of the above: each macro only takes two arguments.  Use
+ // StrCat if you need to build a richer message.
+-#define ABSL_INTERNAL_LOG(severity, message)                                \
+-  do {                                                                      \
+-    ::absl::raw_logging_internal::internal_log_function(                    \
+-        ABSL_RAW_LOGGING_INTERNAL_##severity, __FILE__, __LINE__, message); \
++#define ABSL_INTERNAL_LOG(severity, message)                    \
++  do {                                                          \
++    ::absl::raw_logging_internal::internal_log_function(        \
++        ABSL_RAW_LOGGING_INTERNAL_##severity,                   \
++        static_cast<const char*>(__FILE__), __LINE__, message); \
+   } while (0)
+ 
+ #define ABSL_INTERNAL_CHECK(condition, message)                    \
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index a67b0552..fb78f79 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -191,6 +191,7 @@
     ??$?RAEAY0O@$$CBDPEAVCondVar@absl@@@?$AtomicHook@P6AXPEBDPEBX@Z@base_internal@absl@@QEBAXAEAY0O@$$CBD$$QEAPEAVCondVar@2@@Z
     ??$?RAEA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QEBAXAEA_J@Z
     ??$?RPEAVSpinLock@base_internal@absl@@AEB_K@?$AtomicHook@P6AXPEBX_J@Z@base_internal@absl@@QEBAX$$QEAPEAVSpinLock@12@AEB_K@Z
+    ??$?RW4LogSeverity@absl@@PEBDHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@$$QEAPEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?XH@Duration@absl@@QEAAAEAV01@H@Z
     ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z
@@ -1669,6 +1670,7 @@
     ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@USubRange@absl@@@__1@std@@XZ
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 98a8803..1ce997c 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -368,6 +368,7 @@
     ?FromUniversal@absl@@YA?AVTime@1@_J@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCurrentTimeNanos@absl@@YA_JXZ
     ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z
     ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index 4ddceb67..b767bda 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -191,6 +191,7 @@
     ??$?RAEAY0O@$$CBDPEAVCondVar@absl@@@?$AtomicHook@P6AXPEBDPEBX@Z@base_internal@absl@@QEBAXAEAY0O@$$CBD$$QEAPEAVCondVar@2@@Z
     ??$?RAEA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QEBAXAEA_J@Z
     ??$?RPEAVSpinLock@base_internal@absl@@AEB_K@?$AtomicHook@P6AXPEBX_J@Z@base_internal@absl@@QEBAX$$QEAPEAVSpinLock@12@AEB_K@Z
+    ??$?RW4LogSeverity@absl@@PEBDHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@$$QEAPEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?XH@Duration@absl@@QEAAAEAV01@H@Z
     ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z
@@ -1671,6 +1672,7 @@
     ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEAV?$allocator@USubRange@absl@@@__1@std@@XZ
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QEAAAEA_KXZ
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def
index 1e301a4..1c620a5 100644
--- a/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -368,6 +368,7 @@
     ?FromUniversal@absl@@YA?AVTime@1@_J@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCurrentTimeNanos@absl@@YA_JXZ
     ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z
     ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def
index 90417beb..ff4257a 100644
--- a/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -377,6 +377,7 @@
     ?FromUniversal@absl@@YA?AVTime@1@_J@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QEAAXPEAPEADPEA_K_K@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCurrentTimeNanos@absl@@YA_JXZ
     ?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAVstring_view@2@@Z
     ?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index 8d50a8e4..a9c8727 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -191,6 +191,7 @@
     ??$?RAAY0O@$$CBDPAVCondVar@absl@@@?$AtomicHook@P6AXPBDPBX@Z@base_internal@absl@@QBEXAAY0O@$$CBD$$QAPAVCondVar@2@@Z
     ??$?RAA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QBEXAA_J@Z
     ??$?RPAVSpinLock@base_internal@absl@@AB_K@?$AtomicHook@P6AXPBX_J@Z@base_internal@absl@@QBEX$$QAPAVSpinLock@12@AB_K@Z
+    ??$?RW4LogSeverity@absl@@PBDHAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@$$QAPBD$$QAHAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?XH@Duration@absl@@QAEAAV01@H@Z
     ??$Append@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$AppendImpl@ABVCord@absl@@@Cord@absl@@AAEXABV01@@Z
@@ -1668,6 +1669,7 @@
     ?GetAllocator@?$AllocationTransaction@V?$allocator@USubRange@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAV?$allocator@USubRange@absl@@@__1@std@@XZ
     ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAI@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAII@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@H@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ
     ?GetCapacity@?$AllocationTransaction@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@inlined_vector_internal@absl@@QAEAAIXZ
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 861f1ac..ad76f93a 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -368,6 +368,7 @@
     ?FromUniversal@absl@@YA?AVTime@1@_J@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAI@Z
     ?GetAppendRegion@InlineRep@Cord@absl@@QAEXPAPADPAII@Z
+    ?GetCachedTID@base_internal@absl@@YAIXZ
     ?GetCurrentTimeNanos@absl@@YA_JXZ
     ?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAVstring_view@2@@Z
     ?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn
index ddf1736..9431d17 100644
--- a/third_party/android_deps/BUILD.gn
+++ b/third_party/android_deps/BUILD.gn
@@ -787,6 +787,17 @@
 }
 
 # This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
+android_aar_prebuilt("androidx_webkit_webkit_java") {
+  aar_path = "libs/androidx_webkit_webkit/webkit-1.3.0-rc01.aar"
+  info_path = "libs/androidx_webkit_webkit/androidx_webkit_webkit.info"
+  deps = [
+    ":androidx_annotation_annotation_java",
+    ":androidx_core_core_java",
+  ]
+  visibility = [ "//android_webview/tools/system_webview_shell:*" ]
+}
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
 android_aar_prebuilt("com_android_support_appcompat_v7_java") {
   aar_path = "libs/com_android_support_appcompat_v7/appcompat-v7-28.0.0.aar"
   info_path = "libs/com_android_support_appcompat_v7/com_android_support_appcompat_v7.info"
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json
index 7e715d0b0..d3d975a 100644
--- a/third_party/android_deps/additional_readme_paths.json
+++ b/third_party/android_deps/additional_readme_paths.json
@@ -74,6 +74,7 @@
     "libs/androidx_versionedparcelable_versionedparcelable",
     "libs/androidx_viewpager2_viewpager2",
     "libs/androidx_viewpager_viewpager",
+    "libs/androidx_webkit_webkit",
     "libs/backport_util_concurrent_backport_util_concurrent",
     "libs/classworlds_classworlds",
     "libs/com_android_support_animated_vector_drawable",
diff --git a/third_party/android_deps/build.gradle b/third_party/android_deps/build.gradle
index f44dc81..d2c810a 100644
--- a/third_party/android_deps/build.gradle
+++ b/third_party/android_deps/build.gradle
@@ -84,6 +84,7 @@
     compile "androidx.viewpager2:viewpager2:${androidXSupportLibVersion}"
 
     compile "androidx.multidex:multidex:2.0.0"
+    compile "androidx.webkit:webkit:1.3.0-rc01"
 
     // Replacement for com.android.support:design
     compile "com.google.android.material:material:1.2.0-alpha06"
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index 25068097..93221a9 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -463,6 +463,9 @@
                 sb.append('    "com/google/protobuf/Wrappers*",\n')
                 sb.append('  ]')
                 break
+	    case 'androidx_webkit_webkit':
+	        sb.append('  visibility = ["//android_webview/tools/system_webview_shell:*"]\n')
+		break
         }
     }
 
diff --git a/third_party/android_deps/libs/androidx_webkit_webkit/LICENSE b/third_party/android_deps/libs/androidx_webkit_webkit/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_webkit_webkit/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_webkit_webkit/OWNERS b/third_party/android_deps/libs/androidx_webkit_webkit/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_webkit_webkit/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_webkit_webkit/README.chromium b/third_party/android_deps/libs/androidx_webkit_webkit/README.chromium
new file mode 100644
index 0000000..5949d57
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_webkit_webkit/README.chromium
@@ -0,0 +1,13 @@
+Name: WebView Support Library
+Short Name: webkit
+URL: https://developer.android.com/jetpack/androidx
+Version: 1.3.0-rc01
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The WebView Support Library is a static library you can add to your Android application in order to use android.webkit APIs that are not available for older platform versions.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/androidx_webkit_webkit/androidx_webkit_webkit.info b/third_party/android_deps/libs/androidx_webkit_webkit/androidx_webkit_webkit.info
new file mode 100644
index 0000000..8e7b59d
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_webkit_webkit/androidx_webkit_webkit.info
@@ -0,0 +1,13 @@
+# Generated by //build/android/gyp/aar.py
+# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
+
+aidl = []
+assets = []
+has_classes_jar = true
+has_native_libraries = false
+has_proguard_flags = true
+has_r_text_file = true
+is_manifest_empty = true
+resources = []
+subjar_tuples = []
+subjars = []
diff --git a/third_party/android_deps/libs/androidx_webkit_webkit/cipd.yaml b/third_party/android_deps/libs/androidx_webkit_webkit/cipd.yaml
new file mode 100644
index 0000000..5d02223
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_webkit_webkit/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.3.0-rc01-cr0
+package: chromium/third_party/android_deps/libs/androidx_webkit_webkit
+description: "WebView Support Library"
+data:
+- file: webkit-1.3.0-rc01.aar
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index fd09857..ab4c854c 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -104,7 +104,6 @@
     "input/web_mouse_wheel_event.cc",
     "input/web_pointer_event.cc",
     "input/web_touch_event.cc",
-    "loader/feature_utils.cc",
     "loader/mime_sniffing_throttle.cc",
     "loader/mime_sniffing_url_loader.cc",
     "loader/network_utils.cc",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 19b991a..706e6b8e 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -112,13 +112,6 @@
 const base::Feature kPlzDedicatedWorker{"PlzDedicatedWorker",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enable to load top-level script pre-requested by the browser process for
-// dedicated worker (PlzDedicatedWorker) and shared worker using
-// WorkerMainScriptLoadParameters.
-const base::Feature kLoadMainScriptForPlzDedicatedWorkerByParams{
-    "LoadMainScriptForPlzDedicatedWorkerByParams",
-    base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enable Portals. https://crbug.com/865123.
 // For the current origin trial (https://crbug.com/1040212), this is enabled on
 // Android only.
diff --git a/third_party/blink/common/loader/feature_utils.cc b/third_party/blink/common/loader/feature_utils.cc
deleted file mode 100644
index 23f31df1..0000000
--- a/third_party/blink/common/loader/feature_utils.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/public/common/loader/feature_utils.h"
-
-#include "third_party/blink/public/common/features.h"
-
-namespace blink {
-
-bool IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled() {
-  return base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker) &&
-         base::FeatureList::IsEnabled(
-             blink::features::kLoadMainScriptForPlzDedicatedWorkerByParams);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index 9401ecb..e528eaa 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -109,7 +109,6 @@
     "input/web_pointer_properties.h",
     "input/web_touch_event.h",
     "input/web_touch_point.h",
-    "loader/feature_utils.h",
     "loader/loading_behavior_flag.h",
     "loader/mime_sniffing_throttle.h",
     "loader/mime_sniffing_url_loader.h",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 5eaa322..d23c4da 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -41,8 +41,6 @@
 BLINK_COMMON_EXPORT extern const base::Feature kNavigationPredictor;
 BLINK_COMMON_EXPORT extern const base::Feature kParentNodeReplaceChildren;
 BLINK_COMMON_EXPORT extern const base::Feature kPlzDedicatedWorker;
-BLINK_COMMON_EXPORT extern const base::Feature
-    kLoadMainScriptForPlzDedicatedWorkerByParams;
 BLINK_COMMON_EXPORT extern const base::Feature kPortals;
 BLINK_COMMON_EXPORT extern const base::Feature kPortalsCrossOrigin;
 BLINK_COMMON_EXPORT extern const base::Feature
diff --git a/third_party/blink/public/common/loader/feature_utils.h b/third_party/blink/public/common/loader/feature_utils.h
deleted file mode 100644
index 7a016a1..0000000
--- a/third_party/blink/public/common/loader/feature_utils.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_FEATURE_UTILS_H_
-#define THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_FEATURE_UTILS_H_
-
-#include "third_party/blink/public/common/common_export.h"
-
-namespace blink {
-
-BLINK_COMMON_EXPORT bool IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled();
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_FEATURE_UTILS_H_
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 32e1d85..544a487 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -1430,6 +1430,22 @@
       # The stylesheet text.
       string text
 
+  # Starts tracking the given computed styles for updates. The specified array of properties
+  # replaces the one previously specified. Pass empty array to disable tracking.
+  # Use takeComputedStyleUpdates to retrieve the list of nodes that had properties modified.
+  # The changes to computed style properties are only tracked for nodes pushed to the front-end
+  # by the DOM agent. If no changes to the tracked properties occur after the node has been pushed
+  # to the front-end, no updates will be issued for the node.
+  experimental command trackComputedStyleUpdates
+    parameters
+      array of CSSComputedStyleProperty propertiesToTrack
+
+  # Polls the next batch of computed style updates.
+  experimental command takeComputedStyleUpdates
+    returns
+      # The list of node Ids that have their tracked computed styles updated
+      array of DOM.NodeId nodeIds
+
   # Find a rule with the given active property for the given node and set the new value for this
   # property
   command setEffectivePropertyValueForNode
@@ -5324,12 +5340,20 @@
       optional boolean showTrackSizes
       # The grid container border highlight color (default: transparent).
       optional DOM.RGBA gridBorderColor
-      # The cell border color (default: transparent).
-      optional DOM.RGBA cellBorderColor
+      # The cell border color (default: transparent). Deprecated, please use rowLineColor and columnLineColor instead.
+      deprecated optional DOM.RGBA cellBorderColor
+      # The row line color (default: transparent).
+      optional DOM.RGBA rowLineColor
+      # The column line color (default: transparent).
+      optional DOM.RGBA columnLineColor
       # Whether the grid border is dashed (default: false).
       optional boolean gridBorderDash
-      # Whether the cell border is dashed (default: false).
-      optional boolean cellBorderDash
+      # Whether the cell border is dashed (default: false). Deprecated, please us rowLineDash and columnLineDash instead.
+      deprecated optional boolean cellBorderDash
+      # Whether row lines are dashed (default: false).
+      optional boolean rowLineDash
+      # Whether column lines are dashed (default: false).
+      optional boolean columnLineDash
       # The row gap highlight fill color (default: transparent).
       optional DOM.RGBA rowGapColor
       # The row gap hatching fill color (default: transparent).
@@ -5646,6 +5670,11 @@
       string url
       # Frame document's URL fragment including the '#'.
       experimental optional string urlFragment
+      # Frame document's registered domain, taking the public suffixes list into account.
+      # Extracted from the Frame's url.
+      # Example URLs: http://www.google.com/file.html -> "google.com"
+      #               http://a.b.co.uk/file.html      -> "b.co.uk"
+      experimental string domainAndRegistry
       # Frame document's security origin.
       string securityOrigin
       # Frame document's mimeType as determined by the browser.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
index ad8cb22..8327721 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
@@ -666,12 +666,20 @@
 }
 
 ExecutionContext* ToExecutionContext(v8::Local<v8::Context> context) {
-  DCHECK(!context.IsEmpty());
+  // TODO(jgruber,crbug.com/v8/10460): Change this back to a DCHECK once the
+  // crash has been flushed out.
+  CHECK(!context.IsEmpty());
 
   RUNTIME_CALL_TIMER_SCOPE(context->GetIsolate(),
                            RuntimeCallStats::CounterId::kToExecutionContext);
 
   v8::Local<v8::Object> global_proxy = context->Global();
+
+  // TODO(jgruber,crbug.com/v8/10460): Change these back to a DCHECK once the
+  // crash has been flushed out.
+  CHECK(!global_proxy.IsEmpty());
+  CHECK(global_proxy->IsObject());
+
   // There are several contexts other than Window, WorkerGlobalScope or
   // WorkletGlobalScope but entering into ToExecutionContext, namely GC context,
   // DevTools' context (debug context), and maybe more.  They all don't have
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 09c4b0f..e3354b1 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1050,6 +1050,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_idle_state.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_verification_requirement.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_verification_requirement.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_acceleration_preference.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_acceleration_preference.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_power_preference.cc",
@@ -1939,8 +1941,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_acceleration_preference.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_acceleration_preference.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_playback_quality.cc",
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
index f89dd7f4..5c483ca 100644
--- a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
+++ b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
@@ -107,7 +107,6 @@
             "String",
             ref_fmt="{}&",
             const_ref_fmt="const {}&",
-            value_fmt="bindings::NativeValueTraitsStringAdapter",
             has_null_value=True)
 
     if real_type.is_array_buffer:
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 8e37a29..9a2f433 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1212,6 +1212,7 @@
     "layout/ng/inline/ng_bidi_paragraph_test.cc",
     "layout/ng/inline/ng_caret_position_test.cc",
     "layout/ng/inline/ng_fragment_item_test.cc",
+    "layout/ng/inline/ng_fragment_items_builder_test.cc",
     "layout/ng/inline/ng_inline_cursor_test.cc",
     "layout/ng/inline/ng_inline_fragment_traversal_test.cc",
     "layout/ng/inline/ng_inline_items_builder_test.cc",
diff --git a/third_party/blink/renderer/core/animation/compositor_animations.cc b/third_party/blink/renderer/core/animation/compositor_animations.cc
index 18ee7b8..a3a8be1 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -756,7 +756,7 @@
   if (!target)
     return false;
   DCHECK(target->GetDocument().Lifecycle().GetState() >=
-         DocumentLifecycle::kCompositingClean);
+         DocumentLifecycle::kCompositingAssignmentsClean);
   auto* layout_box_model_object = target->GetLayoutBoxModelObject();
   if (!layout_box_model_object)
     return false;
diff --git a/third_party/blink/renderer/core/dom/document_lifecycle.cc b/third_party/blink/renderer/core/dom/document_lifecycle.cc
index a4710c5..1e41e058 100644
--- a/third_party/blink/renderer/core/dom/document_lifecycle.cc
+++ b/third_party/blink/renderer/core/dom/document_lifecycle.cc
@@ -116,6 +116,9 @@
         return true;
       if (next_state == kInPerformLayout)
         return true;
+      if (next_state == kInCompositingInputsUpdate ||
+          next_state == kInCompositingAssignmentsUpdate)
+        return true;
       break;
     case kInStyleRecalc:
       return next_state == kStyleClean;
@@ -140,7 +143,7 @@
           next_state == kInCompositingInputsUpdate)
         return true;
       if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInPrePaint)
+          next_state == kCompositingInputsClean)
         return true;
       break;
     case kInLayoutSubtreeChange:
@@ -160,13 +163,10 @@
       if (next_state == kLayoutClean)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingInputsUpdate)
+          next_state == kCompositingInputsClean)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingUpdate)
-        return true;
-      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInPrePaint)
+          next_state == kInCompositingAssignmentsUpdate)
         return true;
       break;
     case kInPreLayout:
@@ -209,10 +209,12 @@
           next_state == kInCompositingInputsUpdate)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingUpdate)
+          next_state == kInCompositingAssignmentsUpdate)
         return true;
       if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInPrePaint)
+          next_state == kCompositingInputsClean)
+        return true;
+      if (next_state == kInPrePaint)
         return true;
       break;
     case kInAccessibility:
@@ -224,7 +226,10 @@
           next_state == kInCompositingInputsUpdate)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingUpdate)
+          next_state == kInCompositingAssignmentsUpdate)
+        return true;
+      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+          next_state == kCompositingInputsClean)
         return true;
       if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
           next_state == kInPrePaint)
@@ -233,13 +238,12 @@
     case kInCompositingInputsUpdate:
       DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
       return next_state == kCompositingInputsClean;
-    case kInCompositingUpdate:
+    case kInCompositingAssignmentsUpdate:
       DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
       // Once we are in the compositing update, we can either just clean the
       // inputs or do the whole of compositing.
-      return next_state == kCompositingClean;
+      return next_state == kCompositingAssignmentsClean;
     case kCompositingInputsClean:
-      DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
       // We can return to style re-calc, layout, or the start of compositing.
       if (next_state == kInStyleRecalc)
         return true;
@@ -247,27 +251,36 @@
         return true;
       if (next_state == kInCompositingInputsUpdate)
         return true;
-      if (next_state == kInCompositingUpdate)
+      if (next_state == kInCompositingAssignmentsUpdate)
+        return true;
+      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+          next_state == kCompositingAssignmentsClean)
+        return true;
+      if (next_state == kInPrePaint)
         return true;
       if (next_state == kInAccessibility)
         return true;
       // Otherwise, we can continue onwards.
-      if (next_state == kCompositingClean)
+      if (next_state == kCompositingAssignmentsClean)
         return true;
       break;
-    case kCompositingClean:
-      DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+    case kCompositingAssignmentsClean:
       if (next_state == kInStyleRecalc)
         return true;
       if (next_state == kInPreLayout)
         return true;
       if (next_state == kInCompositingInputsUpdate)
         return true;
-      if (next_state == kInCompositingUpdate)
+      if (next_state == kInCompositingAssignmentsUpdate)
+        return true;
+      if (next_state == kInAccessibility)
         return true;
       if (next_state == kInPrePaint)
         return true;
-      if (next_state == kInAccessibility)
+      if (next_state == kInPaint)
+        return true;
+      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+          next_state == kCompositingInputsClean)
         return true;
       break;
     case kInPrePaint:
@@ -285,7 +298,10 @@
           next_state == kInCompositingInputsUpdate)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingUpdate)
+          next_state == kInCompositingAssignmentsUpdate)
+        return true;
+      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+          next_state == kCompositingAssignmentsClean)
         return true;
       if (next_state == kInPrePaint)
         return true;
@@ -305,7 +321,10 @@
           next_state == kInCompositingInputsUpdate)
         return true;
       if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-          next_state == kInCompositingUpdate)
+          next_state == kInCompositingAssignmentsUpdate)
+        return true;
+      if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+          next_state == kCompositingInputsClean)
         return true;
       if (next_state == kInPrePaint)
         return true;
@@ -334,7 +353,7 @@
   return state_ == kStyleClean || state_ == kLayoutSubtreeChangeClean ||
          state_ == kAfterPerformLayout || state_ == kLayoutClean ||
          state_ == kAccessibilityClean || state_ == kCompositingInputsClean ||
-         state_ == kCompositingClean || state_ == kPrePaintClean ||
+         state_ == kCompositingAssignmentsClean || state_ == kPrePaintClean ||
          state_ == kPaintClean;
 }
 
@@ -359,9 +378,9 @@
     DEBUG_STRING_CASE(kInAccessibility);
     DEBUG_STRING_CASE(kAccessibilityClean);
     DEBUG_STRING_CASE(kInCompositingInputsUpdate);
-    DEBUG_STRING_CASE(kInCompositingUpdate);
+    DEBUG_STRING_CASE(kInCompositingAssignmentsUpdate);
     DEBUG_STRING_CASE(kCompositingInputsClean);
-    DEBUG_STRING_CASE(kCompositingClean);
+    DEBUG_STRING_CASE(kCompositingAssignmentsClean);
     DEBUG_STRING_CASE(kInPrePaint);
     DEBUG_STRING_CASE(kPrePaintClean);
     DEBUG_STRING_CASE(kInPaint);
diff --git a/third_party/blink/renderer/core/dom/document_lifecycle.h b/third_party/blink/renderer/core/dom/document_lifecycle.h
index e665c7f..d878d9eb 100644
--- a/third_party/blink/renderer/core/dom/document_lifecycle.h
+++ b/third_party/blink/renderer/core/dom/document_lifecycle.h
@@ -73,14 +73,15 @@
 
     kInCompositingInputsUpdate,
     kCompositingInputsClean,
-    kInCompositingUpdate,
-    kCompositingClean,
 
     // In InPrePaint step, any data needed by painting are prepared.
     // Paint property trees are built and paint invalidations are issued.
     kInPrePaint,
     kPrePaintClean,
 
+    kInCompositingAssignmentsUpdate,
+    kCompositingAssignmentsClean,
+
     // In InPaint step, paint artifacts are generated and raster invalidations
     // are issued.
     // In CAP, composited layers are generated/updated.
@@ -271,7 +272,7 @@
   // FIXME: We should not allow mutations in InPreLayout or AfterPerformLayout
   // either, but we need to fix MediaList listeners and plugins first.
   return state_ != kInStyleRecalc && state_ != kInPerformLayout &&
-         state_ != kInCompositingUpdate &&
+         state_ != kInCompositingAssignmentsUpdate &&
          state_ != kInCompositingInputsUpdate && state_ != kInPrePaint &&
          state_ != kInPaint;
 }
@@ -289,9 +290,9 @@
   return state_ == kVisualUpdatePending || state_ == kInStyleRecalc ||
          state_ == kStyleClean || state_ == kLayoutSubtreeChangeClean ||
          state_ == kInPreLayout || state_ == kLayoutClean ||
-         state_ == kCompositingInputsClean || state_ == kCompositingClean ||
-         state_ == kPrePaintClean || state_ == kPaintClean ||
-         state_ == kStopping || state_ == kInactive;
+         state_ == kCompositingInputsClean ||
+         state_ == kCompositingAssignmentsClean || state_ == kPrePaintClean ||
+         state_ == kPaintClean || state_ == kStopping || state_ == kInactive;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index ec5a009..d6afcd4 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3042,6 +3042,7 @@
   } else {
     INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
                                   styles_changed, 1);
+    probe::DidUpdateComputedStyle(this, old_style.get(), new_style.get());
     if (this == GetDocument().documentElement()) {
       if (GetDocument().GetStyleEngine().UpdateRemUnits(old_style.get(),
                                                         new_style.get())) {
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index c0323583..9ae726b 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -296,7 +296,7 @@
     // until the JS is complete, and then the Close request can be sent.
     if (auto* main_thread_scheduler =
             scheduler::WebThreadScheduler::MainThreadScheduler()) {
-      main_thread_scheduler->CleanupTaskRunner()->PostTask(
+      main_thread_scheduler->DeprecatedDefaultTaskRunner()->PostTask(
           FROM_HERE, WTF::Bind(&WebViewImpl::DoDeferredCloseWindowSoon,
                                weak_ptr_factory_.GetWeakPtr()));
     }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index adcc5e5..e99d90c 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2165,7 +2165,7 @@
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
     return UpdateAllLifecyclePhasesExceptPaint(reason);
   return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
-      DocumentLifecycle::kCompositingClean, reason);
+      DocumentLifecycle::kCompositingAssignmentsClean, reason);
 }
 
 // TODO(schenney): Pass a LifecycleUpdateReason in here
@@ -2181,13 +2181,15 @@
 bool LocalFrameView::UpdateAllLifecyclePhasesExceptPaint(
     DocumentUpdateReason reason) {
   return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
-      DocumentLifecycle::kPrePaintClean, reason);
+      DocumentLifecycle::kCompositingAssignmentsClean, reason);
 }
 
 void LocalFrameView::UpdateLifecyclePhasesForPrinting() {
   auto* local_frame_view_root = GetFrame().LocalFrameRoot().View();
+  // TODO(chrishr): this can be changed to kPrePaintClean
   local_frame_view_root->UpdateLifecyclePhases(
-      DocumentLifecycle::kPrePaintClean, DocumentUpdateReason::kPrinting);
+      DocumentLifecycle::kCompositingAssignmentsClean,
+      DocumentUpdateReason::kPrinting);
 
   auto* detached_frame_view = this;
   while (detached_frame_view->IsAttached() &&
@@ -2204,8 +2206,9 @@
   // was not reached in some phases during during |local_frame_view_root->
   // UpdateLifecyclePhasesnormal()|. We need the subtree to be ready for
   // painting.
-  detached_frame_view->UpdateLifecyclePhases(DocumentLifecycle::kPrePaintClean,
-                                             DocumentUpdateReason::kPrinting);
+  detached_frame_view->UpdateLifecyclePhases(
+      DocumentLifecycle::kCompositingAssignmentsClean,
+      DocumentUpdateReason::kPrinting);
 }
 
 // TODO(schenney): Pass a LifecycleUpdateReason in here
@@ -2286,8 +2289,7 @@
 
   // Prevent reentrance.
   // TODO(vmpstr): Should we just have a DCHECK instead here?
-  if (UNLIKELY(current_update_lifecycle_phases_target_state_ !=
-               DocumentLifecycle::kUninitialized)) {
+  if (UNLIKELY(IsUpdatingLifecycle())) {
     NOTREACHED()
         << "LocalFrameView::updateLifecyclePhasesInternal() reentrance";
     return false;
@@ -2302,7 +2304,7 @@
   DCHECK(target_state == DocumentLifecycle::kLayoutClean ||
          target_state == DocumentLifecycle::kAccessibilityClean ||
          target_state == DocumentLifecycle::kCompositingInputsClean ||
-         target_state == DocumentLifecycle::kCompositingClean ||
+         target_state == DocumentLifecycle::kCompositingAssignmentsClean ||
          target_state == DocumentLifecycle::kPrePaintClean ||
          target_state == DocumentLifecycle::kPaintClean);
   lifecycle_update_count_for_testing_++;
@@ -2345,6 +2347,8 @@
     TRACE_EVENT0("blink", "LocalFrameView::WillStartLifecycleUpdate");
 
     ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+      frame_view.Lifecycle().EnsureStateAtMost(
+          DocumentLifecycle::kVisualUpdatePending);
       auto lifecycle_observers = frame_view.lifecycle_observers_;
       for (auto& observer : lifecycle_observers)
         observer->WillStartLifecycleUpdate(frame_view);
@@ -2426,7 +2430,8 @@
       TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
                    inspector_update_layer_tree_event::Data(frame_.Get()));
 
-      run_more_lifecycle_phases = RunCompositingLifecyclePhase(target_state);
+      run_more_lifecycle_phases =
+          RunCompositingInputsLifecyclePhase(target_state);
       if (!run_more_lifecycle_phases)
         return;
 
@@ -2437,6 +2442,12 @@
              Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
       if (!run_more_lifecycle_phases)
         return;
+
+      run_more_lifecycle_phases =
+          RunCompositingAssignmentsLifecyclePhase(target_state);
+      if (!run_more_lifecycle_phases) {
+        return;
+      }
     }
 
     run_more_lifecycle_phases = RunResizeObserverSteps(target_state);
@@ -2544,32 +2555,55 @@
   return Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean;
 }
 
-bool LocalFrameView::RunCompositingLifecyclePhase(
+bool LocalFrameView::RunCompositingInputsLifecyclePhase(
     DocumentLifecycle::LifecycleState target_state) {
   TRACE_EVENT0("blink,benchmark",
-               "LocalFrameView::RunCompositingLifecyclePhase");
+               "LocalFrameView::RunCompositingInputsLifecyclePhase");
   auto* layout_view = GetLayoutView();
   DCHECK(layout_view);
 
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
     SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
-                             LocalFrameUkmAggregator::kCompositing);
-    DCHECK_GE(target_state, DocumentLifecycle::kCompositingInputsClean);
-    {
-      SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
-                               LocalFrameUkmAggregator::kCompositingInputs);
-      layout_view->Compositor()->UpdateInputsIfNeededRecursive(target_state);
-    }
-    {
-      SCOPED_UMA_AND_UKM_TIMER(
-          EnsureUkmAggregator(),
-          LocalFrameUkmAggregator::kCompositingAssignments);
-      layout_view->Compositor()->UpdateAssignmentsIfNeededRecursive(
-          target_state);
-    }
+                             LocalFrameUkmAggregator::kCompositingInputs);
+    layout_view->Compositor()->UpdateInputsIfNeededRecursive(target_state);
+  } else {
+    ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+      frame_view.Lifecycle().AdvanceTo(
+          DocumentLifecycle::kCompositingInputsClean);
+    });
   }
 
-  return target_state > DocumentLifecycle::kCompositingClean;
+  return target_state > DocumentLifecycle::kCompositingInputsClean;
+}
+
+bool LocalFrameView::RunCompositingAssignmentsLifecyclePhase(
+    DocumentLifecycle::LifecycleState target_state) {
+  TRACE_EVENT0("blink,benchmark",
+               "LocalFrameView::RunCompositingAssignmentsLifecyclePhase");
+  auto* layout_view = GetLayoutView();
+  DCHECK(layout_view);
+
+  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+    SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
+                             LocalFrameUkmAggregator::kCompositingAssignments);
+    layout_view->Compositor()->UpdateAssignmentsIfNeededRecursive(target_state);
+  } else {
+    ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+      frame_view.Lifecycle().AdvanceTo(
+          DocumentLifecycle::kCompositingAssignmentsClean);
+    });
+  }
+
+  UpdateCompositedSelectionIfNeeded();
+
+  frame_->GetPage()->GetValidationMessageClient().UpdatePrePaint();
+  ForAllNonThrottledLocalFrameViews([](LocalFrameView& view) {
+    view.frame_->UpdateFrameColorOverlayPrePaint();
+  });
+  if (auto* web_local_frame_impl = WebLocalFrameImpl::FromFrame(frame_))
+    web_local_frame_impl->UpdateDevToolsOverlaysPrePaint();
+
+  return target_state > DocumentLifecycle::kCompositingAssignmentsClean;
 }
 
 bool LocalFrameView::RunPrePaintLifecyclePhase(
@@ -2616,15 +2650,6 @@
     GetPage()->GetLinkHighlight().UpdateAfterPrePaint();
   }
 
-  UpdateCompositedSelectionIfNeeded();
-
-  frame_->GetPage()->GetValidationMessageClient().UpdatePrePaint();
-  ForAllNonThrottledLocalFrameViews([](LocalFrameView& view) {
-    view.frame_->UpdateFrameColorOverlayPrePaint();
-  });
-  if (auto* web_local_frame_impl = WebLocalFrameImpl::FromFrame(frame_))
-    web_local_frame_impl->UpdateDevToolsOverlaysPrePaint();
-
   ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
     frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPrePaintClean);
   });
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index f9d15dfa..f13c88d 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -326,6 +326,11 @@
   // LocalFrame.
   void WillBeRemovedFromFrame();
 
+  bool IsUpdatingLifecycle() {
+    return current_update_lifecycle_phases_target_state_ !=
+           DocumentLifecycle::kUninitialized;
+  }
+
   // Run all needed lifecycle stages. After calling this method, all frames will
   // be in the lifecycle state PaintClean.  If lifecycle throttling is allowed
   // (see DocumentLifecycle::AllowThrottlingScope), some frames may skip the
@@ -771,7 +776,9 @@
       DocumentLifecycle::LifecycleState target_state);
   bool RunAccessibilityLifecyclePhase(
       DocumentLifecycle::LifecycleState target_state);
-  bool RunCompositingLifecyclePhase(
+  bool RunCompositingInputsLifecyclePhase(
+      DocumentLifecycle::LifecycleState target_state);
+  bool RunCompositingAssignmentsLifecyclePhase(
       DocumentLifecycle::LifecycleState target_state);
   bool RunPrePaintLifecyclePhase(
       DocumentLifecycle::LifecycleState target_state);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
index b82551f8..1617572 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view_test.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -172,9 +172,9 @@
   ChildDocument().View()->UpdateLifecyclePhasesForPrinting();
 
   // The following checks that the detached frame has been walked for PrePaint.
-  EXPECT_EQ(DocumentLifecycle::kPrePaintClean,
+  EXPECT_EQ(DocumentLifecycle::kCompositingAssignmentsClean,
             GetDocument().Lifecycle().GetState());
-  EXPECT_EQ(DocumentLifecycle::kPrePaintClean,
+  EXPECT_EQ(DocumentLifecycle::kCompositingAssignmentsClean,
             ChildDocument().Lifecycle().GetState());
   auto* child_layout_view = ChildDocument().GetLayoutView();
   EXPECT_TRUE(child_layout_view->FirstFragment().PaintProperties());
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 f8175f5..a45fd65 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -51,7 +51,9 @@
 #include "third_party/blink/renderer/core/css/media_values.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
 #include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
@@ -336,6 +338,8 @@
 }  // namespace
 
 typedef blink::protocol::CSS::Backend::EnableCallback EnableCallback;
+typedef blink::protocol::CSS::Backend::TakeComputedStyleUpdatesCallback
+    TakeComputedStyleUpdatesCallback;
 
 enum ForcePseudoClassFlags {
   kPseudoNone = 0,
@@ -2226,6 +2230,7 @@
   int node_id = dom_agent_->BoundNodeId(node);
   DCHECK(node_id);
   node_id_to_forced_pseudo_state_.erase(node_id);
+  computed_style_updated_node_ids_.erase(node_id);
 
   NodeToInspectorStyleSheet::iterator it =
       node_to_inspector_style_sheet_.find(node);
@@ -2605,6 +2610,128 @@
   return Response::Success();
 }
 
+Response InspectorCSSAgent::trackComputedStyleUpdates(
+    std::unique_ptr<protocol::Array<protocol::CSS::CSSComputedStyleProperty>>
+        properties_to_track) {
+  tracked_computed_styles_.clear();
+  if (properties_to_track->size() == 0) {
+    if (computed_style_updated_callback_) {
+      computed_style_updated_callback_->sendSuccess(
+          BuildArrayForComputedStyleUpdatedNodes());
+    }
+    computed_style_updated_node_ids_.clear();
+    return Response::Success();
+  }
+
+  for (const auto& property : *properties_to_track) {
+    String property_name = property->getName();
+    HashMap<String, HashSet<String>>::iterator it =
+        tracked_computed_styles_.find(property_name);
+    if (it != tracked_computed_styles_.end()) {
+      it->value.insert(property->getValue());
+    } else {
+      HashSet<String> tracked_values;
+      tracked_values.insert(property->getValue());
+      tracked_computed_styles_.Set(property_name, tracked_values);
+    }
+  }
+
+  return Response::Success();
+}
+
+void InspectorCSSAgent::takeComputedStyleUpdates(
+    std::unique_ptr<TakeComputedStyleUpdatesCallback> callback) {
+  if (tracked_computed_styles_.IsEmpty()) {
+    callback->sendFailure(Response::ServerError(
+        "No computed styles are being tracked right now."));
+    return;
+  }
+
+  if (computed_style_updated_callback_) {
+    callback->sendFailure(
+        Response::ServerError("A previous request has not been resolved yet."));
+    return;
+  }
+
+  if (computed_style_updated_node_ids_.size()) {
+    callback->sendSuccess(BuildArrayForComputedStyleUpdatedNodes());
+    computed_style_updated_node_ids_.clear();
+    return;
+  }
+
+  computed_style_updated_callback_ = std::move(callback);
+}
+
+void InspectorCSSAgent::DidUpdateComputedStyle(Element* element,
+                                               const ComputedStyle* old_style,
+                                               const ComputedStyle* new_style) {
+  if (tracked_computed_styles_.IsEmpty())
+    return;
+
+  if (!old_style && !new_style)
+    return;
+
+  int id = dom_agent_->BoundNodeId(element);
+  // If node is not mapped yet -> ignore the event.
+  if (!id)
+    return;
+
+  if (computed_style_updated_node_ids_.Contains(id))
+    return;
+
+  // Compares with the currently tracked styles to see if this node should be
+  // included
+  for (const auto& tracked_computed_style : tracked_computed_styles_) {
+    const HashSet<String>& tracked_values = tracked_computed_style.value;
+    CSSPropertyRef ref(tracked_computed_style.key, element->GetDocument());
+    if (!ref.IsValid())
+      continue;
+    const CSSProperty& tracked_property = ref.GetProperty();
+    // TODO(crbug/1108356): consider using the Prepared Value once it's ready
+    const CSSValue* old_value = old_style
+                                    ? ComputedStyleUtils::ComputedPropertyValue(
+                                          tracked_property, *old_style)
+                                    : nullptr;
+    const CSSValue* new_value = new_style
+                                    ? ComputedStyleUtils::ComputedPropertyValue(
+                                          tracked_property, *new_style)
+                                    : nullptr;
+    if (old_value == new_value)
+      continue;
+    String old_value_text = old_value ? old_value->CssText() : "";
+    String new_value_text = new_value ? new_value->CssText() : "";
+    if (old_value_text == new_value_text)
+      continue;
+    if (tracked_values.Contains(old_value_text) ||
+        tracked_values.Contains(new_value_text)) {
+      computed_style_updated_node_ids_.insert(id);
+      return;
+    }
+  }
+}
+
+void InspectorCSSAgent::Will(const probe::RecalculateStyle&) {}
+
+void InspectorCSSAgent::Did(const probe::RecalculateStyle&) {
+  if (computed_style_updated_callback_ &&
+      computed_style_updated_node_ids_.size()) {
+    computed_style_updated_callback_->sendSuccess(
+        BuildArrayForComputedStyleUpdatedNodes());
+    computed_style_updated_node_ids_.clear();
+    computed_style_updated_callback_ = nullptr;
+  }
+}
+
+std::unique_ptr<protocol::Array<int>>
+InspectorCSSAgent::BuildArrayForComputedStyleUpdatedNodes() {
+  std::unique_ptr<protocol::Array<int>> nodes =
+      std::make_unique<protocol::Array<int>>();
+  for (int node_id : computed_style_updated_node_ids_) {
+    nodes->push_back(node_id);
+  }
+  return nodes;
+}
+
 void InspectorCSSAgent::Trace(Visitor* visitor) const {
   visitor->Trace(dom_agent_);
   visitor->Trace(inspected_frames_);
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.h b/third_party/blink/renderer/core/inspector/inspector_css_agent.h
index 0b32c6c..eaf2c0f 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.h
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h"
 #include "third_party/blink/renderer/core/inspector/inspector_style_sheet.h"
 #include "third_party/blink/renderer/core/inspector/protocol/CSS.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -45,6 +46,10 @@
 
 namespace blink {
 
+namespace probe {
+class RecalculateStyle;
+}  // namespace probe
+
 class CSSRule;
 class CSSStyleRule;
 class CSSStyleSheet;
@@ -207,6 +212,11 @@
   protocol::Response stopRuleUsageTracking(
       std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result)
       override;
+  protocol::Response trackComputedStyleUpdates(
+      std::unique_ptr<protocol::Array<protocol::CSS::CSSComputedStyleProperty>>
+          properties_to_track) override;
+  void takeComputedStyleUpdates(
+      std::unique_ptr<TakeComputedStyleUpdatesCallback>) override;
 
   protocol::Response setLocalFontsEnabled(bool enabled) override;
 
@@ -229,6 +239,13 @@
   HeapVector<Member<CSSStyleDeclaration>> MatchingStyles(Element*);
   String StyleSheetId(CSSStyleSheet*);
 
+  void DidUpdateComputedStyle(Element*,
+                              const ComputedStyle*,
+                              const ComputedStyle*);
+
+  void Will(const probe::RecalculateStyle&);
+  void Did(const probe::RecalculateStyle&);
+
  private:
   class StyleSheetAction;
   class SetStyleSheetTextAction;
@@ -296,6 +313,8 @@
   BuildArrayForMatchedRuleList(RuleIndexList*, PseudoId);
   std::unique_ptr<protocol::CSS::CSSStyle> BuildObjectForAttributesStyle(
       Element*);
+  std::unique_ptr<protocol::Array<int>>
+  BuildArrayForComputedStyleUpdatedNodes();
 
   // InspectorDOMAgent::DOMListener implementation
   void DidAddDocument(Document*) override;
@@ -342,6 +361,14 @@
   InspectorAgentState::Boolean coverage_enabled_;
   InspectorAgentState::Boolean local_fonts_enabled_;
 
+  // Maps style property names to the set of tracked values for that property.
+  // Notifications are sent when the property changes to or from one of the
+  // tracked values.
+  HashMap<String, HashSet<String>> tracked_computed_styles_;
+  std::unique_ptr<TakeComputedStyleUpdatesCallback>
+      computed_style_updated_callback_;
+  HashSet<int> computed_style_updated_node_ids_;
+
   friend class InspectorResourceContentLoaderCallback;
   friend class StyleSheetBinder;
   DISALLOW_COPY_AND_ASSIGN(InspectorCSSAgent);
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index 657543a..cfb6371 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -368,7 +368,8 @@
   std::unique_ptr<protocol::DictionaryValue> grid_config_info =
       protocol::DictionaryValue::create();
   grid_config_info->setBoolean("gridBorderDash", grid_config.grid_border_dash);
-  grid_config_info->setBoolean("cellBorderDash", grid_config.cell_border_dash);
+  grid_config_info->setBoolean("rowLineDash", grid_config.row_line_dash);
+  grid_config_info->setBoolean("columnLineDash", grid_config.column_line_dash);
   grid_config_info->setBoolean("showGridExtensionLines",
                                grid_config.show_grid_extension_lines);
   grid_config_info->setBoolean("showPositiveLineNumbers",
@@ -382,9 +383,13 @@
     grid_config_info->setString("gridBorderColor",
                                 grid_config.grid_color.Serialized());
   }
-  if (grid_config.cell_color != Color::kTransparent) {
-    grid_config_info->setString("cellBorderColor",
-                                grid_config.cell_color.Serialized());
+  if (grid_config.row_line_color != Color::kTransparent) {
+    grid_config_info->setString("rowLineColor",
+                                grid_config.row_line_color.Serialized());
+  }
+  if (grid_config.column_line_color != Color::kTransparent) {
+    grid_config_info->setString("columnLineColor",
+                                grid_config.column_line_color.Serialized());
   }
   if (grid_config.row_gap_color != Color::kTransparent) {
     grid_config_info->setString("rowGapColor",
@@ -971,8 +976,10 @@
   if (highlight_config.css_grid != Color::kTransparent) {
     std::unique_ptr<InspectorGridHighlightConfig> grid_config =
         std::make_unique<InspectorGridHighlightConfig>();
-    grid_config->cell_color = highlight_config.css_grid;
-    grid_config->cell_border_dash = true;
+    grid_config->row_line_color = highlight_config.css_grid;
+    grid_config->column_line_color = highlight_config.css_grid;
+    grid_config->row_line_dash = true;
+    grid_config->column_line_dash = true;
     return BuildGridInfo(node, *grid_config, scale, isPrimary);
   }
 
@@ -1061,7 +1068,8 @@
 InspectorGridHighlightConfig::InspectorGridHighlightConfig()
     : show_grid_extension_lines(false),
       grid_border_dash(false),
-      cell_border_dash(false),
+      row_line_dash(false),
+      column_line_dash(false),
       show_positive_line_numbers(false),
       show_negative_line_numbers(false),
       show_area_names(false),
@@ -1639,7 +1647,8 @@
 InspectorGridHighlightConfig InspectorHighlight::DefaultGridConfig() {
   InspectorGridHighlightConfig config;
   config.grid_color = Color(255, 0, 0, 0);
-  config.cell_color = Color(128, 0, 0, 0);
+  config.row_line_color = Color(128, 0, 0, 0);
+  config.column_line_color = Color(128, 0, 0, 0);
   config.row_gap_color = Color(0, 255, 0, 0);
   config.column_gap_color = Color(0, 0, 255, 0);
   config.row_hatch_color = Color(255, 255, 255, 0);
@@ -1651,7 +1660,8 @@
   config.show_area_names = true;
   config.show_line_names = true;
   config.grid_border_dash = false;
-  config.cell_border_dash = true;
+  config.row_line_dash = true;
+  config.column_line_dash = true;
   config.show_track_sizes = true;
   return config;
 }
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h
index 1df76a7..2ccab9b4 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.h
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -35,7 +35,8 @@
   InspectorGridHighlightConfig();
 
   Color grid_color;
-  Color cell_color;
+  Color row_line_color;
+  Color column_line_color;
   Color row_gap_color;
   Color column_gap_color;
   Color row_hatch_color;
@@ -44,7 +45,8 @@
 
   bool show_grid_extension_lines;
   bool grid_border_dash;
-  bool cell_border_dash;
+  bool row_line_dash;
+  bool column_line_dash;
   bool show_positive_line_numbers;
   bool show_negative_line_numbers;
   bool show_area_names;
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
index 38a9066..41b6996 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -1426,12 +1426,37 @@
   highlight_config->show_grid_extension_lines =
       config->getShowGridExtensionLines(false);
   highlight_config->grid_border_dash = config->getGridBorderDash(false);
-  highlight_config->cell_border_dash = config->getCellBorderDash(false);
+
+  // cellBorderDash is deprecated. We only use it if defined and none of the new
+  // properties are.
+  bool hasLegacyBorderDash = !config->hasRowLineDash() &&
+                             !config->hasColumnLineDash() &&
+                             config->hasCellBorderDash();
+  highlight_config->row_line_dash = hasLegacyBorderDash
+                                        ? config->getCellBorderDash(false)
+                                        : config->getRowLineDash(false);
+  highlight_config->column_line_dash = hasLegacyBorderDash
+                                           ? config->getCellBorderDash(false)
+                                           : config->getColumnLineDash(false);
+
   highlight_config->show_track_sizes = config->getShowTrackSizes(false);
   highlight_config->grid_color =
       InspectorDOMAgent::ParseColor(config->getGridBorderColor(nullptr));
-  highlight_config->cell_color =
-      InspectorDOMAgent::ParseColor(config->getCellBorderColor(nullptr));
+
+  // cellBorderColor is deprecated. We only use it if defined and none of the
+  // new properties are.
+  bool hasLegacyBorderColors = !config->hasRowLineColor() &&
+                               !config->hasColumnLineColor() &&
+                               config->hasCellBorderColor();
+  highlight_config->row_line_color =
+      hasLegacyBorderColors
+          ? InspectorDOMAgent::ParseColor(config->getCellBorderColor(nullptr))
+          : InspectorDOMAgent::ParseColor(config->getRowLineColor(nullptr));
+  highlight_config->column_line_color =
+      hasLegacyBorderColors
+          ? InspectorDOMAgent::ParseColor(config->getCellBorderColor(nullptr))
+          : InspectorDOMAgent::ParseColor(config->getColumnLineColor(nullptr));
+
   highlight_config->row_gap_color =
       InspectorDOMAgent::ParseColor(config->getRowGapColor(nullptr));
   highlight_config->column_gap_color =
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 42b8631..16d609e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -77,6 +77,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
+#include "third_party/blink/renderer/platform/network/network_utils.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/text/base64.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -1068,6 +1069,10 @@
           .setId(IdentifiersFactory::FrameId(frame))
           .setLoaderId(IdentifiersFactory::LoaderId(loader))
           .setUrl(UrlWithoutFragment(loader->Url()).GetString())
+          .setDomainAndRegistry(blink::network_utils::GetDomainAndRegistry(
+              loader->Url().Host(),
+              blink::network_utils::PrivateRegistryFilter::
+                  kIncludePrivateRegistries))
           .setMimeType(frame->Loader().GetDocumentLoader()->MimeType())
           .setSecurityOrigin(
               SecurityOrigin::Create(loader->Url())->ToRawString())
diff --git a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
index b6ba2f3..0bb788a 100644
--- a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
+++ b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -25,7 +25,7 @@
             },
             {
                 "domain": "CSS",
-                "async": ["enable"]
+                "async": ["enable", "takeComputedStyleUpdates"]
             },
             {
                 "domain": "Database",
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 927b77a..c1dfd182 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -182,13 +182,13 @@
   if (local_frame_view->ShouldThrottleRendering() ||
       !local_frame_view->GetFrame().GetDocument() ||
       local_frame_view->GetFrame().GetDocument()->Lifecycle().GetState() <
-          DocumentLifecycle::kCompositingClean) {
+          DocumentLifecycle::kCompositingAssignmentsClean) {
     return NodeAtPointOverEmbeddedContentView(result, hit_test_location,
                                               accumulated_offset, action);
   }
 
   DCHECK_GE(GetDocument().Lifecycle().GetState(),
-            DocumentLifecycle::kCompositingClean);
+            DocumentLifecycle::kCompositingAssignmentsClean);
 
   if (action == kHitTestForeground) {
     auto* child_layout_view = local_frame_view->GetLayoutView();
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 1d99fda..51a8884 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -4001,7 +4001,7 @@
     case DocumentLifecycle::kInPerformLayout:
     case DocumentLifecycle::kAfterPerformLayout:
       return PaintInvalidationReason::kGeometry;
-    case DocumentLifecycle::kInCompositingUpdate:
+    case DocumentLifecycle::kInCompositingAssignmentsUpdate:
       DCHECK(false);
       return PaintInvalidationReason::kFull;
     default:
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
index 5f414b9..78127ba 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
@@ -36,41 +36,94 @@
     items_.ReserveInitialCapacity(estimated_item_count);
 }
 
-void NGFragmentItemsBuilder::SetCurrentLine(
-    const NGPhysicalLineBoxFragment& line,
-    NGLogicalLineItems* current_line) {
-#if DCHECK_IS_ON()
-  current_line_fragment_ = &line;
-#endif
-  DCHECK(current_line);
-  DCHECK(!current_line_);  // Check |AddLine| runs after |SetCurrentLine|.
-  current_line_ = current_line;
+NGFragmentItemsBuilder::~NGFragmentItemsBuilder() {
+  ReleaseCurrentLogicalLineItems();
+
+  // Delete leftovers that were associated, but were not added.
+  for (const auto& i : line_items_map_) {
+    if (i.value != line_items_pool_)
+      delete i.value;
+  }
 }
 
-void NGFragmentItemsBuilder::ClearCurrentLineForTesting() {
-  current_line_ = nullptr;
+void NGFragmentItemsBuilder::AddLogicalLineItemsPool(
+    NGLogicalLineItems* line_items) {
+  DCHECK(line_items);
+  DCHECK(!line_items_pool_);
+  line_items_pool_ = line_items;
+  DCHECK(!is_line_items_pool_acquired_);
 }
 
-void NGFragmentItemsBuilder::AddLine(const NGPhysicalLineBoxFragment& line,
-                                     const LogicalOffset& offset) {
+void NGFragmentItemsBuilder::ReleaseCurrentLogicalLineItems() {
+  if (!current_line_items_)
+    return;
+  if (current_line_items_ == line_items_pool_) {
+    DCHECK(is_line_items_pool_acquired_);
+    is_line_items_pool_acquired_ = false;
+  } else {
+    delete current_line_items_;
+  }
+  current_line_items_ = nullptr;
+}
+
+void NGFragmentItemsBuilder::MoveCurrentLogicalLineItemsToMap() {
+  if (!current_line_items_) {
+    DCHECK(!current_line_fragment_);
+    return;
+  }
+  DCHECK(current_line_fragment_);
+  line_items_map_.insert(current_line_fragment_, current_line_items_);
+  current_line_fragment_ = nullptr;
+  current_line_items_ = nullptr;
+}
+
+NGLogicalLineItems* NGFragmentItemsBuilder::AcquireLogicalLineItems() {
+  if (line_items_pool_ && !is_line_items_pool_acquired_) {
+    is_line_items_pool_acquired_ = true;
+    return line_items_pool_;
+  }
+  MoveCurrentLogicalLineItemsToMap();
+  DCHECK(!current_line_items_);
+  current_line_items_ = new NGLogicalLineItems();
+  return current_line_items_;
+}
+
+void NGFragmentItemsBuilder::AssociateLogicalLineItems(
+    NGLogicalLineItems* line_items,
+    const NGPhysicalFragment& line_fragment) {
+  DCHECK(!current_line_items_ || current_line_items_ == line_items);
+  current_line_items_ = line_items;
+  DCHECK(!current_line_fragment_);
+  current_line_fragment_ = &line_fragment;
+}
+
+void NGFragmentItemsBuilder::AddLine(
+    const NGPhysicalLineBoxFragment& line_fragment,
+    const LogicalOffset& offset) {
   DCHECK(!is_converted_to_physical_);
-#if DCHECK_IS_ON()
-  DCHECK_EQ(current_line_fragment_, &line);
-#endif
-  DCHECK(current_line_);
+  if (&line_fragment == current_line_fragment_) {
+    DCHECK(current_line_items_);
+    current_line_fragment_ = nullptr;
+  } else {
+    MoveCurrentLogicalLineItemsToMap();
+    DCHECK(!current_line_items_);
+    current_line_items_ = line_items_map_.Take(&line_fragment);
+    DCHECK(current_line_items_);
+  }
+  NGLogicalLineItems* line_items = current_line_items_;
 
   // Reserve the capacity for (children + line box item).
   const wtf_size_t size_before = items_.size();
-  const wtf_size_t estimated_size = size_before + current_line_->size() + 1;
+  const wtf_size_t estimated_size = size_before + line_items->size() + 1;
   const wtf_size_t old_capacity = items_.capacity();
   if (estimated_size > old_capacity)
     items_.ReserveCapacity(std::max(estimated_size, old_capacity * 2));
 
   // Add an empty item so that the start of the line can be set later.
   const wtf_size_t line_start_index = items_.size();
-  items_.emplace_back(offset, line);
+  items_.emplace_back(offset, line_fragment);
 
-  AddItems(current_line_->begin(), current_line_->end());
+  AddItems(line_items->begin(), line_items->end());
 
   // All children are added. Create an item for the start of the line.
   NGFragmentItem& line_item = items_[line_start_index].item;
@@ -81,13 +134,7 @@
   // Keep children's offsets relative to |line|. They will be adjusted later in
   // |ConvertToPhysical()|.
 
-  // Clear the current line without releasing the buffer. It is likely to be
-  // reused again.
-  current_line_->Shrink(0);
-#if DCHECK_IS_ON()
-  current_line_ = nullptr;
-  current_line_fragment_ = nullptr;
-#endif
+  ReleaseCurrentLogicalLineItems();
 
   DCHECK_LE(items_.size(), estimated_size);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
index 081a028..f605fcb 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
@@ -26,6 +26,7 @@
   explicit NGFragmentItemsBuilder(WritingDirectionMode writing_direction);
   NGFragmentItemsBuilder(const NGInlineNode& node,
                          WritingDirectionMode writing_direction);
+  ~NGFragmentItemsBuilder();
 
   WritingDirectionMode GetWritingDirection() const {
     return writing_direction_;
@@ -49,20 +50,33 @@
                : text_content_;
   }
 
-  // The caller should create a |NGLogicalLineItems| for a complete line and add
-  // to this builder.
-  //
-  // Adding a line is a two-pass operation, because |NGInlineLayoutAlgorithm|
+  // Adding a line is a three-pass operation, because |NGInlineLayoutAlgorithm|
   // creates and positions children within a line box, but its parent algorithm
-  // positions the line box. |SetCurrentLine| sets the children, and the next
-  // |AddLine| adds them.
+  // positions the line box.
   //
-  // The caller must keep |children| alive until |AddLine| completes.
-  void SetCurrentLine(const NGPhysicalLineBoxFragment& line,
-                      NGLogicalLineItems* current_line);
+  // 1. |AcquireLogicalLineItems| to get an instance of |NGLogicalLineItems|.
+  // 2. Add items to |NGLogicalLineItems| and create |NGPhysicalFragment|,
+  //    then associate them by |AssociateLogicalLineItems|.
+  // 3. |AddLine| adds the |NGPhysicalLineBoxFragment|.
+  //
+  // |NGBlockLayoutAlgorithm| runs these phases in the order for each line. In
+  // this case, one instance of |NGLogicalLineItems| is reused for all lines to
+  // reduce memory allocations.
+  //
+  // Custom layout produces all line boxes first by running only 1 and 2 (in
+  // |NGInlineLayoutAlgorithm|). Then after worklet determined the position and
+  // the order of line boxes, it runs 3 for each line. In this case,
+  // |NGFragmentItemsBuilder| allocates new instance for each line, and keeps
+  // them alive until |AddLine|.
+  NGLogicalLineItems* AcquireLogicalLineItems();
+  void AssociateLogicalLineItems(NGLogicalLineItems* line_items,
+                                 const NGPhysicalFragment& line_fragment);
   void AddLine(const NGPhysicalLineBoxFragment& line,
                const LogicalOffset& offset);
-  void ClearCurrentLineForTesting();
+
+  // Add to |NGLogicalLineItems| instance pool. |AcquireLogicalLineItems|
+  // uses pooled instances first if available to avoid memory allocations.
+  void AddLogicalLineItemsPool(NGLogicalLineItems* line_items);
 
   // Add a list marker to the current line.
   void AddListMarker(const NGPhysicalBoxFragment& marker_fragment,
@@ -122,6 +136,9 @@
   void ToFragmentItems(const PhysicalSize& outer_size, void* data);
 
  private:
+  void ReleaseCurrentLogicalLineItems();
+  void MoveCurrentLogicalLineItemsToMap();
+
   void AddItems(NGLogicalLineItem* child_begin, NGLogicalLineItem* child_end);
 
   void ConvertToPhysical(const PhysicalSize& outer_size);
@@ -131,7 +148,11 @@
   String first_line_text_content_;
 
   // Keeps children of a line until the offset is determined. See |AddLine|.
-  NGLogicalLineItems* current_line_ = nullptr;
+  NGLogicalLineItems* current_line_items_ = nullptr;
+  const NGPhysicalFragment* current_line_fragment_ = nullptr;
+
+  HashMap<const NGPhysicalFragment*, NGLogicalLineItems*> line_items_map_;
+  NGLogicalLineItems* line_items_pool_ = nullptr;
 
   NGInlineNode node_;
 
@@ -139,10 +160,7 @@
 
   bool has_floating_descendants_for_paint_ = false;
   bool is_converted_to_physical_ = false;
-
-#if DCHECK_IS_ON()
-  const NGPhysicalLineBoxFragment* current_line_fragment_ = nullptr;
-#endif
+  bool is_line_items_pool_acquired_ = false;
 
   friend class NGFragmentItems;
 };
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc
new file mode 100644
index 0000000..e4818069
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc
@@ -0,0 +1,143 @@
+// 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/core/layout/ng/inline/ng_fragment_item.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
+
+using testing::ElementsAre;
+
+namespace blink {
+
+class NGFragmentItemsBuilderTest : public NGLayoutTest,
+                                   ScopedLayoutNGFragmentItemForTest {
+ public:
+  NGFragmentItemsBuilderTest() : ScopedLayoutNGFragmentItemForTest(true) {}
+};
+
+TEST_F(NGFragmentItemsBuilderTest, MultipleLogicalLineItems) {
+  SetBodyInnerHTML(R"HTML(
+    <div id="container">
+      1<br>
+      2
+    </div>
+  )HTML");
+  LayoutBlockFlow* container =
+      To<LayoutBlockFlow>(GetLayoutObjectByElementId("container"));
+
+  // Get |NGPhysicalLineBoxFragment|s to use for testing.
+  NGInlineCursor cursor(*container);
+  cursor.MoveToFirstLine();
+  const NGPhysicalLineBoxFragment* line_fragment1 =
+      cursor.Current()->LineBoxFragment();
+  cursor.MoveToNextLine();
+  const NGPhysicalLineBoxFragment* line_fragment2 =
+      cursor.Current()->LineBoxFragment();
+
+  NGInlineNode inline_node(container);
+  NGLogicalLineItems line_items_pool;
+  {
+    // First test emulates what |NGBlockLayoutAlgorithm| does, which loops
+    // following calls for each line:
+    // 1. |AcquireLogicalLineItems|
+    // 2. |AssociateLogicalLineItems|
+    // 3. |AddLine|.
+    NGFragmentItemsBuilder items_builder(
+        inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
+    NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
+    items_builder.AddLine(*line_fragment1, LogicalOffset());
+    NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items2, *line_fragment2);
+    items_builder.AddLine(*line_fragment2, LogicalOffset());
+
+    // In this case, we should reuse one |NGLogicalLineItems| instance.
+    EXPECT_EQ(line_items1, &line_items_pool);
+    EXPECT_EQ(line_items1, line_items2);
+
+    const auto& items = items_builder.Items(PhysicalSize());
+    EXPECT_EQ(items.size(), 2u);
+    EXPECT_EQ(items[0].item->LineBoxFragment(), line_fragment1);
+    EXPECT_EQ(items[1].item->LineBoxFragment(), line_fragment2);
+  }
+  {
+    // Custom layout produces all line boxes first without adding them to the
+    // container box. Then runs worklet, and add line boxes to the container
+    // box.
+    NGFragmentItemsBuilder items_builder(
+        inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
+    NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
+    NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items2, *line_fragment2);
+
+    // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
+    // be allocated for line 2.
+    EXPECT_EQ(line_items1, &line_items_pool);
+    EXPECT_NE(line_items1, line_items2);
+
+    items_builder.AddLine(*line_fragment1, LogicalOffset());
+    items_builder.AddLine(*line_fragment2, LogicalOffset());
+    const auto& items = items_builder.Items(PhysicalSize());
+    EXPECT_EQ(items.size(), 2u);
+    EXPECT_EQ(items[0].item->LineBoxFragment(), line_fragment1);
+    EXPECT_EQ(items[1].item->LineBoxFragment(), line_fragment2);
+  }
+  {
+    // Custom layout can reorder line boxes. In this test, line boxes are added
+    // to the container box in the reverse order.
+    NGFragmentItemsBuilder items_builder(
+        inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
+    NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
+    NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items2, *line_fragment2);
+
+    // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
+    // be allocated for line 2.
+    EXPECT_EQ(line_items1, &line_items_pool);
+    EXPECT_NE(line_items1, line_items2);
+
+    // Add lines in the reverse order.
+    items_builder.AddLine(*line_fragment2, LogicalOffset());
+    items_builder.AddLine(*line_fragment1, LogicalOffset());
+    const auto& items = items_builder.Items(PhysicalSize());
+    EXPECT_EQ(items.size(), 2u);
+    EXPECT_EQ(items[0].item->LineBoxFragment(), line_fragment2);
+    EXPECT_EQ(items[1].item->LineBoxFragment(), line_fragment1);
+  }
+  {
+    // Custom layout may not add all line boxes.
+    NGFragmentItemsBuilder items_builder(
+        inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
+    NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
+    NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
+    items_builder.AssociateLogicalLineItems(line_items2, *line_fragment2);
+
+    // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
+    // be allocated for line 2.
+    EXPECT_EQ(line_items1, &line_items_pool);
+    EXPECT_NE(line_items1, line_items2);
+
+    // Add line2, but not line1.
+    items_builder.AddLine(*line_fragment2, LogicalOffset());
+    const auto& items = items_builder.Items(PhysicalSize());
+    EXPECT_EQ(items.size(), 1u);
+    EXPECT_EQ(items[0].item->LineBoxFragment(), line_fragment2);
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
index ed45064a..82cd170a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
@@ -29,7 +29,10 @@
 
   NGFragmentItemsBuilder* ItemsBuilder() { return items_builder_; }
   void SetItemsBuilder(NGFragmentItemsBuilder* builder) {
+    DCHECK(!items_builder_ || !builder);
     items_builder_ = builder;
+    if (builder)
+      builder->AddLogicalLineItemsPool(&logical_line_items_);
   }
 
   // Returns an instance of |NGLogicalLineItems|. This is reused when laying out
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 3c912c2..a8688cd 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -997,7 +997,10 @@
   NGExclusionSpace exclusion_space;
   const NGInlineBreakToken* break_token = BreakToken();
 
-  NGLogicalLineItems* line_box = context_->LogicalLineItems();
+  NGFragmentItemsBuilder* items_builder = context_->ItemsBuilder();
+  NGLogicalLineItems* line_box = items_builder
+                                     ? items_builder->AcquireLogicalLineItems()
+                                     : context_->LogicalLineItems();
 
   bool is_line_created = false;
   LayoutUnit line_block_size;
@@ -1143,14 +1146,13 @@
   CHECK(is_line_created);
   container_builder_.SetExclusionSpace(std::move(exclusion_space));
 
-  if (NGFragmentItemsBuilder* items_builder = context_->ItemsBuilder()) {
+  if (items_builder) {
     DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
     container_builder_.PropagateChildrenData(*line_box);
     scoped_refptr<const NGLayoutResult> layout_result =
         container_builder_.ToLineBoxFragment();
-    items_builder->SetCurrentLine(
-        To<NGPhysicalLineBoxFragment>(layout_result->PhysicalFragment()),
-        line_box);
+    items_builder->AssociateLogicalLineItems(line_box,
+                                             layout_result->PhysicalFragment());
     return layout_result;
   }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index e6385902..2d0b3d9 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -67,14 +67,12 @@
   EXPECT_FALSE(line1.BreakToken()->IsFinished());
 
   // Perform 2nd layout with the break token from the 1st line.
-  items_builder.ClearCurrentLineForTesting();
   scoped_refptr<const NGLayoutResult> layout_result2 =
       inline_node.Layout(constraint_space, line1.BreakToken(), &context);
   const auto& line2 = layout_result2->PhysicalFragment();
   EXPECT_FALSE(line2.BreakToken()->IsFinished());
 
   // Perform 3rd layout with the break token from the 2nd line.
-  items_builder.ClearCurrentLineForTesting();
   scoped_refptr<const NGLayoutResult> layout_result3 =
       inline_node.Layout(constraint_space, line2.BreakToken(), &context);
   const auto& line3 = layout_result3->PhysicalFragment();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
index 92eaa4b..be4ca52a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
@@ -223,8 +223,6 @@
 // Unlike the fragment builder, chlidren are mutable.
 // Callers can add to the fragment builder in a batch once finalized.
 class NGLogicalLineItems {
-  STACK_ALLOCATED();
-
  public:
   NGLogicalLineItems() = default;
   void operator=(NGLogicalLineItems&& other) {
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
index 8bc34ca7..36e3bdf4 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
@@ -131,4 +131,14 @@
   LayoutNGBlockFlow::InvalidatePaint(context);
 }
 
+bool LayoutNGFieldset::BackgroundIsKnownToBeOpaqueInRect(
+    const PhysicalRect& local_rect) const {
+  // If the field set has a legend, then it probably does not completely fill
+  // its background.
+  if (LayoutFieldset::FindInFlowLegend(*this))
+    return false;
+
+  return LayoutBlockFlow::BackgroundIsKnownToBeOpaqueInRect(local_rect);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h b/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
index 8b15b875..21cf081 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
@@ -24,6 +24,7 @@
  protected:
   bool IsOfType(LayoutObjectType) const override;
   void InvalidatePaint(const PaintInvalidatorContext& context) const final;
+  bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
index a657cce..9359a1e29 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -446,7 +446,7 @@
     return;
   const DocumentLifecycle& lifecycle = GetDocument().Lifecycle();
   DCHECK(lifecycle.GetState() >= DocumentLifecycle::kLayoutClean &&
-         lifecycle.GetState() < DocumentLifecycle::kCompositingClean)
+         lifecycle.GetState() < DocumentLifecycle::kCompositingAssignmentsClean)
       << lifecycle.GetState();
 }
 #endif
diff --git a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
index 3bf7edc..69a978e 100644
--- a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
@@ -49,8 +49,6 @@
       worker_main_script_load_params =
           global_scope_->TakeWorkerMainScriptLoadingParametersForModules();
   if (worker_main_script_load_params) {
-    DCHECK(base::FeatureList::IsEnabled(
-        features::kLoadMainScriptForPlzDedicatedWorkerByParams));
     DCHECK_EQ(level_, ModuleGraphLevel::kTopLevelModuleFetch);
 
     fetch_params.MutableResourceRequest().SetInspectorId(
@@ -204,8 +202,6 @@
 }
 
 void WorkerModuleScriptFetcher::DidReceiveData(base::span<const char> span) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   if (!decoder_) {
     decoder_ = std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
         TextResourceDecoderOptions::kPlainTextContent,
@@ -218,8 +214,6 @@
 
 void WorkerModuleScriptFetcher::OnStartLoadingBody(
     const ResourceResponse& resource_response) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   if (!MIMETypeRegistry::IsSupportedJavaScriptMIMEType(
           resource_response.HttpContentType())) {
     HeapVector<Member<ConsoleMessage>> error_messages;
@@ -241,8 +235,6 @@
 }
 
 void WorkerModuleScriptFetcher::OnFinishedLoadingWorkerMainScript() {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   const ResourceResponse& response = worker_main_script_loader_->GetResponse();
   if (decoder_)
     source_text_.Append(decoder_->Flush());
@@ -254,8 +246,6 @@
 }
 
 void WorkerModuleScriptFetcher::OnFailedLoadingWorkerMainScript() {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   client_->NotifyFetchFinished(base::nullopt,
                                HeapVector<Member<ConsoleMessage>>());
 }
diff --git a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
index d676f8d..ce9cf62 100644
--- a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
+++ b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h
@@ -33,8 +33,8 @@
              ModuleGraphLevel,
              ModuleScriptFetcher::Client*) override;
 
-  // Implements WorkerMainScriptLoaderClient, and these will be called only when
-  // features::kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // Implements WorkerMainScriptLoaderClient, and these will be called for
+  // dedicated workers (when PlzDedicatedWorker is enabled) and shared workers.
   void DidReceiveData(base::span<const char> span) override;
   void OnStartLoadingBody(const ResourceResponse& resource_response) override;
   void OnFinishedLoadingWorkerMainScript() override;
@@ -56,8 +56,8 @@
 
   const Member<WorkerGlobalScope> global_scope_;
 
-  // These are used only when
-  // features::kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // These are used for dedicated workers (when PlzDedicatedWorker is enabled)
+  // and shared workers.
   Member<WorkerMainScriptLoader> worker_main_script_loader_;
   std::unique_ptr<TextResourceDecoder> decoder_;
   StringBuilder source_text_;
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index 5cecf06..e2877b92 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -370,7 +370,7 @@
 
 void CompositedLayerMapping::UpdateCompositedBounds() {
   DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
-            DocumentLifecycle::kInCompositingUpdate);
+            DocumentLifecycle::kInCompositingAssignmentsUpdate);
   // FIXME: if this is really needed for performance, it would be better to
   // store it on Layer.
   composited_bounds_ = owning_layer_.BoundingBoxForCompositing();
@@ -387,7 +387,7 @@
 bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
     const PaintLayer* compositing_container) {
   DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
-            DocumentLifecycle::kInCompositingUpdate);
+            DocumentLifecycle::kInCompositingAssignmentsUpdate);
 
   // Note carefully: here we assume that the compositing state of all
   // descendants have been updated already, so it is legitimate to compute and
@@ -464,9 +464,6 @@
     // Changes to either the internal hierarchy or the mask layer have an impact
     // on painting phases, so we need to update when either are updated.
     UpdatePaintingPhases();
-    // Need to update paint LayerState of the changed GraphicsLayers.
-    // The pre-paint tree walk does this.
-    layout_object.SetNeedsPaintPropertyUpdate();
   }
 
   UpdateElementId();
@@ -701,8 +698,8 @@
   if (new_offset != non_scrolling_squashing_layer_offset_from_layout_object_) {
     non_scrolling_squashing_layer_offset_from_layout_object_ = new_offset;
     // Need to update squashing LayerState according to the new offset.
-    // The pre-paint tree walk does this.
-    GetLayoutObject().SetNeedsPaintPropertyUpdate();
+    // GraphicsLayerUpdater does this.
+    layers_needing_paint_invalidation.push_back(&owning_layer_);
   }
 
   for (auto& layer : layers)
@@ -713,7 +710,7 @@
     const PaintLayer* compositing_container,
     Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
-            DocumentLifecycle::kInCompositingUpdate);
+            DocumentLifecycle::kInCompositingAssignmentsUpdate);
 
   IntRect local_compositing_bounds;
   IntPoint snapped_offset_from_composited_ancestor;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
index 4e47cec..ca001ef 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
@@ -53,7 +53,7 @@
   TRACE_EVENT0("blink", "CompositingLayerAssigner::assign");
 
   SquashingState squashing_state;
-  AssignLayersToBackingsInternal(update_root, squashing_state,
+  AssignLayersToBackingsInternal(update_root, update_root, squashing_state,
                                  layers_needing_paint_invalidation);
   if (squashing_state.most_recent_mapping) {
     squashing_state.most_recent_mapping->FinishAccumulatingSquashingLayers(
@@ -290,12 +290,10 @@
 
 void CompositingLayerAssigner::AssignLayersToBackingsInternal(
     PaintLayer* layer,
+    PaintLayer* paint_invalidation_container,
     SquashingState& squashing_state,
     Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   if (layer->NeedsCompositingLayerAssignment()) {
-    DCHECK(layer->GetCompositingReasons() ||
-           (layer->GetCompositingState() != kNotComposited) ||
-           layer->LostGroupedMapping());
     if (RequiresSquashing(layer->GetCompositingReasons())) {
       SquashingDisallowedReasons reasons_preventing_squashing =
           GetReasonsPreventingSquashing(layer, squashing_state);
@@ -354,10 +352,14 @@
     }
   }
 
+  if (layer->GetCompositingState() != kNotComposited)
+    paint_invalidation_container = layer;
+
   if (layer->StackingDescendantNeedsCompositingLayerAssignment()) {
     PaintLayerPaintOrderIterator iterator(*layer, kNegativeZOrderChildren);
     while (PaintLayer* child_node = iterator.Next()) {
-      AssignLayersToBackingsInternal(child_node, squashing_state,
+      AssignLayersToBackingsInternal(child_node, paint_invalidation_container,
+                                     squashing_state,
                                      layers_needing_paint_invalidation);
     }
   }
@@ -375,7 +377,8 @@
     PaintLayerPaintOrderIterator iterator(*layer,
                                           kNormalFlowAndPositiveZOrderChildren);
     while (PaintLayer* curr_layer = iterator.Next()) {
-      AssignLayersToBackingsInternal(curr_layer, squashing_state,
+      AssignLayersToBackingsInternal(curr_layer, paint_invalidation_container,
+                                     squashing_state,
                                      layers_needing_paint_invalidation);
     }
   }
@@ -397,6 +400,19 @@
         false;
   }
 
+  if (layer->NeedsCheckRasterInvalidation()) {
+    DCHECK(paint_invalidation_container);
+    if (!paint_invalidation_container->SelfNeedsRepaint()) {
+      auto* mapping = paint_invalidation_container->GetCompositedLayerMapping();
+      if (!mapping)
+        mapping = paint_invalidation_container->GroupedMapping();
+      if (mapping)
+        mapping->SetNeedsCheckRasterInvalidation();
+    }
+
+    layer->ClearNeedsCheckRasterInvalidation();
+  }
+
   layer->ClearNeedsCompositingLayerAssignment();
 }
 
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
index 8763b86c..d3d926e 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
@@ -93,7 +93,8 @@
   };
 
   void AssignLayersToBackingsInternal(
-      PaintLayer*,
+      PaintLayer* layer,
+      PaintLayer* paint_invalidation_container,
       SquashingState&,
       Vector<PaintLayer*>& layers_needing_paint_invalidation);
   SquashingDisallowedReasons GetReasonsPreventingSquashing(
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
index 7683733..fea7513 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/core/layout/layout_block.h"
 #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
 #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
+#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
 #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -138,6 +139,10 @@
         scrollable_area->PositionOverflowControls();
       update_type = mapping->UpdateTypeForChildren(update_type);
       mapping->ClearNeedsGraphicsLayerUpdate();
+
+      // TODO(crbug.com/1058792): Allow multiple fragments for composited
+      // elements (passing |iterator| here is probably part of the solution).
+      CompositingLayerPropertyUpdater::Update(layer.GetLayoutObject());
     }
   }
 
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
index 8b15a46..09cb39c 100644
--- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
+++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -107,8 +107,11 @@
 
 void PaintLayerCompositor::UpdateInputsIfNeededRecursiveInternal(
     DocumentLifecycle::LifecycleState target_state) {
-  if (layout_view_->GetFrameView()->ShouldThrottleRendering())
+  if (layout_view_->GetFrameView()->ShouldThrottleRendering()) {
     return;
+  }
+
+  Lifecycle().AdvanceTo(DocumentLifecycle::kInCompositingInputsUpdate);
 
   for (Frame* child =
            layout_view_->GetFrameView()->GetFrame().Tree().FirstChild();
@@ -144,8 +147,6 @@
 
   layout_view_->CommitPendingSelection();
 
-  Lifecycle().AdvanceTo(DocumentLifecycle::kInCompositingInputsUpdate);
-
   if (pending_update_type_ >= kCompositingUpdateAfterCompositingInputChange) {
     CompositingInputsUpdater updater(RootLayer(), GetCompositingInputsRoot());
     updater.Update();
@@ -175,6 +176,8 @@
 
 void PaintLayerCompositor::UpdateAssignmentsIfNeededRecursive(
     DocumentLifecycle::LifecycleState target_state) {
+  DCHECK_GE(target_state, DocumentLifecycle::kCompositingAssignmentsClean);
+
   CompositingReasonsStats compositing_reasons_stats;
   UpdateAssignmentsIfNeededRecursiveInternal(target_state,
                                              compositing_reasons_stats);
@@ -198,11 +201,13 @@
 void PaintLayerCompositor::UpdateAssignmentsIfNeededRecursiveInternal(
     DocumentLifecycle::LifecycleState target_state,
     CompositingReasonsStats& compositing_reasons_stats) {
+  if (target_state == DocumentLifecycle::kCompositingInputsClean)
+    return;
+
   if (layout_view_->GetFrameView()->ShouldThrottleRendering())
     return;
 
-  if (target_state == DocumentLifecycle::kCompositingInputsClean)
-    return;
+  Lifecycle().AdvanceTo(DocumentLifecycle::kInCompositingAssignmentsUpdate);
 
   LocalFrameView* view = layout_view_->GetFrameView();
   view->ResetNeedsForcedCompositingUpdate();
@@ -235,8 +240,11 @@
 
   UpdateAssignmentsIfNeeded(target_state, compositing_reasons_stats);
 
+  Lifecycle().AdvanceTo(DocumentLifecycle::kCompositingAssignmentsClean);
+
 #if DCHECK_IS_ON()
-  DCHECK_EQ(Lifecycle().GetState(), DocumentLifecycle::kCompositingClean);
+  DCHECK_EQ(Lifecycle().GetState(),
+            DocumentLifecycle::kCompositingAssignmentsClean);
   AssertNoUnresolvedDirtyBits();
   for (Frame* child =
            layout_view_->GetFrameView()->GetFrame().Tree().FirstChild();
@@ -269,8 +277,6 @@
 
   if (layout_view_->DocumentBeingDestroyed())
     return;
-
-  Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean);
 }
 
 #if DCHECK_IS_ON()
@@ -286,9 +292,7 @@
 void PaintLayerCompositor::UpdateAssignmentsIfNeeded(
     DocumentLifecycle::LifecycleState target_state,
     CompositingReasonsStats& compositing_reasons_stats) {
-  DCHECK(target_state >= DocumentLifecycle::kCompositingClean);
-
-  Lifecycle().AdvanceTo(DocumentLifecycle::kInCompositingUpdate);
+  DCHECK(target_state >= DocumentLifecycle::kCompositingAssignmentsClean);
 
   CompositingUpdateType update_type = pending_update_type_;
   pending_update_type_ = kCompositingUpdateNone;
@@ -297,7 +301,6 @@
            .GetSettings()
            ->GetAcceleratedCompositingEnabled() ||
       update_type == kCompositingUpdateNone) {
-    Lifecycle().AdvanceTo(DocumentLifecycle::kCompositingClean);
     return;
   }
 
@@ -363,12 +366,8 @@
   }
 
   for (auto* layer : layers_needing_paint_invalidation) {
-    // We need to repaint all containing paint subsequences, because parts of
-    // them may have changed composited layer backings.
     PaintInvalidationOnCompositingChange(layer);
   }
-
-  Lifecycle().AdvanceTo(DocumentLifecycle::kCompositingClean);
 }
 
 static void RestartAnimationOnCompositor(const LayoutObject& layout_object) {
@@ -455,11 +454,6 @@
     return;
 
   layer->SetNeedsRepaint();
-  // We need to cause CompositingLayerPropertyUpdater::Update to run on
-  // |layer|. This currently happens in the PrePaintTreeWalk, which is
-  // triggered by SetNeedsPaintPropertyUpdate(); that is the reason for
-  // calling SetNeedsPaintPropertyUpdate().
-  layer->GetLayoutObject().SetNeedsPaintPropertyUpdate();
   // We need to check for raster invalidations due to content changing
   // composited layer backings.
   DisableCompositingQueryAsserts compositing_disabler;
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
index 3a08814..7154b1a 100644
--- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
+++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -94,7 +94,11 @@
   void UpdateAcceleratedCompositingSettings();
 
   // Used to indicate that a compositing update will be needed for the next
-  // frame that gets drawn.
+  // frame that gets drawn. If called from before the compositing inputs
+  // step has run, and the type is > kCompositingUpdateNone, compositing
+  // inputs will be re-computed. If called during pre-paint (which is after
+  // compositing inputs and before the rest of compositing), it will cause
+  // the rest of compositing to run, but not compositing inputs.
   void SetNeedsCompositingUpdate(CompositingUpdateType);
 
   // Whether the given layer needs an extra 'contents' layer.
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc
index 3ca2029..a4bf31c 100644
--- a/third_party/blink/renderer/core/paint/frame_painter.cc
+++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -61,7 +61,7 @@
   // TODO(wangxianzhu): The following check should be stricter, but currently
   // this is blocked by the svg root issue (crbug.com/442939).
   DCHECK(document->Lifecycle().GetState() >=
-         DocumentLifecycle::kCompositingClean);
+         DocumentLifecycle::kCompositingAssignmentsClean);
 
   FramePaintTiming frame_paint_timing(context, &GetFrameView().GetFrame());
   TRACE_EVENT1("devtools.timeline,rail", "Paint", "data",
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index 210e82a..0ed180f4 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -186,6 +186,7 @@
       static_inline_edge_(InlineEdge::kInlineStart),
       static_block_edge_(BlockEdge::kBlockStart),
       needs_paint_offset_translation_for_compositing_(false),
+      needs_check_raster_invalidation_(false),
 #if DCHECK_IS_ON()
       layer_list_mutation_allowed_(true),
 #endif
@@ -1030,7 +1031,7 @@
 
 PaintLayer* PaintLayer::EnclosingDirectlyCompositableLayer(
     IncludeSelfOrNot include_self_or_not) const {
-  DCHECK(IsAllowedToQueryCompositingState());
+  DCHECK(IsAllowedToQueryCompositingInputs());
   if (include_self_or_not == kIncludeSelf && CanBeCompositedForDirectReasons())
     return const_cast<PaintLayer*>(this);
 
@@ -1054,6 +1055,16 @@
     MarkAncestorChainForFlagsUpdate(NeedsDescendantDependentUpdate);
 }
 
+void PaintLayer::SetNeedsCheckRasterInvalidation() {
+  DCHECK_EQ(GetLayoutObject().GetDocument().Lifecycle().GetState(),
+            DocumentLifecycle::kInPrePaint);
+  needs_check_raster_invalidation_ = true;
+  // We need to mark |this| as needing layer assignment also, because
+  // CompositingLayerAssigner is where we transfer the raster invalidation
+  // checking bit from PaintLayer to GraphicsLayer.
+  SetNeedsCompositingLayerAssignment();
+}
+
 void PaintLayer::SetNeedsVisualOverflowRecalc() {
   DCHECK(IsSelfPaintingLayer());
   needs_visual_overflow_recalc_ = true;
@@ -1903,7 +1914,7 @@
                                      bool check_resizer_only) {
   const LayoutObject& layout_object = GetLayoutObject();
   DCHECK_GE(layout_object.GetDocument().Lifecycle().GetState(),
-            DocumentLifecycle::kCompositingClean);
+            DocumentLifecycle::kPrePaintClean);
 
   if (!IsSelfPaintingLayer() && !HasSelfPaintingLayerDescendant())
     return nullptr;
@@ -2457,7 +2468,10 @@
 }
 
 FloatRect PaintLayer::FilterReferenceBox() const {
-  DCHECK(IsAllowedToQueryCompositingState());
+#if DCHECK_IS_ON()
+  DCHECK(GetLayoutObject().GetDocument().Lifecycle().GetState() >=
+         DocumentLifecycle::kInPrePaint);
+#endif
   if (ResourceInfo())
     return ResourceInfo()->FilterReferenceBox();
   return FloatRect();
@@ -2757,7 +2771,10 @@
 }
 
 CompositingState PaintLayer::GetCompositingState() const {
-  DCHECK(IsAllowedToQueryCompositingState());
+#if DCHECK_IS_ON()
+  DCHECK(IsAllowedToQueryCompositingState())
+      << " " << GetLayoutObject().GetDocument().Lifecycle().ToString();
+#endif
 
   // This is computed procedurally so there is no redundant state variable that
   // can get out of sync from the real actual compositing state.
@@ -2777,8 +2794,18 @@
   if (g_compositing_query_mode == kCompositingQueriesAreAllowed ||
       RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
     return true;
+  if (!GetLayoutObject().GetFrameView()->IsUpdatingLifecycle())
+    return true;
   return GetLayoutObject().GetDocument().Lifecycle().GetState() >=
-         DocumentLifecycle::kInCompositingUpdate;
+         DocumentLifecycle::kInCompositingAssignmentsUpdate;
+}
+
+bool PaintLayer::IsAllowedToQueryCompositingInputs() const {
+  if (g_compositing_query_mode == kCompositingQueriesAreAllowed ||
+      RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+    return true;
+  return GetLayoutObject().GetDocument().Lifecycle().GetState() >=
+         DocumentLifecycle::kCompositingInputsClean;
 }
 
 CompositedLayerMapping* PaintLayer::GetCompositedLayerMapping() const {
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h
index d835d5b..507d79d 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -568,6 +568,8 @@
   // which compositing state may legally be read.
   bool IsAllowedToQueryCompositingState() const;
 
+  bool IsAllowedToQueryCompositingInputs() const;
+
   // Don't null check this.
   // FIXME: Rename.
   CompositedLayerMapping* GetCompositedLayerMapping() const;
@@ -819,6 +821,16 @@
   void SetNeedsVisualOverflowRecalc();
   void SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags = true);
 
+  // Mark this PaintLayer as needing raster invalidation checking after the
+  // next compositing update step.
+  void SetNeedsCheckRasterInvalidation();
+  bool NeedsCheckRasterInvalidation() const {
+    return needs_check_raster_invalidation_;
+  }
+  void ClearNeedsCheckRasterInvalidation() {
+    needs_check_raster_invalidation_ = false;
+  }
+
   // This methods marks everything from this layer up to the |ancestor| argument
   // (both included).
   void SetChildNeedsCompositingInputsUpdateUpToAncestor(PaintLayer* ancestor);
@@ -1123,7 +1135,7 @@
 
   bool NeedsPaintOffsetTranslationForCompositing() const {
     DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
-    DCHECK(IsAllowedToQueryCompositingState());
+    DCHECK(IsAllowedToQueryCompositingInputs());
     return needs_paint_offset_translation_for_compositing_;
   }
 
@@ -1382,6 +1394,8 @@
 
   unsigned needs_paint_offset_translation_for_compositing_ : 1;
 
+  unsigned needs_check_raster_invalidation_ : 1;
+
 #if DCHECK_IS_ON()
   mutable unsigned layer_list_mutation_allowed_ : 1;
 #endif
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index ee715e7..c04a91f 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -132,7 +132,7 @@
   // PaintLayer::previousXXX() when paintLayer is composited scrolling and is
   // painted twice for GraphicsLayers of container and scrolling contents.
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-      paint_layer.GetCompositingState() == kPaintsIntoOwnBacking)
+      (paint_layer.GetCompositingState() == kPaintsIntoOwnBacking))
     return false;
 
   return true;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index ecf5a35..88eafe7 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2402,6 +2402,10 @@
   // PaintPropertyTreeBuilder::updateScrollAndScrollTranslation).
   GetLayoutBox()->SetNeedsPaintPropertyUpdate();
 
+  // ScrollsOverflow() is an input into UpdateNeedsCompositedScrolling, which
+  // is computed during the compositing inputs update.
+  layer_->SetNeedsCompositingInputsUpdate(false);
+
   // Scroll hit test data depend on whether the box scrolls overflow.
   // They are painted in the background phase
   // (see: BoxPainter::PaintBoxDecorationBackground).
@@ -2521,7 +2525,8 @@
     DCHECK(GetDocument()->Lifecycle().GetState() ==
                DocumentLifecycle::kInCompositingInputsUpdate ||
            GetDocument()->Lifecycle().GetState() ==
-               DocumentLifecycle::kInCompositingUpdate);
+               DocumentLifecycle::kInCompositingAssignmentsUpdate)
+        << " " << GetDocument()->Lifecycle().ToString();
   }
 #endif
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
index a24e12f..c7bb3b7 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -559,16 +559,16 @@
   Element* scroller = GetDocument().getElementById("scroller");
   EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject()));
 
+  // pointer-events: none causes the scoller to be invisible for hit testing,
+  // so ScrollsOverflow becomes false on the PaintLayerScrollableArea, and hence
+  // composited scrolling is not present.
   scroller->setAttribute(html_names::kStyleAttr, "pointer-events: none");
   UpdateAllLifecyclePhasesForTest();
   EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject()));
 
   scroller->setAttribute(html_names::kStyleAttr, "");
   UpdateAllLifecyclePhasesForTest();
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
-    EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject()));
-  else
-    EXPECT_FALSE(UsesCompositedScrolling(scroller->GetLayoutObject()));
+  EXPECT_TRUE(UsesCompositedScrolling(scroller->GetLayoutObject()));
 }
 
 // Test that <input> elements don't use composited scrolling even with
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
index cb0a81b..3e1f566 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -25,7 +25,7 @@
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
-#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
+#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/paint/paint_property_tree_printer.h"
@@ -142,6 +142,35 @@
 
 }  // anonymous namespace
 
+static void SetNeedsCompositingLayerPropertyUpdate(const LayoutObject& object) {
+  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+    return;
+
+  if (!object.HasLayer())
+    return;
+
+  auto* compositor = object.View()->Compositor();
+  if (!compositor)
+    return;
+
+  PaintLayer* paint_layer = ToLayoutBoxModelObject(object).Layer();
+
+  DisableCompositingQueryAsserts disabler;
+  // This ensures that CompositingLayerPropertyUpdater::Update will
+  // be called and update LayerState for the LayoutView.
+  auto* mapping = paint_layer->GetCompositedLayerMapping();
+  if (!mapping)
+    mapping = paint_layer->GroupedMapping();
+  if (!mapping)
+    return;
+
+  // These two calls will cause GraphicsLayerUpdater to run on |paint_layer|
+  // from with PLC::UpdateIfNeeded.
+  compositor->SetNeedsCompositingUpdate(
+      kCompositingUpdateAfterCompositingInputChange);
+  mapping->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateLocal);
+}
+
 void PrePaintTreeWalk::WalkTree(LocalFrameView& root_frame_view) {
   if (root_frame_view.ShouldThrottleRendering()) {
     // Skip the throttled frame. Will update it when it becomes unthrottled.
@@ -172,6 +201,8 @@
     if (property_changed >
         PaintPropertyChangeType::kChangedOnlyCompositedValues) {
       root_frame_view.SetPaintArtifactCompositorNeedsUpdate();
+      if (auto* layout_view = root_frame_view.GetLayoutView())
+        SetNeedsCompositingLayerPropertyUpdate(*layout_view);
     }
   }
 
@@ -436,6 +467,8 @@
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
     return;
 
+  DisableCompositingQueryAsserts disabler;
+
   if (object.IsPaintInvalidationContainer()) {
     context.paint_invalidation_container = ToLayoutBoxModelObject(&object);
     if (object.IsStackingContext() || object.IsSVGRoot()) {
@@ -551,6 +584,11 @@
         if ((property_changed >
              PaintPropertyChangeType::kChangedOnlyCompositedValues) &&
             context.paint_invalidation_container) {
+          // Mark the previous paint invalidation container as needing
+          // raster invalidation. This handles cases where raster invalidation
+          // needs to happen but no compositing layers were added or removed.
+          DisableCompositingQueryAsserts disabler;
+
           const auto* paint_invalidation_container =
               context.paint_invalidation_container->Layer();
           if (!paint_invalidation_container->SelfNeedsRepaint()) {
@@ -561,6 +599,8 @@
             if (mapping)
               mapping->SetNeedsCheckRasterInvalidation();
           }
+
+          SetNeedsCompositingLayerPropertyUpdate(object);
         }
       } else if (!context.tree_builder_context
                       ->supports_composited_raster_invalidation) {
@@ -574,10 +614,6 @@
   // may paint more or less results according to the changed clip.
   if (context.clip_changed && object.HasLayer())
     ToLayoutBoxModelObject(object).Layer()->SetNeedsRepaint();
-
-  // TODO(crbug.com/1058792): Allow multiple fragments for composited elements
-  // (passing |iterator| here is probably part of the solution).
-  CompositingLayerPropertyUpdater::Update(object);
 }
 
 LocalFrameView* FindWebViewPluginContentFrameView(
diff --git a/third_party/blink/renderer/core/probe/core_probes.json5 b/third_party/blink/renderer/core/probe/core_probes.json5
index 8af3f7f..9f52fac2 100644
--- a/third_party/blink/renderer/core/probe/core_probes.json5
+++ b/third_party/blink/renderer/core/probe/core_probes.json5
@@ -57,6 +57,8 @@
         "MediaQueryResultChanged",
         "WillChangeStyleElement",
         "LocalFontsEnabled",
+        "DidUpdateComputedStyle",
+        "RecalculateStyle",
       ]
     },
     InspectorDOMAgent: {
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl
index cfcf2cd..0804815 100644
--- a/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -183,4 +183,5 @@
   void SetDevToolsIds(CoreProbeSink*, ResourceRequest& request, const FetchInitiatorInfo&);
   void DidMutateStyleSheet(Document*, CSSStyleSheet* style_sheet);
   void LocalFontsEnabled(ExecutionContext*, bool* result);
+  void DidUpdateComputedStyle([Keep] Element*, const ComputedStyle* old_style, const ComputedStyle* new_style);
 }
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
index 34cacd9..30f6130 100644
--- a/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
+++ b/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc
@@ -1411,7 +1411,7 @@
     EXPECT_TRUE(
         frame_element->contentDocument()->View()->ShouldThrottleRendering());
   }
-  EXPECT_EQ(DocumentLifecycle::kCompositingClean,
+  EXPECT_EQ(DocumentLifecycle::kCompositingAssignmentsClean,
             frame_element->contentDocument()->Lifecycle().GetState());
 }
 
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
index 2524228..83fbd69 100644
--- a/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
+++ b/third_party/blink/renderer/core/scheduler_integration_tests/throttling_test.cc
@@ -272,8 +272,8 @@
     // Tasks are not throttled beyond the default background throttling behavior
     // nor do they get to run more often.
     Vector<String> expected_ouput(
-        base::ClampFloor<wtf_size_t>(
-            kTimeUntilNextCheck.FltDiv(kDefaultThrottledWakeUpInterval)),
+        base::ClampFloor<wtf_size_t>(kTimeUntilNextCheck /
+                                     kDefaultThrottledWakeUpInterval),
         "called onTimer");
     EXPECT_THAT(ConsoleMessages(), expected_ouput);
   }
diff --git a/third_party/blink/renderer/core/svg/animation/smil_time.h b/third_party/blink/renderer/core/svg/animation/smil_time.h
index 8cfe0d7..a5c9f3c 100644
--- a/third_party/blink/renderer/core/svg/animation/smil_time.h
+++ b/third_party/blink/renderer/core/svg/animation/smil_time.h
@@ -108,17 +108,16 @@
   SMILTime operator-() const { return -time_; }
   // Division and /modulo are used primarily for computing interval
   // progress/repeats.
-  int64_t operator/(SMILTime other) const = delete;
+  double operator/(SMILTime other) const {
+    DCHECK(IsFinite());
+    DCHECK(other.IsFinite());
+    return time_ / other.time_;
+  }
   int64_t IntDiv(SMILTime other) const {
     DCHECK(IsFinite());
     DCHECK(other.IsFinite());
     return time_.IntDiv(other.time_);
   }
-  double FltDiv(SMILTime other) const {
-    DCHECK(IsFinite());
-    DCHECK(other.IsFinite());
-    return time_.FltDiv(other.time_);
-  }
   SMILTime operator%(SMILTime other) const {
     DCHECK(IsFinite());
     DCHECK(other.IsFinite());
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
index 64d9dd2..7acd62e8 100644
--- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -171,9 +171,6 @@
   // Use WorkerMainScriptLoader to load the main script for dedicated workers
   // (PlzDedicatedWorker) and shared workers.
   if (worker_main_script_load_params) {
-    DCHECK(base::FeatureList::IsEnabled(
-        features::kLoadMainScriptForPlzDedicatedWorkerByParams));
-
     request.SetInspectorId(CreateUniqueIdentifier());
     request.SetReferrerString(Referrer::NoReferrer());
     request.SetPriority(ResourceLoadPriority::kHigh);
@@ -302,8 +299,6 @@
 }
 
 void WorkerClassicScriptLoader::DidReceiveData(base::span<const char> span) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   if (!decoder_) {
     decoder_ = std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
         TextResourceDecoderOptions::kPlainTextContent,
@@ -315,8 +310,6 @@
 }
 
 void WorkerClassicScriptLoader::OnFinishedLoadingWorkerMainScript() {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   DidReceiveResponse(0 /*identifier*/,
                      worker_main_script_loader_->GetResponse());
   if (decoder_)
@@ -325,8 +318,6 @@
 }
 
 void WorkerClassicScriptLoader::OnFailedLoadingWorkerMainScript() {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   failed_ = true;
   NotifyFinished();
 }
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.h b/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
index 109ef05..3f31f3c 100644
--- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
+++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.h
@@ -82,12 +82,12 @@
   // TODO(crbug.com/1064920): Remove |reject_coep_unsafe_none| and
   // |blob_url_loader_factory| when PlzDedicatedWorker ships.
   //
-  // |worker_main_script_load_params| is valid only when
-  // features::kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // |worker_main_script_load_params| is valid for dedicated workers (when
+  // PlzDedicatedWorker is enabled) and shared workers.
   //
   // |resource_load_info_notifier| is valid and used to notify of the loading
   // status of the top-level script for DedicatedWorker only when
-  // IsLoadMainScriptForPlzDedicatedWorkerByParamsEnabled() is true
+  // PlzDedicatedWorker is enabled
   void LoadTopLevelScriptAsynchronously(
       ExecutionContext&,
       ResourceFetcher* fetch_client_settings_object_fetcher,
@@ -147,8 +147,8 @@
   void DidFailRedirectCheck() override;
 
   // WorkerMainScriptLoaderClient
-  // These will be called only when
-  // features::kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // These will be called for dedicated workers (when PlzDedicatedWorker is
+  // enabled) and shared workers.
   void DidReceiveData(base::span<const char> span) override;
   void OnFinishedLoadingWorkerMainScript() override;
   void OnFailedLoadingWorkerMainScript() override;
@@ -167,8 +167,8 @@
 
   Member<ThreadableLoader> threadable_loader_;
 
-  // These are used only when
-  // features::kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // These are used for dedicated workers (when PlzDedicatedWorker is enabled)
+  // and shared workers.
   Member<WorkerMainScriptLoader> worker_main_script_loader_;
   String response_encoding_;
   std::unique_ptr<TextResourceDecoder> decoder_;
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index 48657560..3fa2c2c 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -300,8 +300,8 @@
   std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
 
   // |worker_main_script_load_params_for_modules_| is used to load a root module
-  // script only for dedicated worker (when PlzDedicatedWorker is enabled) and
-  // shared worker when kLoadMainScriptForPlzDedicatedWorkerByParams is enabled.
+  // script for dedicated workers (when PlzDedicatedWorker is enabled) and
+  // shared workers.
   std::unique_ptr<WorkerMainScriptLoadParameters>
       worker_main_script_load_params_for_modules_;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index aeac617..427fd79 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -1440,7 +1440,7 @@
 
   // Must be called with lifecycle >= compositing clean.
   DCHECK_GE(GetDocument()->Lifecycle().GetState(),
-            DocumentLifecycle::kCompositingClean);
+            DocumentLifecycle::kCompositingAssignmentsClean);
 
   PaintLayer* layer = ToLayoutBox(layout_object_)->Layer();
 
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 a33ef1d..4571826 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
@@ -1494,7 +1494,7 @@
   DCHECK(node);
   SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument());
 
-  DCHECK(!document_->NeedsLayoutTreeUpdateForNode(*node));
+  DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
   AXObject* obj = Get(node);
   if (!obj)
     return;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
index f0b4621..90e979d 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
@@ -33,8 +33,6 @@
     CrossVariantMojoRemote<mojom::ResourceLoadInfoNotifierInterfaceBase>
         resource_load_info_notifier,
     WorkerMainScriptLoaderClient* client) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kLoadMainScriptForPlzDedicatedWorkerByParams));
   DCHECK(resource_loade_observer);
   DCHECK(client);
   initial_request_.CopyFrom(fetch_params.GetResourceRequest());
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
index 337e3956..2674c87 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
@@ -37,10 +37,8 @@
   WorkerMainScriptLoaderTest()
       : fake_loader_(pending_remote_loader_.InitWithNewPipeAndPassReceiver()),
         client_(MakeGarbageCollected<TestClient>()) {
-    scoped_feature_list_.InitWithFeatures(
-        {blink::features::kLoadMainScriptForPlzDedicatedWorkerByParams,
-         blink::features::kPlzDedicatedWorker},
-        {});
+    scoped_feature_list_.InitWithFeatureState(
+        blink::features::kPlzDedicatedWorker, true);
   }
 
  protected:
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc
index 6ebed02..eb4b8bc 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -38,15 +38,6 @@
 
 static const int kInvalidNextPreviousFlagsValue = -1;
 
-scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner() {
-  if (auto* main_thread_scheduler =
-          scheduler::WebThreadScheduler::MainThreadScheduler()) {
-    return main_thread_scheduler->CleanupTaskRunner();
-  } else {
-    return base::ThreadTaskRunnerHandle::Get();
-  }
-}
-
 void OnDidPresentForceDrawFrame(
     mojom::blink::Widget::ForceRedrawCallback callback,
     const gfx::PresentationFeedback& feedback) {
@@ -162,7 +153,7 @@
 void WidgetBase::Shutdown(
     scoped_refptr<base::SingleThreadTaskRunner> cleanup_runner) {
   if (!cleanup_runner)
-    cleanup_runner = GetCleanupTaskRunner();
+    cleanup_runner = base::ThreadTaskRunnerHandle::Get();
 
   // The |input_event_queue_| is refcounted and will live while an event is
   // being handled. This drops the connection back to this WidgetBase which
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index d140daa3..6daf107 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2151,4 +2151,4 @@
 wpt_internal/serial/serialPort_disconnect-manual.https.html [ Skip ]
 
 # CPU test is enough for this one as there are gradient issues on the GPU
-virtual/gpu/fast/canvas/conic-gradient.html [ Skip ]
\ No newline at end of file
+virtual/gpu/fast/canvas/conic-gradient.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 39b19ae..9ce878e 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1042,7 +1042,7 @@
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-004.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-007.xht [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-008.xht [ Failure ]
-crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-001.xht [ Crash ]
+crbug.com/1112657 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-001.xht [ Crash ]
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-003.xht [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-004.xht [ Failure ]
@@ -1116,6 +1116,7 @@
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/composited-with-overflow-in-next-column.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/change-second-row-height.html [ Failure ]
+crbug.com/1112657 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spanner-after-spanner-before-content.html [ Crash ]
 crbug.com/1105758 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spanner-before-content.html [ Crash ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spanner-into-stf-constrained-width.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spanner-into-stf-unconstrained-width.html [ Failure ]
@@ -1153,7 +1154,7 @@
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/layers-in-multicol.html [ Failure ]
 crbug.com/1066626 virtual/layout_ng_block_frag/fast/multicol/layers-split-across-columns.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/line-too-tall-for-second-outer-row.html [ Failure ]
-crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/many-lines-overflow-in-single-row-inner.html [ Failure ]
+crbug.com/1112657 virtual/layout_ng_block_frag/fast/multicol/many-lines-overflow-in-single-row-inner.html [ Crash ]
 crbug.com/1066626 virtual/layout_ng_block_frag/fast/multicol/mixed-opacity-fixed-test.html [ Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/mixed-opacity-test.html [ Crash Failure ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/mixed-positioning-stacking-order.html [ Crash Failure ]
@@ -1308,7 +1309,6 @@
 #
 crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html [ Pass ]
 crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-block-size.html [ Failure ]
-crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html [ Failure ]
 crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html [ Failure ]
 crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html [ Failure ]
 crbug.com/875235 virtual/layout_ng_fieldset/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-margin-inline.html [ Failure ]
@@ -2717,6 +2717,24 @@
 crbug.com/1105958 external/wpt/payment-request/payment-is-showing.https.html [ Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Linux ] external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/css/css-overflow/overflow-body-propagation-008.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-overflow/overflow-body-propagation-008.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/css/css-overflow/overflow-body-propagation-008.html [ Failure ]
+crbug.com/626703 [ Linux ] virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Mac ] virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Win ] virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/css/css-overflow/overflow-body-propagation-007.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-overflow/overflow-body-propagation-007.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/css/css-overflow/overflow-body-propagation-007.html [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/css/css-pseudo/active-selection-043.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-pseudo/active-selection-043.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/css/css-pseudo/active-selection-043.html [ Failure ]
+crbug.com/626703 [ Linux ] external/wpt/css/css-overflow/overflow-body-propagation-009.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-overflow/overflow-body-propagation-009.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/css/css-overflow/overflow-body-propagation-009.html [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html [ Timeout ]
 crbug.com/626703 [ Mac ] external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html [ Timeout ]
 crbug.com/626703 [ Win ] external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index df1dda86..cd6fb49 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -1041,6 +1041,22 @@
       ]
      ]
     },
+    "start_url-member": {
+     "start_url-member-fail-manual.sub.html": [
+      "b0743e7d86ee198f39363a3ed1cadd16be634e81",
+      [
+       null,
+       {}
+      ]
+     ],
+     "start_url-member-pass-manual.html": [
+      "d0ca61017d557c1347162132c294cc319f4cfb24",
+      [
+       null,
+       {}
+      ]
+     ]
+    },
     "theme_color-member": {
      "theme_color-member-hsl-manual.html": [
       "0203a977669687d6635639ca681bdb6bf087d4fb",
@@ -65197,6 +65213,19 @@
         {}
        ]
       ],
+      "flex-and-intrinsic-sizes-002.html": [
+       "1f93d0e3d0e2b6bff13351e92c7ffaba7cb68553",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "grid-as-flex-item-should-not-shrink-to-fit-001.html": [
        "e0665d56a1a55ecd41a9ae384e822c8662740d39",
        [
@@ -76876,6 +76905,58 @@
        {}
       ]
      ],
+     "overflow-body-propagation-007.html": [
+      "9ce13ed8de359a9e3d79f27f4eced40d6115cb1a",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/overflow-body-propagation-007-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "overflow-body-propagation-008.html": [
+      "867cd379c73ebdb348ef0d30285946e43ef7051f",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/overflow-body-propagation-008-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "overflow-body-propagation-009.html": [
+      "6924719f97872021cefa31f920e7619ec2208747",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/overflow-body-propagation-009-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "overflow-body-propagation-010.html": [
+      "7a9966c151afff318959fef9f6c760d6bde078cd",
+      [
+       null,
+       [
+        [
+         "/css/css-overflow/overflow-body-propagation-010-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "overflow-ellipsis-dynamic-001.html": [
       "2a9edba9308bf06009d7b9a27f21f1e0f1a231c7",
       [
@@ -80306,12 +80387,12 @@
       ]
      ],
      "active-selection-018.html": [
-      "ee7871c9503d45a3e0a0fbcff7e368d4557e33c3",
+      "0c515bedf4d17fdc226bcaebf8f4e8f7bb10bd49",
       [
        null,
        [
         [
-         "/css/css-pseudo/reference/active-selection-011-ref.html",
+         "/css/css-pseudo/reference/active-selection-018-ref.html",
          "=="
         ]
        ],
@@ -80357,6 +80438,32 @@
        {}
       ]
      ],
+     "active-selection-041.html": [
+      "f437c8bb523c3a403b8ccddc0ac224e77ecd52c4",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/reference/active-selection-041-notref.html",
+         "!="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "active-selection-043.html": [
+      "f760dee536e2a832d5b26760006cedef12ed56c1",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-nothing-below.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "active-selection-045.html": [
       "415aa60610a85327362f3a4e592168ab9fccbbe3",
       [
@@ -156602,7 +156709,7 @@
       []
      ],
      "constructors-expected.txt": [
-      "bf840dabe0af5579a2cd27278d0371b83a5462fc",
+      "ebb7dde64bb751128721d31934acf23148a28cbf",
       []
      ],
      "default-iterator-object-expected.txt": [
@@ -157064,6 +157171,32 @@
       []
      ]
     },
+    "start_url-member": {
+     "fail.html": [
+      "4c6c599b5a78e5422aa64b5aed1753eb8b3259b5",
+      []
+     ],
+     "pass.html": [
+      "caecc70f6d1bd491b54ef3af2a2c098f54f15994",
+      []
+     ],
+     "start_url-member-fail.sub.webmanifest": [
+      "73ee4744a240a6f76e3e2c741538e13b443e5d41",
+      []
+     ],
+     "start_url-member-fail.webmanifest.headers": [
+      "23f36ea27ced7bba400a60e8e618757e5701cd88",
+      []
+     ],
+     "start_url-member.webmanifest": [
+      "8d2325880d8360d7fb1467a4fb0a8caacc71f90d",
+      []
+     ],
+     "start_url-member.webmanifest.headers": [
+      "23f36ea27ced7bba400a60e8e618757e5701cd88",
+      []
+     ]
+    },
     "theme_color-member": {
      "theme_color-member-hsl.webmanifest": [
       "23ae16c15a72aace322420bf8b931d5d24c7f3b9",
@@ -165942,7 +166075,7 @@
       []
      ],
      "event-dispatch.tentative-expected.txt": [
-      "0feefd2eedc72d4c5724d016e9ba3de6d51a4bb1",
+      "a4512f67d28b1cdd814fa152b6d8fef4fe153e82",
       []
      ],
      "event-order.tentative-expected.txt": [
@@ -177553,7 +177686,7 @@
        []
       ],
       "grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt": [
-       "0f92eef471cbf581117bba5ca7a42f0d7f573f6a",
+       "c9eac7bd66ee5edb9fe7216958ed607313d0c4e5",
        []
       ],
       "grid-limits-001-expected.txt": [
@@ -177573,7 +177706,7 @@
        []
       ],
       "grid-template-columns-rows-resolved-values-001.tentative-expected.txt": [
-       "0f92eef471cbf581117bba5ca7a42f0d7f573f6a",
+       "c9eac7bd66ee5edb9fe7216958ed607313d0c4e5",
        []
       ],
       "grid-template-rows-fit-content-001-ref.html": [
@@ -177582,7 +177715,7 @@
       ],
       "support": {
        "testing-utils.js": [
-        "bfedc32b710136cf73706809d62bf19305be720b",
+        "30b944265b463fb595f1cb50ae8527ff00291019",
         []
        ]
       }
@@ -177737,7 +177870,7 @@
        []
       ],
       "grid-flex-track-intrinsic-sizes-001-expected.txt": [
-       "f9802810a8f8b66342a94c254dfc8b75536922c4",
+       "549da5a597dba9fcf40ae65da6b77f28412653dd",
        []
       ],
       "grid-flex-track-intrinsic-sizes-003-expected.txt": [
@@ -180713,6 +180846,22 @@
       "59864d0f4d185ece259879a299f597b80f9babdc",
       []
      ],
+     "overflow-body-propagation-007-ref.html": [
+      "66f9b1c3b0098c0cc448775cde0d94b4325a94a8",
+      []
+     ],
+     "overflow-body-propagation-008-ref.html": [
+      "91e582aa00ff139338921eec47714dc58d3817cd",
+      []
+     ],
+     "overflow-body-propagation-009-ref.html": [
+      "9632674a5a8e40b98f320c078f14ef8dafa75839",
+      []
+     ],
+     "overflow-body-propagation-010-ref.html": [
+      "9e502e7e237de7ffb6dfc754450c70f5f03d297e",
+      []
+     ],
      "parsing": {
       "block-ellipsis-valid-expected.txt": [
        "85dc4ba27ef3afc7d791bc912c83bc1344001aa7",
@@ -181872,6 +182021,10 @@
        "cd80adb3c3be45234bb3e89f42086dd30432cdb9",
        []
       ],
+      "active-selection-018-ref.html": [
+       "9644602179b034f0a362218244289113b90781b6",
+       []
+      ],
       "active-selection-021-ref.html": [
        "7790a3fad8a36f1709fea6a4155ed5af0f3c49d7",
        []
@@ -181884,6 +182037,10 @@
        "0e3680844f887050520d8fb9b9bd2f68a2234e85",
        []
       ],
+      "active-selection-041-notref.html": [
+       "17d69f306d77411f2ef0a7dab682b119c5b59e50",
+       []
+      ],
       "selection-contenteditable-011-ref.html": [
        "0677a4b6b39f26aa4b3acc7480240b9d061e4929",
        []
@@ -181918,6 +182075,10 @@
        "57bf3ddc5213d06e0975de38f330ffb7c441b268",
        []
       ],
+      "60x60-red.png": [
+       "823f125b8e4a60f780f00443c9c9a10b9fa1f447",
+       []
+      ],
       "select-custom.cur": [
        "0a1f5dd51458223ce9213487ebcea627cdf75a4d",
        []
@@ -188400,7 +188561,7 @@
       ]
      },
      "event-dispatch.tentative-expected.txt": [
-      "cbabf0d170ec923a97a31645450e341982cb4352",
+      "180a68fa2af47c9699da1a3f7abc1ba9015072ba",
       []
      ],
      "idlharness-expected.txt": [
@@ -197662,6 +197823,22 @@
      "HTMLCollection-as-prototype-expected.txt": [
       "f36f3bf1426c59572dc577805db9d9a3503ffd29",
       []
+     ],
+     "HTMLCollection-delete-expected.txt": [
+      "4e83310253ec2afe853ba52b5dc12ea498f1fbcd",
+      []
+     ],
+     "HTMLCollection-own-props-expected.txt": [
+      "4d2dd7fc4d6f07aa855ea46158784cc4c4977170",
+      []
+     ],
+     "HTMLCollection-supported-property-indices-expected.txt": [
+      "be034fafcfe7066e657a1071d00d39fd7321d67c",
+      []
+     ],
+     "HTMLCollection-supported-property-names-expected.txt": [
+      "30d2dd44e943d0b8f796fc76dde01286ee3fbe89",
+      []
      ]
     },
     "common.js": [
@@ -197739,7 +197916,7 @@
      []
     ],
     "idlharness.window_exclude=Node-expected.txt": [
-     "58f17fc27836870051e6f09c1cacffb193f7f3d0",
+     "0aa1687706a2b60295c26653b16a6f059370c1cb",
      []
     ],
     "lists": {
@@ -200557,7 +200734,7 @@
        []
       ],
       "feature-policy-trust-token-redemption.html": [
-       "cf6c98307aadacc202d0fbc4b8895145f00aab40",
+       "6ae6f6fa4d4684af4b839658ed295d7cfec976cd",
        []
       ],
       "focus-without-user-activation-iframe-tentative.html": [
@@ -202830,6 +203007,18 @@
      "b1d9945efd773f06dbb5302591f2d83fd93f4a03",
      []
     ],
+    "feature-policy-gamepad.html": [
+     "8ee0c719216904c8d46319ab552d1d8f1ca247a5",
+     []
+    ],
+    "gamepad-default-feature-policy.https.sub-expected.txt": [
+     "5d94b3548a3663371ef097069e9f61a98ae44497",
+     []
+    ],
+    "gamepad-secure-context-expected.txt": [
+     "30e28ffa1172e2793ce26feeb3f79494a33203d9",
+     []
+    ],
     "idlharness-extensions.window-expected.txt": [
      "8f261de6141c5b9a74ede23340cb3bb90ffe4a61",
      []
@@ -203059,6 +203248,10 @@
         "6387bc89c8f39f43a49079a45be7e3d1910569a1",
         []
        ],
+       "api-availability-expected.txt": [
+        "8676e6ed8abab677631fa87c21b6ac770422d669",
+        []
+       ],
        "browsing_context_name-0.html": [
         "5cbab71a5eaac4fd789a470cca2538225589a497",
         []
@@ -203826,7 +204019,7 @@
         []
        ],
        "location-protocol-setter-non-broken-expected.txt": [
-        "4d1f8a9abd4d46f445ceb66ec1f65fe65425aabd",
+        "73507dc26a7a6935592a606ac49ce62bbaf4ff8c",
         []
        ],
        "location-protocol-setter-non-broken-weird-expected.txt": [
@@ -203849,6 +204042,18 @@
         "dfeea3d36e6e594b7d90a5c5eb6063943eb7f2a7",
         []
        ],
+       "location-prototype-setting-same-origin-expected.txt": [
+        "f1e424f8fcf3924342e1077d82a8986939687f9c",
+        []
+       ],
+       "location-stringifier-expected.txt": [
+        "59612a1b796be218c107943580d9c408601ff665",
+        []
+       ],
+       "location-valueof-expected.txt": [
+        "1086fb9fd54aca0cc6675f7cf9b4408ae8bb4da5",
+        []
+       ],
        "location_assign_about_blank-1.html": [
         "b43598f2cd8f47bcd23373075773ef245c95c21a",
         []
@@ -204347,6 +204552,10 @@
         "e08395a89affb9f921c9cae368f32c7c5444970b",
         []
        ],
+       "prototype-expected.txt": [
+        "312d0a1aa5fc22cd30618476df4a5538d1b4af50",
+        []
+       ],
        "test.html": [
         "c3b3cc185255d159b0f9ff9fd97aae71170d0af6",
         []
@@ -204388,8 +204597,16 @@
         []
        ]
       },
+      "window-indexed-properties-expected.txt": [
+       "f958b38c919a376fb363f746b023eeab44d4b4ff",
+       []
+      ],
+      "window-indexed-properties-strict-expected.txt": [
+       "24149dd095eaed7a4b925498c90bbf80cff7df65",
+       []
+      ],
       "window-properties.https-expected.txt": [
-       "90301e06ddd143e349dbe6e12ced7dc0dad8fde9",
+       "76418e85aa664da7e4e6a7f5219fb5dde1d3e46a",
        []
       ],
       "window-reuse-in-nested-browsing-contexts.tentative-expected.txt": [
@@ -204413,6 +204630,10 @@
      },
      "windows": {
       "auxiliary-browsing-contexts": {
+       "opener-setter.window-expected.txt": [
+        "8dfee380a4f83d006027c76b643ffa4bb8a11ddd",
+        []
+       ],
        "resources": {
         "close-opener.html": [
          "f41773ed2cd00945e844e6ec3abb3c0e49b00854",
@@ -204548,8 +204769,12 @@
        "5ae578d930f8a9e29d4f6396299d09efe167e728",
        []
       ],
+      "embedded-opener-expected.txt": [
+       "16481744cb91f79d4589e364e539ef8d4128bc90",
+       []
+      ],
       "embedded-opener-remove-frame-expected.txt": [
-       "36c9182acf3571c65b546a886539972edad4e5ac",
+       "1d304732ae89dc1d919737f00e0d29eaec6d5e91",
        []
       ],
       "nested-browsing-contexts": {
@@ -205891,6 +206116,10 @@
        ]
       },
       "the-offscreen-canvas": {
+       "2d.getcontext.extraargs-expected.txt": [
+        "7212cb86263531b14d5a476773e1b53681644610",
+        []
+       ],
        "size.attributes.idl-expected.txt": [
         "6046e3bd01e110f56729b99516515b109d8a426c",
         []
@@ -206011,7 +206240,7 @@
          []
         ],
         "fill-and-stroke-styles.yaml": [
-         "d05ae0911bd8f97c90e16ef2376235f67de3f553",
+         "50d28085f4c4985b5697a3df8ca45278351942ad",
          []
         ],
         "line-styles.yaml": [
@@ -206077,7 +206306,7 @@
          []
         ],
         "fill-and-stroke-styles.yaml": [
-         "2554d48d26844a56dbcb9847b15b3ea7bb51c5d5",
+         "7be040a13291c0d729fd562a57fc0a12b31b37c6",
          []
         ],
         "line-styles.yaml": [
@@ -206520,6 +206749,10 @@
        "property.https-expected.txt": [
         "ba655328c973a9fd51197c2b50f2616f3d038103",
         []
+       ],
+       "reporting-observer-expected.txt": [
+        "9dadb68281f098f2a90ab44949b27269ee8d7182",
+        []
        ]
       },
       "navigation-reporting": {
@@ -206570,11 +206803,15 @@
        "reporting-popup-unsafe-none-report-to.https.html.sub.headers": [
         "a0d12c549fac7d4e7b06d2741085b4ef712bae13",
         []
+       ],
+       "reporting-redirect-with-same-origin-allow-popups.https-expected.txt": [
+        "2097b2ecddc5816e219af01066903d8610a3c703",
+        []
        ]
       },
       "resources": {
        "dispatcher.js": [
-        "38243fab81a8c01e7c8880f905f22fb0c43893dc",
+        "13c01add30fcc14571537ae04912c6c4b11a61c7",
         []
        ],
        "dispatcher.py": [
@@ -206687,6 +206924,10 @@
         "a134f46ae4f026f047d3d2556bd665b1403d85f5",
         []
        ],
+       "dataset-binding.window-expected.txt": [
+        "0f3419e7fc36e3093a7e183bf3d14f8e08c830ff",
+        []
+       ],
        "dir_auto-EN-L-ref.html": [
         "de6e13b3a3221f6054e387eb76525673bc1201f9",
         []
@@ -207034,11 +207275,11 @@
       []
      ],
      "idlharness.https_exclude=(Document_Window_HTML._)-expected.txt": [
-      "7968f85556da5f0881b2ca3a60c1d32fd4522b1c",
+      "9f3049c1e0d0daa483bbb0e332d96478cedd6985",
       []
      ],
      "idlharness.https_include=(Document_Window)-expected.txt": [
-      "ecc0d9891941d601d6ef705c6759553b867c479d",
+      "2a60f996ab87e61e651effd9c958610bd7d1cf54",
       []
      ],
      "idlharness.https_include=HTML._-expected.txt": [
@@ -213541,8 +213782,12 @@
         "25900f613e24a8146e00cfe68f4fd11d481ca2a9",
         []
        ],
+       "form-indexed-element-expected.txt": [
+        "c25ec2fe6ce147656cfefe0633efd106936f39fc",
+        []
+       ],
        "form-nameditem-expected.txt": [
-        "90758955cb9790fb082a2de0097eee0315c48a95",
+        "86a0d6792487d76ddba8748af29f09ce4121beb4",
         []
        ],
        "resources": {
@@ -217747,7 +217992,7 @@
      []
     ],
     "webhid.idl": [
-     "aa699a31ba71135cfa3538a0742078d7d9db5770",
+     "9136e128cd53cc204f62ac1e9d2711d4bed1b201",
      []
     ],
     "webmidi.idl": [
@@ -219990,6 +220235,14 @@
      "6905a68e7901ce26bc1a363062304e1536604400",
      []
     ],
+    "idlharness.https.any-expected.txt": [
+     "fd08a2bb73c2a94f8c4c36393a195471450e84d4",
+     []
+    ],
+    "idlharness.https.any.worker-expected.txt": [
+     "0b3ae0d7ccbcfee19de1287167959f61a433af58",
+     []
+    ],
     "native_FileSystemWritableFileStream-write-manual.https-expected.txt": [
      "53bf72d0a209fb6a85c7ebc48adb92dfdd4bb1de",
      []
@@ -225249,6 +225502,10 @@
       "e6e6986dc00a2077b683c28c4b9d639ef0f2d949",
       []
      ],
+     "detached-context.https-expected.txt": [
+      "904eaa7c97d76506033b177eac0a76ac8a076e60",
+      []
+     ],
      "fetch-canvas-tainting-video-with-range-request.https-expected.txt": [
       "eb2733136fe9f8fbdb385fff6da47c50a73f9148",
       []
@@ -228822,19 +229079,19 @@
       []
      ],
      "cacert.key": [
-      "445aae1b9fb9760e390e7e4d0476a808c4e3f80b",
+      "c36ebcbc91054d4d61036004883f9bfbf7d4f5ac",
       []
      ],
      "cacert.pem": [
-      "eeba528d26d357320ba42f516f17e32447a83ad1",
+      "f450f014d9f09b7f7c4e60f23a2f7cb779ab8188",
       []
      ],
      "web-platform.test.key": [
-      "cfaccce423ededdb890d4a80683c747692e23fe0",
+      "0d422053f76ba4df1e69df513fe916532c4ccfad",
       []
      ],
      "web-platform.test.pem": [
-      "68a9b96f3ee9d9cda57daeb6796b5b674d75ac40",
+      "e7b1b018466895f32356c24ae1f3da0fff2f1c4c",
       []
      ]
     },
@@ -236933,7 +237190,7 @@
        []
       ],
       "animate-no-browsing-context-expected.txt": [
-       "91238a475503e550d5c625007db878116069158a",
+       "de9770be913bd9a3c3b8706887b573af02509501",
        []
       ]
      },
@@ -236943,7 +237200,7 @@
        []
       ],
       "style-change-events-expected.txt": [
-       "a618fd79eb71323d65202f9ecc6fca7c4614ff40",
+       "ae99c09d35c85b72a189ce367be2ad2f5acfd60a",
        []
       ]
      },
@@ -236957,7 +237214,7 @@
        []
       ],
       "style-change-events-expected.txt": [
-       "a3ce4529056ab9b227ebc34f2384deca356eaf93",
+       "ea372480457f4bb391aec9beb1e16992a7465aef",
        []
       ],
       "target-expected.txt": [
@@ -237015,7 +237272,7 @@
        []
       ],
       "setting-the-timeline-of-an-animation-expected.txt": [
-       "305bfa278215a6e0aafa5062ebac6cb03f6913ca",
+       "1b685b0566ee9e911c2ff10658344aa0d25c7ea4",
        []
       ],
       "sync-start-times-ref.html": [
@@ -237033,7 +237290,7 @@
      },
      "timelines": {
       "update-and-send-events-replacement-expected.txt": [
-       "888d29a1593108c0a5c71a94c562e1bf63429ea5",
+       "d583a4f0555923321aec16d04de0644ad2a472a1",
        []
       ]
      }
@@ -237274,7 +237531,7 @@
       []
      ],
      "helpers.js": [
-      "3819d12769898a3e2462ab06a35e5046d25f14f3",
+      "413c72051b8f8bd41022a8719b70dc2ad5c53a95",
       []
      ],
      "worklet-recorder.js": [
@@ -237518,6 +237775,12 @@
        "0bc5ce3b8dd6612b7af44007276819c9b1276e91",
        []
       ]
+     },
+     "the-periodicwave-interface": {
+      "periodicWave-expected.txt": [
+       "8d26f7ef4bb7d872adf059ec54ca05132487c261",
+       []
+      ]
      }
     }
    },
@@ -238393,7 +238656,7 @@
    },
    "webhid": {
     "idlharness.https.window-expected.txt": [
-     "c69b336391eca7ee54120c15d7884939f4fc4d62",
+     "dd981326d8c2c76391b89ed0bf5b5e62692e99fb",
      []
     ]
    },
@@ -238613,7 +238876,7 @@
      []
     ],
     "RTCPeerConnection-iceGatheringState-expected.txt": [
-     "b8da17006905b4af212310d30d2cabfd3113f8bf",
+     "db32c8e1339f96d1b5c5fe2bd26d88d0d6bc1ed2",
      []
     ],
     "RTCPeerConnection-mandatory-getStats.https-expected.txt": [
@@ -239457,7 +239720,7 @@
        []
       ],
       "region-expected.txt": [
-       "305af887cbb64413add0152ae0b7bb0d83120d97",
+       "bbc8739b6edda3d9cc3db75af10236876204d83f",
        []
       ]
      },
@@ -246480,7 +246743,7 @@
      ]
     ],
     "idbobjectstore_putall.tentative.any.js": [
-     "a312d71d03d59c5c9369afa1492aacd0e91e9a5d",
+     "8bdc765906d86504bcb344e1e579a97f8f602c6e",
      [
       "IndexedDB/idbobjectstore_putall.tentative.any.html",
       {
@@ -266913,6 +267176,13 @@
         {}
        ]
       ],
+      "float-in-self-painting-inline.html": [
+       "6ff47d362639ea31dc73547c5c24ea7a8b053015",
+       [
+        null,
+        {}
+       ]
+      ],
       "hit-test-floats-001.html": [
        "e554918e7538b0afedb60c80c74647967a114d47",
        [
@@ -271183,7 +271453,7 @@
        ]
       ],
       "flexbox_computedstyle_flex-basis-0percent.html": [
-       "abdd030da8a4336001c0f50cba9d28420b259c5a",
+       "6abbc50a22b3533b675ced0ca538e7d6f3233b6e",
        [
         null,
         {}
@@ -271414,7 +271684,7 @@
        ]
       ],
       "flexbox_computedstyle_flex-shorthand-number.html": [
-       "413a94f0236f79834153477701af3b7199aa9652",
+       "a35622277b890b6ee4041c15b01013bba1778413",
        [
         null,
         {}
@@ -271976,6 +272246,13 @@
        {}
       ]
      ],
+     "percentage-size-quirks-002.html": [
+      "c66ebd4428e963cd90ad93a204ce4840bf20b2fc",
+      [
+       null,
+       {}
+      ]
+     ],
      "percentage-size-quirks.html": [
       "1a5c5136bee8eeca54e65ae9bb509c121a98df62",
       [
@@ -272032,6 +272309,13 @@
        {}
       ]
      ],
+     "position-absolute-014.html": [
+      "f02a26800749fd067f38127c52a592df7cef9487",
+      [
+       null,
+       {}
+      ]
+     ],
      "position-relative-percentage-top-001.html": [
       "3ec47c1d42d69330c616a87f0b22208f8d6196a6",
       [
@@ -275704,6 +275988,13 @@
         {}
        ]
       ],
+      "grid-intrinsic-track-sizes-001.html": [
+       "15ca612c7cb5a639ba6da6931b2e55775e12d4dc",
+       [
+        null,
+        {}
+       ]
+      ],
       "grid-item-margin-auto-columns-rows-001.html": [
        "6ae1c50c220cdd07c5fb1fb266e2e2bd11bf2a4e",
        [
@@ -310736,7 +311027,7 @@
       ]
      ],
      "trust-token-redemption-default-feature-policy.tentative.https.sub.html": [
-      "c0485aa90d4c5237f04cc73f93eae36e2f89cad8",
+      "d88048953ea3f1d26dee502ef331bc3f07ec0152",
       [
        null,
        {}
@@ -315296,6 +315587,27 @@
     }
    },
    "gamepad": {
+    "gamepad-default-feature-policy.https.sub.html": [
+     "fce0eaffee308992f29d626438ef6002f0f69aef",
+     [
+      null,
+      {}
+     ]
+    ],
+    "gamepad-secure-context.html": [
+     "97b4ea2967eed3fbb5588ac0010b1dbf42ba19c8",
+     [
+      null,
+      {}
+     ]
+    ],
+    "gamepad-supported-by-feature-policy.html": [
+     "a688a380a7783277061a0b759e5b7e3501299170",
+     [
+      null,
+      {}
+     ]
+    ],
     "idlharness-extensions.window.js": [
      "dcf76878fc9257d4b7f2cbb6d603d9848c55f083",
      [
@@ -320733,6 +321045,13 @@
          {}
         ]
        ],
+       "2d.gradient.conic.html": [
+        "608b6a14db1bf4294aa455739e531a0ae3597aef",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.gradient.empty.html": [
         "c5fc908df31e33abd27c1c228367d7bd56fb7444",
         [
@@ -328500,6 +328819,20 @@
          {}
         ]
        ],
+       "2d.gradient.conic.html": [
+        "a1a4651ef65bb926279d5fbab4c1c991da935444",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.gradient.conic.worker.js": [
+        "53a61ad114ddbfcc176812aab2e9946b82624994",
+        [
+         "html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.worker.html",
+         {}
+        ]
+       ],
        "2d.gradient.empty.html": [
         "927c580f0e652aa674ff3b7fad92a0b5dac41819",
         [
@@ -336238,6 +336571,13 @@
           "timeout": "long"
          }
         ]
+       ],
+       "reporting-observer.html": [
+        "4d1eda941ae50ce4482c692dafe749ef9e455ac6",
+        [
+         null,
+         {}
+        ]
        ]
       },
       "navigation-reporting": {
@@ -336346,6 +336686,15 @@
           "timeout": "long"
          }
         ]
+       ],
+       "reporting-redirect-with-same-origin-allow-popups.https.html": [
+        "7dba76c4ef5434d49d7800da14eb980f79728f44",
+        [
+         null,
+         {
+          "timeout": "long"
+         }
+        ]
        ]
       }
      }
@@ -355106,6 +355455,20 @@
       {}
      ]
     ],
+    "inline-flow-shift-vertical-rl.html": [
+     "06bc34c37dd0559bfe6bedcc956ec2e2734c14b3",
+     [
+      null,
+      {}
+     ]
+    ],
+    "inline-flow-shift.html": [
+     "39550da6588eeb7aca7001ab592ee0177d26ca56",
+     [
+      null,
+      {}
+     ]
+    ],
     "local-shift-without-viewport-shift.html": [
      "37729f1c13c298b5a2d95c46b7a4f199d8943022",
      [
@@ -355127,6 +355490,13 @@
       {}
      ]
     ],
+    "outline.html": [
+     "1fed8e92f5e4b60cd83646405b6bd77e673c076f",
+     [
+      null,
+      {}
+     ]
+    ],
     "partially-clipped-visual-rect.html": [
      "3b18b98dd93312c37b9e2f25918df50266a09243",
      [
@@ -362517,7 +362887,7 @@
      ]
     },
     "about-blank.https.sub.html": [
-     "50a07ff0c02e45b4fb5cf5018d1b811f7944211d",
+     "6af31dd021f902f5005becf7b39332d0139da887",
      [
       null,
       {}
@@ -390839,14 +391209,14 @@
      ]
     },
     "trust-token-parameter-validation-xhr.tentative.https.html": [
-     "4a6c30c6d32424c9b1d3dce883d3f44862c6e3b6",
+     "0ee538c07e63a744ca8764c6fc67fc5fcbcd2696",
      [
       null,
       {}
      ]
     ],
     "trust-token-parameter-validation.tentative.https.html": [
-     "c3a612724ee8a0216f64b7a66434736df9def9a4",
+     "733873e538ccafc15ade66e2139828dc5a3da05d",
      [
       null,
       {}
@@ -393964,6 +394334,17 @@
       {}
      ]
     ],
+    "case-sensitivity.any.js": [
+     "1c0b0dcac361fe02eefc1dd5035955d10dc37151",
+     [
+      "user-timing/case-sensitivity.any.html",
+      {}
+     ],
+     [
+      "user-timing/case-sensitivity.any.worker.html",
+      {}
+     ]
+    ],
     "clearMarks.html": [
      "92c60a3bbb856bd05bf13f12bde09dac7eefb6e6",
      [
@@ -397922,7 +398303,7 @@
       ]
      ],
      "subresource-loading-from-web-bundle.tentative.html": [
-      "e35264698dbf7f42feb1012195a791adcbdb5b16",
+      "27e164afe8be36dfbbaed11f7d7faaf88431d131",
       [
        null,
        {}
@@ -399315,7 +399696,7 @@
        ]
       ],
       "test-analyser-minimum.html": [
-       "3b9e57314d6500ca8c33455d6fe3f949a59216ce",
+       "ab0fe6b2d6094f38d04a016f90b6873a5827da06",
        [
         null,
         {
@@ -399542,7 +399923,7 @@
        ]
       ],
       "audiocontextoptions.html": [
-       "b556e31b5e0dcea8b0c82d859e53d980b4936a2e",
+       "0bf2cfbb7ab2f0e332c72d7859b678833d983938",
        [
         null,
         {}
@@ -400751,6 +401132,15 @@
        ]
       ]
      },
+     "the-periodicwave-interface": {
+      "periodicWave.html": [
+       "bd42453001498c990bea27424eb4164d3196aee0",
+       [
+        null,
+        {}
+       ]
+      ]
+     },
      "the-scriptprocessornode-interface": {
       "simple-input-output.html": [
        "7fd20e67a7079ab3c02d490e458cb762006e0ca0",
@@ -411085,7 +411475,7 @@
         ]
        ],
        "not-handled.html": [
-        "96fdb4a6f119ad63a9f29a1592c846454293794c",
+        "11d03d728b158f2cf46af96f8cc1b2cfa137f5ab",
         [
          null,
          {}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/fail.html b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/fail.html
new file mode 100644
index 0000000..4c6c599
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/fail.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<meta charset="utf-8">
+<body style="background-color: red">
+<h1>FAIL</h1>
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/pass.html b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/pass.html
new file mode 100644
index 0000000..caecc70
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/pass.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>PASS</title>
+<meta charset="utf-8">
+<body style="background-color: green">
+<h1>PASS</h1>
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub.html b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub.html
new file mode 100644
index 0000000..b0743e7d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Test that start_url member is supported</title>
+<link rel="help" href="https://w3c.github.io/manifest/#start_url-member" />
+<link rel="manifest" href="https://{{host}}:{{ports[https][0]}}/appmanifest/start_url-member/start_url-member-fail.sub.webmanifest" />
+<h1>Cross-origin start URLs are invalid</h1>
+<script>
+  // Force the port of the origin to be ports[https][0] (likely :8443)
+  // we treat the start_url's port ports[https][1] (likely :8444) to be another origin that we fail against
+  if (window.location.origin !== "https://{{host}}:{{ports[https][0]}}") {
+    window.location = new URL(window.location.pathname, "https://{{host}}:{{ports[https][0]}}")
+  }
+</script>
+
+<style>
+@media all and (display-mode: fullscreen) {
+  body {
+    background-color: green;
+  }
+}
+</style>
+
+<p>
+  To pass, the start URL must not be fail.html because it's not same origin.
+  It will use this page as the start URL and the background will be green.
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.sub.webmanifest
new file mode 100644
index 0000000..73ee474
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.sub.webmanifest
@@ -0,0 +1,4 @@
+{
+    "start_url": "https://{{host}}:{{ports[https][1]}}/appmanifest/start_url-member/fail.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.webmanifest.headers
new file mode 100644
index 0000000..23f36ea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-fail.webmanifest.headers
@@ -0,0 +1 @@
+Content-Type: application/manifest+json; charset=utf-8
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual.html b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual.html
new file mode 100644
index 0000000..d0ca610
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>Test that start_url member is supported</title>
+<link rel="help" href="https://w3c.github.io/manifest/#start_url-member" />
+<link rel="manifest" href="start_url-member.webmanifest" />
+<h1>Testing support for start_url member</h1>
+<p>
+  To pass, the application name must be "pass".
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest
new file mode 100644
index 0000000..8d23258
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest
@@ -0,0 +1,3 @@
+{
+    "start_url": "pass.html"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest.headers
new file mode 100644
index 0000000..23f36ea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/start_url-member/start_url-member.webmanifest.headers
@@ -0,0 +1 @@
+Content-Type: application/manifest+json; charset=utf-8
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub-expected.txt
new file mode 100644
index 0000000..329b19a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Document shouldn't be sandboxed by <meta>
+FAIL Worker shouldn't be sandboxed by inheriting <meta> assert_equals: expected "http://web-platform.test:8001" but got "null"
+FAIL Worker shouldn't be sandboxed when created <iframe> inheriting parent's CSP with sandbox <meta> assert_equals: expected "http://web-platform.test:8001" but got "null"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub.html
new file mode 100644
index 0000000..cd8da8f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/meta-element.sub.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta content="sandbox allow-scripts" http-equiv="Content-Security-Policy">
+<body>
+<iframe id="iframe"></iframe>
+<script>
+// According to
+// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-security-policy
+// `sandbox` directives must be ignored when delivered via `<meta>`.
+test(() => {
+  assert_equals(location.origin, "{{location[scheme]}}://{{location[host]}}");
+}, "Document shouldn't be sandboxed by <meta>");
+
+// Note: sandbox directive for workers are not yet specified.
+// https://github.com/w3c/webappsec-csp/issues/279
+// Anyway workers shouldn't be affected by sandbox directives in `<meta>`.
+async_test(t => {
+  const worker = new Worker("support/post-origin-on-load-worker.js");
+  worker.onerror = t.unreached_func("Worker construction failed");
+  worker.onmessage = t.step_func_done(e => {
+    assert_equals(e.data, "{{location[scheme]}}://{{location[host]}}");
+  });
+}, "Worker shouldn't be sandboxed by inheriting <meta>");
+
+parent.async_test(t => {
+  // Although <iframe about:blank> should inherit parent's CSP,
+  // sandbox directives in <meta> should be ignored in the first place,
+  // so workers created from such <iframe>s shouldn't also be sandboxed.
+  const iframeDocument = document.querySelector("#iframe").contentDocument;
+  const script = iframeDocument.createElement("script");
+  script.innerText = `
+    const worker = new Worker("support/post-origin-on-load-worker.js");
+    worker.onerror = () => parent.postMessage("onerror", "*");
+    worker.onmessage = (e) => parent.postMessage(e.data, "*");
+  `;
+  iframeDocument.body.appendChild(script);
+
+  // Receive message from <iframe>.
+  onmessage = t.step_func_done(e => {
+    assert_equals(e.data, "{{location[scheme]}}://{{location[host]}}");
+  });
+}, "Worker shouldn't be sandboxed when created <iframe> inheriting parent's CSP with sandbox <meta>");
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/support/post-origin-on-load-worker.js b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/support/post-origin-on-load-worker.js
new file mode 100644
index 0000000..21ce574
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/sandbox/support/post-origin-on-load-worker.js
@@ -0,0 +1 @@
+postMessage(self.origin);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt
index 0f92eef4..c9eac7b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt
@@ -1,80 +1,80 @@
 This is a testharness.js-based test.
 Found 76 tests; 40 PASS, 36 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px;
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
+FAIL 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
-PASS undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
-PASS undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px;
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt
index 0f92eef4..c9eac7b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt
@@ -1,80 +1,80 @@
 This is a testharness.js-based test.
 Found 76 tests; 40 PASS, 36 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px;
-FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+FAIL 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
 PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px;
-FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
+FAIL 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
 PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
+FAIL 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
-PASS undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
 PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+FAIL 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px;
-FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+FAIL 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
 PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+FAIL 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
-PASS undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
 PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px;
-FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+FAIL 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
 PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px;
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/support/testing-utils.js b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/support/testing-utils.js
index bfedc32b..30b9442 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/support/testing-utils.js
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-definition/support/testing-utils.js
@@ -19,7 +19,7 @@
             grid.style.gridTemplateRows = rowsStyle;
             checkGridTemplateColumns(grid, columnsComputedValue);
             checkGridTemplateRows(grid, rowsComputedValue);
-        }, (label + " " || "") + "'" + gridId + "' with: grid-template-columns: " + columnsStyle  + "; and grid-template-rows: " + rowsStyle + ";");
+        }, (label ? label + " " : "") + "'" + gridId + "' with: grid-template-columns: " + columnsStyle  + "; and grid-template-rows: " + rowsStyle + ";");
     }
 
     function checkGridTemplateAreas(element, value) {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html
new file mode 100644
index 0000000..1f93d0e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/flex-and-intrinsic-sizes-002.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Auto Min Size is Zeroed When Spanning Flexible Tracks</title>
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact/">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#min-size-auto">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="An item spanning >1 track, at least one of which is flexible, must have a zero automatic minimum size (and thus, not grow to accommodate its children)."
+
+<style>
+.grid { display: grid; grid-template-columns: repeat(12, 1fr); height: 100px; width: 100px; }
+.test { grid-column: 1 / span 8; grid-row: 1; background: red; }
+.over { grid-column: 1 / span 8; grid-row: 1; background: green; }
+.under { grid-column: 9 / span 4; grid-row: 1; background: green; }
+.big-child { width: 500px; height: 100px; }
+</style>
+
+
+<div class="grid">
+  <div class="under"></div>
+  <div class="test">
+    <div class=big-child></div>
+  </div>
+  <div class="over"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt
index f9802810..549da5a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt
@@ -1,33 +1,33 @@
 This is a testharness.js-based test.
-PASS undefined 'grid' with: grid-template-columns: 0fr; and grid-template-rows: 0fr;
-PASS undefined 'grid' with: grid-template-columns: 1fr; and grid-template-rows: 1fr;
-PASS undefined 'grid' with: grid-template-columns: 2fr; and grid-template-rows: 2fr;
-PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(0, .5fr); and grid-template-rows: minmax(0, .5fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
-FAIL undefined 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
-FAIL undefined 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["50px 50px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "12.5px 37.5px" not in array ["25px 75px"]
-FAIL undefined 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 50px" not in array ["50px 50px 0px"]
-PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
-PASS undefined 'grid' with: grid-template-columns: minmax(30px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(30px, 1fr) minmax(0, 1fr);
-FAIL undefined 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["75px 25px"]
-FAIL undefined 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
-FAIL undefined 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
-FAIL undefined 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["0px 100px"]
-FAIL undefined 'grid' with: grid-template-columns: minmax(25px, 0fr) auto; and grid-template-rows: minmax(25px, 0fr) auto; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["25px 75px"]
-FAIL undefined 'grid' with: grid-template-columns: minmax(25px, 1fr) auto; and grid-template-rows: minmax(25px, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["25px 75px"]
+PASS 'grid' with: grid-template-columns: 0fr; and grid-template-rows: 0fr;
+PASS 'grid' with: grid-template-columns: 1fr; and grid-template-rows: 1fr;
+PASS 'grid' with: grid-template-columns: 2fr; and grid-template-rows: 2fr;
+PASS 'grid' with: grid-template-columns: minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr);
+PASS 'grid' with: grid-template-columns: minmax(0, .5fr); and grid-template-rows: minmax(0, .5fr);
+PASS 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
+PASS 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
+FAIL 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
+FAIL 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
+FAIL 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["50px 50px"]
+FAIL 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "12.5px 37.5px" not in array ["25px 75px"]
+FAIL 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 50px" not in array ["50px 50px 0px"]
+PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
+PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: minmax(30px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(30px, 1fr) minmax(0, 1fr);
+FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["75px 25px"]
+FAIL 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
+FAIL 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["0px 100px"]
+FAIL 'grid' with: grid-template-columns: minmax(25px, 0fr) auto; and grid-template-rows: minmax(25px, 0fr) auto; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["25px 75px"]
+FAIL 'grid' with: grid-template-columns: minmax(25px, 1fr) auto; and grid-template-rows: minmax(25px, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["25px 75px"]
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001.html
new file mode 100644
index 0000000..15ca612c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Intrinsic contribution of a small item to intrinsic tracks</title>
+<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact">
+<link rel="help" href="https://www.w3.org/TR/css-grid-1/#algo-content">
+<meta name="assert" content="This test checks that the intrinsic contribution of a single grid item smaller than its container is distributed correctly among the tracks it spans when intrinsic tracks are involved.">
+<base href="https://wpt.live/css/css-grid/grid-definition/">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+#grid {
+  display: grid;
+  width: 120px;
+  height: 120px;
+  border: solid;
+  font: 10px/1 Ahem;
+}
+#item {
+  background: blue;
+  /* make min-content contribution differ from minimum contribution */
+  min-width: 12px;
+  min-height: 12px;
+}
+</style>
+
+<div id="grid">
+  <div id="item">XXX XX<br>XX<br>XX</div>
+</div>
+
+<div id="log"></div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../grid-definition/support/testing-utils.js"></script>
+<script>
+const item = document.getElementById("item");
+function checkTrackSizes(span, trackList, expectedCols, expectedRows) {
+  item.style.gridColumn = item.style.gridRow = `span ${span}`;
+  if (!expectedRows) {
+    expectedRows = expectedCols;
+  }
+  TestingUtils.testGridTemplateColumnsRows("grid", trackList, trackList, expectedCols, expectedRows);
+}
+
+// Item spanning a single track
+checkTrackSizes(1, "auto", "120px");
+checkTrackSizes(1, "min-content", "30px", "40px");
+checkTrackSizes(1, "max-content", "60px", "30px");
+
+checkTrackSizes(1, "minmax(0, auto)", "120px");
+checkTrackSizes(1, "minmax(0, min-content)", "30px", "40px");
+checkTrackSizes(1, "minmax(0, max-content)", "60px", "30px");
+
+checkTrackSizes(1, "minmax(auto, 10px)", "12px");
+checkTrackSizes(1, "minmax(min-content, 10px)", "30px", "40px");
+checkTrackSizes(1, "minmax(max-content, 10px)", "60px", "30px");
+
+// Item spanning two identical tracks
+
+checkTrackSizes(2, "auto auto", "60px 60px");
+checkTrackSizes(2, "min-content min-content", "15px 15px", "20px 20px");
+checkTrackSizes(2, "max-content max-content", "30px 30px", "15px 15px");
+
+checkTrackSizes(2, "minmax(0, auto) minmax(0, auto)", "60px 60px");
+checkTrackSizes(2, "minmax(0, min-content) minmax(0, min-content)", "15px 15px", "20px 20px");
+checkTrackSizes(2, "minmax(0, max-content) minmax(0, max-content)", "30px 30px", "15px 15px");
+
+checkTrackSizes(2, "minmax(auto, 4px) minmax(auto, 4px)", "6px 6px");
+checkTrackSizes(2, "minmax(auto, 10px) minmax(auto, 10px)", "10px 10px");
+checkTrackSizes(2, "minmax(min-content, 10px) minmax(min-content, 10px)", "15px 15px", "20px 20px");
+checkTrackSizes(2, "minmax(max-content, 10px) minmax(max-content, 10px)", "30px 30px", "15px 15px");
+
+// Item spanning a fixed track also
+checkTrackSizes(2, "20px auto", "20px 100px");
+checkTrackSizes(2, "20px min-content", "20px 10px", "20px 20px");
+checkTrackSizes(2, "20px max-content", "20px 40px", "20px 10px");
+
+checkTrackSizes(2, "20px minmax(0, auto)", "20px 100px");
+checkTrackSizes(2, "20px minmax(0, min-content)", "20px 10px", "20px 20px");
+checkTrackSizes(2, "20px minmax(0, max-content)", "20px 40px", "20px 10px");
+
+checkTrackSizes(2, "20px minmax(auto, 30px)", "20px 30px");
+checkTrackSizes(2, "20px minmax(min-content, 6px)", "20px 10px", "20px 20px");
+checkTrackSizes(2, "20px minmax(min-content, 40px)", "20px 40px", "20px 40px");
+checkTrackSizes(2, "20px minmax(max-content, 6px)", "20px 40px", "20px 10px");
+checkTrackSizes(2, "20px minmax(max-content, 30px)", "20px 40px", "20px 30px");
+
+// Item spanning two mismatched intrinsic tracks
+checkTrackSizes(2, "max-content min-content", "45px 15px", "15px 15px");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007-ref.html
new file mode 100644
index 0000000..66f9b1c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007-ref.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Reference: overflow-x:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<style>
+  html { overflow: hidden auto; }
+  body {
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+    border-right-width: 20px;
+    border-right-style: solid;
+    border-right-color: red;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007.html
new file mode 100644
index 0000000..9ce13ed
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-007.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Test: overflow-x:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
+<link rel="match" href="overflow-body-propagation-007-ref.html">
+<style>
+  body {
+    overflow-x: -moz-hidden-unscrollable; /* will be removed in bug 1531609 */
+    overflow-x: clip;
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+    border-right-width: 20px;
+    border-right-style: solid;
+    border-right-color: red;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008-ref.html
new file mode 100644
index 0000000..91e582aa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008-ref.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Reference: overflow-y:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<style>
+  html { overflow: auto hidden; }
+  body {
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008.html
new file mode 100644
index 0000000..867cd379
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-008.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Test: overflow-y:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
+<link rel="match" href="overflow-body-propagation-008-ref.html">
+<style>
+  body {
+    overflow-y: -moz-hidden-unscrollable; /* will be removed in bug 1531609 */
+    overflow-y: clip;
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+    border-right-width: 20px;
+    border-right-style: solid;
+    border-right-color: red;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009-ref.html
new file mode 100644
index 0000000..9632674
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009-ref.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Reference: overflow:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<style>
+  html { overflow: hidden; }
+  body {
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009.html
new file mode 100644
index 0000000..6924719
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-009.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Test: overflow:clip propagated from BODY</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
+<link rel="match" href="overflow-body-propagation-009-ref.html">
+<style>
+  body {
+    overflow: -moz-hidden-unscrollable; /* will be removed in bug 1531609 */
+    overflow: clip;
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+    border-right-width: 20px;
+    border-right-style: solid;
+    border-right-color: red;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010-ref.html
new file mode 100644
index 0000000..9e502e7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010-ref.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Reference: contain:paint on BODY with overflow:clip</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<style>
+  body {
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    width: 50px;
+    height: 50px;
+    background: blue;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010.html
new file mode 100644
index 0000000..7a9966c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/overflow-body-propagation-010.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html><head>
+<meta charset="utf-8">
+<title>CSS Test: contain:paint on BODY with overflow:clip</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1635473">
+<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
+<link rel="match" href="overflow-body-propagation-010-ref.html">
+<style>
+  body {
+    overflow: -moz-hidden-unscrollable; /* will be removed in bug 1531609 */
+    overflow: clip;
+    contain: paint;
+    width: 30px;
+    height: 30px;
+    padding: 10px;
+    margin-left: 100px;
+    margin-top: 100px;
+  }
+
+  div {
+    position: relative;
+    top: -20px;
+    left: -40px;
+    background: blue;
+    height: 10000px;
+    width: 10000px;
+    border-right-width: 20px;
+    border-right-style: solid;
+    border-right-color: red;
+  }
+</style></head>
+<body><div></div></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-018.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-018.html
index ee7871c9..0c515be 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-018.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-018.html
@@ -7,7 +7,7 @@
   <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
   <link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-selectors">
   <link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-styling">
-  <link rel="match" href="reference/active-selection-011-ref.html">
+  <link rel="match" href="reference/active-selection-018-ref.html">
 
   <meta content="" name="flags">
 
@@ -55,6 +55,6 @@
 
   <body onload="startTest();">
 
-  <p>Test passes if each glyph of "Selected Text" is green and if there is <strong>no red</strong>.
+  <p>Test passes if each glyph of "Selected Text" is green, if background color of each glyph of "Selected Text" is white and if there is <strong>no red</strong>.
 
   <div id="parent">Selected Text <span>FAIL</span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-041.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-041.html
new file mode 100644
index 0000000..f437c8b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-041.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+
+<html class="reftest-wait">
+
+  <meta charset="UTF-8">
+
+  <title>CSS Pseudo-Elements Test: active selection and image</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-painting">
+  <link rel="mismatch" href="reference/active-selection-041-notref.html">
+
+  <meta content="should" name="flags">
+  <meta name="assert" content="In this test, a filled yellow image is selected and is overlaid with an opaque blue background color. The specification states that, for replaced content, the UA should create a semi-transparent wash to coat the content. But such semi-transparent wash could use a transparency of 0.3 or 0.5 or 0.7: so, we do not know. Therefore we can not predict the rendered end result. All we can be sure of is that the image, once selected, must not be identical to its original non-selected version. This test checks precisely and only this.">
+
+  <!--
+  "
+  (...) for replaced content, the UA should create
+  a semi-transparent wash to coat the content so
+  that it can show through the selection.
+  "
+  coming from
+  https://www.w3.org/TR/css-pseudo-4/#highlight-painting
+  -->
+
+  <!--
+  July 28th 2020
+
+  Firefox 68.10.0 ESR will create a resulting
+  background color of #7F7F80, which looks like
+  dark gray.
+
+  Chrome 83.0.4103.116 will create a resulting
+  background color of #33CCCC which looks like
+  dark blue.
+
+  July 28th 2020
+  -->
+
+  <style>
+  div
+    {
+      font-size: 300%;
+    }
+
+  img
+    {
+      vertical-align: top;
+    }
+
+  /*
+  Chromium 80+ will highlight space
+  below and above content box while
+  Firefox 72+ only highlights the image itself.
+  Therefore this 'vertical-align: top' declaration
+  to work around this possible behavior.
+  */
+
+  img::selection
+    {
+      background-color: blue;
+      /*
+      equivalent to rgb(0, 0, 255) or rgb(0%, 0%, 100%)
+      or rgba(0, 0, 255, 1) or #0000FF
+      */
+    }
+  </style>
+
+  <script>
+  function startTest()
+  {
+  var targetRange = document.createRange();
+  /* We first create an empty range */
+  targetRange.selectNodeContents(document.getElementById("test"));
+  /* Then we set the range boundaries to the children of div#test */
+  window.getSelection().addRange(targetRange);
+  /* Finally, we now select such range of content */
+  document.documentElement.className = "";
+  }
+  </script>
+
+  <body onload="startTest();">
+
+  <p>Test passes if there is a filled square which is <strong>not yellow</strong>.
+
+  <div id="test"><img src="../support/swatch-yellow.png" width="100" height="100" alt="Image download support must be enabled"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-043.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-043.html
new file mode 100644
index 0000000..f760dee
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/active-selection-043.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+
+<html class="reftest-wait">
+
+  <meta charset="UTF-8">
+
+  <title>CSS Pseudo-Elements Test: active selection and image (complex)</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+  <link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-bounds">
+  <link rel="match" href="../reference/ref-nothing-below.xht">
+
+  <meta content="" name="flags">
+  <meta name="assert" content="In this test, a filled red image has a padding belt painted red and a red border. This test checks that the associated overlay for an image must not leak outside the image's border box.">
+
+  <!--
+
+  "
+   For replaced content, the associated overlay must cover
+   at least the entire replaced object, and may extend
+   outward to include the element's entire content box.
+   The overlay may also include other other areas within
+   the border-box of an element (...)
+  "
+  coming from
+  https://www.w3.org/TR/css-pseudo-4/#highlight-bounds
+
+  -->
+
+  <style>
+  div
+    {
+      font-size: 300%;
+    }
+
+  img
+    {
+      background-color: red;
+      /* so that the padding belt is painted red */
+      border: red solid 10px;
+      padding: 10px;
+    }
+
+  /*
+  Chromium 80+ highlights the descender space
+  below the baseline on which the image "sits" while
+  Firefox 72+ only highlights the image itself.
+  */
+
+  img::selection
+    {
+      background-color: red;
+      color: red;
+    }
+
+  span#masking
+    {
+      background-color: white;
+      display: inline-block;
+      height: 100px;
+      position: relative;
+      right: 100px;
+      width: 100px;
+    }
+  </style>
+
+  <script>
+  function startTest()
+  {
+  var targetRange = document.createRange();
+  /* We first create an empty range */
+  targetRange.selectNodeContents(document.getElementById("test"));
+  /* Then we set the range boundaries to the children of div#test */
+  window.getSelection().addRange(targetRange);
+  /* Finally, we now select such range of content */
+  document.documentElement.className = "";
+  }
+  </script>
+
+  <body onload="startTest();">
+
+  <p>Test passes if there is nothing below.
+
+  <div id="test"><img src="support/60x60-red.png" alt="Image download support must be enabled"><span id="masking"></span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-018-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-018-ref.html
new file mode 100644
index 0000000..9644602
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-018-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest Reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      color: green;
+      font-size: 300%;
+    }
+  </style>
+
+   <p>Test passes if each glyph of "Selected Text" is green, if background color of each glyph of "Selected Text" is white and if there is <strong>no red</strong>.
+
+  <div>Selected Text</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-041-notref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-041-notref.html
new file mode 100644
index 0000000..17d69f3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/reference/active-selection-041-notref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest Reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <p>Test passes if there is a filled square which is <strong>not yellow</strong>.
+
+  <div><img src="../../support/swatch-yellow.png" width="100" height="100" alt="Image download support must be enabled"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/support/60x60-red.png b/third_party/blink/web_tests/external/wpt/css/css-pseudo/support/60x60-red.png
new file mode 100644
index 0000000..823f125
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/support/60x60-red.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
index 7dba76c..bb76df811 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html
@@ -8,7 +8,6 @@
 <script src=/common/get-host-info.sub.js></script>
 <script src="/common/utils.js"></script>
 <script src="../resources/dispatcher.js"></script>
-<script src="../resources/try-access.js"></script>
 <script>
 
 const directory = "/html/cross-origin-opener-policy/reporting";
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl b/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
index aa699a31..9136e12 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webhid.idl
@@ -14,7 +14,10 @@
     required sequence<HIDDeviceFilter> filters;
 };
 
-[SecureContext]
+[
+    Exposed=Window,
+    SecureContext
+]
 interface HID : EventTarget {
     attribute EventHandler onconnect;
     attribute EventHandler ondisconnect;
@@ -32,9 +35,10 @@
 };
 
 [
-    Constructor(DOMString type, HIDConnectionEventInit eventInitDict),
+    Exposed=Window,
     SecureContext
 ] interface HIDConnectionEvent : Event {
+    constructor(DOMString type, HIDConnectionEventInit eventInitDict);
     [SameObject] readonly attribute HIDDevice device;
 };
 
@@ -45,9 +49,10 @@
 };
 
 [
-    Constructor(DOMString type, HIDInputReportEventInit eventInitDict),
+    Exposed=Window,
     SecureContext
 ] interface HIDInputReportEvent : Event {
+    constructor(DOMString type, HIDInputReportEventInit eventInitDict);
     [SameObject] readonly attribute HIDDevice device;
     readonly attribute octet reportId;
     readonly attribute DataView data;
@@ -58,7 +63,10 @@
     "english-rotation", "vendor-defined", "reserved"
 };
 
-[SecureContext] interface HIDReportItem {
+[
+    Exposed=Window,
+    SecureContext
+] interface HIDReportItem {
     readonly attribute boolean isAbsolute;
     readonly attribute boolean isArray;
     readonly attribute boolean isRange;
@@ -66,38 +74,55 @@
     readonly attribute FrozenArray<unsigned long> usages;
     readonly attribute unsigned long usageMinimum;
     readonly attribute unsigned long usageMaximum;
+    readonly attribute unsigned long designatorMinimum;
+    readonly attribute unsigned long designatorMaximum;
+    readonly attribute unsigned long stringMinimum;
+    readonly attribute unsigned long stringMaximum;
     readonly attribute unsigned short reportSize;
     readonly attribute unsigned short reportCount;
-    readonly attribute unsigned long unitExponent;
-    readonly attribute HIDUnitSystem unitSystem;
-    readonly attribute byte unitFactorLengthExponent;
-    readonly attribute byte unitFactorMassExponent;
-    readonly attribute byte unitFactorTimeExponent;
-    readonly attribute byte unitFactorTemperatureExponent;
-    readonly attribute byte unitFactorCurrentExponent;
-    readonly attribute byte unitFactorLuminousIntensityExponent;
+    readonly attribute byte unitExponent;
+    readonly attribute unsigned long unit;
     readonly attribute long logicalMinimum;
     readonly attribute long logicalMaximum;
     readonly attribute long physicalMinimum;
     readonly attribute long physicalMaximum;
-    readonly attribute FrozenArray<DOMString> strings;
 };
 
-[SecureContext] interface HIDReportInfo {
+[
+    Exposed=Window,
+    SecureContext
+] interface HIDReportInfo {
     readonly attribute octet reportId;
     readonly attribute FrozenArray<HIDReportItem> items;
 };
 
-[SecureContext] interface HIDCollectionInfo {
+dictionary HIDFieldOptions {
+    required octet reportId;
+    required unsigned long fieldIndex;
+    boolean isFeatureReport;
+};
+
+[
+    Exposed=Window,
+    SecureContext
+] interface HIDCollectionInfo {
     readonly attribute unsigned short usagePage;
     readonly attribute unsigned short usage;
     readonly attribute FrozenArray<HIDCollectionInfo> children;
     readonly attribute FrozenArray<HIDReportInfo> inputReports;
     readonly attribute FrozenArray<HIDReportInfo> outputReports;
     readonly attribute FrozenArray<HIDReportInfo> featureReports;
+    readonly attribute FrozenArray<octet> reportIds;
+
+    double getField(BufferSource reportData, HIDFieldOptions options);
+    void setField(BufferSource reportData, HIDFieldOptions options,
+                  double value);
 };
 
-[SecureContext] interface HIDDevice : EventTarget {
+[
+    Exposed=Window,
+    SecureContext
+] interface HIDDevice : EventTarget {
     attribute EventHandler oninputreport;
     readonly attribute boolean opened;
     readonly attribute unsigned short vendorId;
@@ -106,7 +131,7 @@
     readonly attribute FrozenArray<HIDCollectionInfo> collections;
     Promise<void> open();
     Promise<void> close();
-    Promise<void> sendReport(octet reportId, BufferSource data);
-    Promise<void> sendFeatureReport(octet reportId, BufferSource data);
-    Promise<DataView> receiveFeatureReport(octet reportId);
+    Promise<void> sendReport([EnforceRange] octet reportId, BufferSource data);
+    Promise<void> sendFeatureReport([EnforceRange] octet reportId, BufferSource data);
+    Promise<DataView> receiveFeatureReport([EnforceRange] octet reportId);
 };
diff --git a/third_party/blink/web_tests/external/wpt/tools/certs/cacert.key b/third_party/blink/web_tests/external/wpt/tools/certs/cacert.key
index 445aae1..c36ebcb 100644
--- a/third_party/blink/web_tests/external/wpt/tools/certs/cacert.key
+++ b/third_party/blink/web_tests/external/wpt/tools/certs/cacert.key
@@ -1,30 +1,30 @@
------BEGIN ENCRYPTED PRIVATE KEY-----

-MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIAwsuZ7yJxLsCAggA

-MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECCKRswLXsh9PBIIEyKOt42mLeL6h

-uPBh63doHoqJxB95pwptR63fqp2RfvZUUzfrWnI2dnn0xRtRcPmf52BR4sliIJJz

-K+h10VO4ailG4mMeP+2VPHFuflQn5xgSC5Vd7jedV0VeycMr0gfZ1XbcMuVIrrW2

-wQVM/Dbb3A6NHT5yUA+ZTyam3SYh0VrBLp8FQn/22xivmjC5jqZbFqvUl+NnBF0H

-u9+mdCnlYqcq9qT1b2hC/VVSeOyiCZXVEE8Xn7trLGlSGIjfgNWmdHJYadL9JuWX

-/5xEU3/MZtfj7DfarYvJYONV9pnBEuucWUjRJgbPgMuqZ2sb7Ip/9/XZHvgFgVry

-LIJesLiFlk8Eme7kDH8EPny4I5RUuuftOfXz5semCOiQKqsV5jKlByPxYMdh+ADV

-jio0uE55Lb4MGfhxWuzcWD/Rov6IwIg0uuXWpEzjKr0JyVl/84wgni5Hq1O9EgeY

-07VBQOuiEzmhlmVGlkqi1/kFAZ+PkdNUSN7JPgvnVA/VgfigtlcIJ9ampsqau2ym

-KWh3bUKiV0eJVPA3/tvEdBooXn+8DQbt44syD7P52Mfl/bS2Lc5y6mPttVO/mDzu

-Xg6boDNzaXB/HDUF2Td8RackvqrHPKKXXoAz9w8sxYFGe8JVeuOwfO5HX6JHyscd

-cKqEZNMBLjxedpL0EZMzp72bse1XcvvIv/XChZnfK2Yfhfxcl3RIiTPx3s6FeeIo

-TsrNiTF8d/cOLK11/02hEUdo2r5jg8PHoZmXl0A8n6abXVcOnWi5M1tEjNduwKM6

-AQURY7Z9AlSsQXw6xj2z60zi8+Iwu3tgD4HP7NqwZRsD99la09HdcI0cSmeaEOTE

-ByrVyqnOBr8ZJVMLue4yM7+BdlGUabTW+0u0qy9Q1AxueQzUmE4VFKtfjRqIUlAA

-6HrfEsOe7HRLKxndctJ7uBXI5ghv3zGd0uZmRyjXsEjGr2JqaZa1HexraB/GHXGD

-9PZTJWS1mL8KE3o1hSj1yTglhfhJ7Wf/erfBGzctUPKQBkkpzVqZMS6Y2AIHTB5G

-b2wox/lwvFA2clodoT3tbeDmhNHxIuGlOnYtcPhILD7MReDNul1R9HL/SsW7AB6+

-q6R54PsSchNgFhLSdz0q6azXUlk6mcF5BgROvgyoa+7Gv0UlbSQbUuVuLD0k3SMU

-Dmpr/w9OmqUsOczYlnPWovh+GbVhze+eFTNIGV/wVNNJQRC1RUNrC/e8af4cp//r

-6jiQ5eNf8rVB8VMeMXRUHxPwRXtFVECuuTdMdPn4U2THJo+45Z0bVG9ytZ6CUP0n

-56DWH6/dKeIivEFz/bY4oCZmsIfkjNeo545GRfhFNNGRgrdjCevr0pJtY4h5VjI2

-iPUL85R0xze8oCT0a/GHY6XvpbnRz5qry1c2DoR3IeDQkq9yQjA7WautTbp8UzCd

-1S7RXIkrzPCg4XBIpQu5hswKC7W/UiH7H92ptyl2griC7E0JOfZ/MvgxZpFi8upe

-yY8j1GDIgwptf9QGLkm/epv/QM6L25wGEE916zQ+3rkUXTXT2oPIi8jaQRsloXci

-NI3l1FFEQjN4V4it3G2tVnegcAQdX9nsZ97pAq+NOK28OiN9kDN9olV+A0LMe75i

-BIB/zRUfIeg/TSbYiFV2cQ==

------END ENCRYPTED PRIVATE KEY-----

+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIwt8BG3xFhxYCAggA
+MB0GCWCGSAFlAwQBKgQQSn81QCB6EGEMiE6pZO1i9gSCBND1XL0OV5alXhRx/wna
+TuDqgFVyDjKbFWkm4gV394chFtOBSlODjAJnDyn25YUCYAf4pj44OQ13YpxFoFtR
+lvqA4TKdETHAONdij2CKIfZONO02Z5qURzySYQ2T4GRANS+UtO5KWD2vS0V4xVHL
+p+BLLoxQM2TgO5vG9/SiktTY7QI7wS7prqUPiUkROOATMR24E+tNlzmCXVRVpMp6
+m8PUecEO4sobYE8KdUgXCiWNb23nok5mM38BTWgxs/6H/ARCPvAUutyqo/gsHMNv
+uaOhev/yWTlF207/E/EtaS2pQcS0MT9sR7rK5KRLsoxpYrmPnEiid4nVvXPSmFAH
+cRCivlb9+VhhJZTtpLCUPgIj7ek9ljZZsr9lw10FELHJNYgQD/2/hkkhdZMQTF/d
+I+Yeq89t13PlyrGQUmL5k+XvmiCbWQWfNGw6p4vWznz6iB1P9L5IuWliQRXW4P3U
+gh/3hRc+C1sDCzCqV1Tr4GFQ7gFTsM5a2AroiT9bJGONGmILPYf6X7UQINruvmBt
+gBLeGJWAtdSN+1Fy7qLz/TbfEYCe0pBChVy1mKuSDXQ3mzWQA4UIJMBeIXkTtEPM
+ijL0Q8SLpt6MTrH8bP78IgrzynugVNvX3gFeVscsGQSUNJvIK+pqgYE1YuwrzNWd
+hpXbQCSgJaLajlyldrXCRudYchqCw4j4Y55BPN4mdgqW6P/9rOyyX9T5Lu/06HZH
+ceRQtsZR5+Qy+aLVL/TJ6nAGp1huVj+Gmz0P+DVb75eqnF7dHBJNqwrrKjq3aIIc
+YrXrKUa1OLkJAm1USHoIKTQS3tG/2xseVdRMCmC8HlaxzXxWxng/ho2L3pQ4MI+e
+5FLqoZruNKUzB9IakfEscEHxleqi+r29gz0FIUWIJU4hPpnE3xL/RF6jP3/f99uJ
+oOhKYVPZLRVgPP7bzO8dzvoF2qiqMRB6lWR7IrOAlHASkfzCkapaOGWgoKf9MqBO
+BptdCA5me2Im5Yrn8DggTogr1o2ZRnvWtZ4S8Ynms4G7P1NM0Da92W08JLLH4/iU
+4IimrFl7dPOn3jvKzr5hhGTmmxcVbO/XXnhY5qTqxlaB1fwq424vzQ7XeRMnlPeI
+NQ/oqO/4Kzz0DrezIz36cXtW4hZt+xNzbvy0FQEqBvWJa3+44nP751owIUG+Af4g
+EIj04smQz1AgiX+ojnvX8udSRsSfpylsUo8K4oF1uZuY3QlzoRgrb0cjR826YL5v
+byd1pJrgxz0oRxduhzR/bHa4mtVmrHiCOYoBjvzEbfQMhnunri8W3HjNDLu50Pdp
+u6xRzUuwL56aF7dqfUafez99KT2eFJBqPmSWnFyfVpL5iFW23KKPD9Oe/jxHWPLh
+/zLqvHaZk4TCT6E0KCn9mv/S6JSoOt+lD6gUnerLqhOnFTKmrZkWCzfchu8Y8NVJ
+nUCdOq/zKZVT1h8p0E8qLVYpTqRGQ4lgPkJt0i1qYJy5FXWmTnZQRdOKeWVh5vwK
+q63ueNwEMGpYCKgm+Gm1StmAQc/eLVL2KmES1BTgTBq1olyiYMHKyIkes1paSvHh
+kkirSf+XJxbQBXw6MpofKHQ5K9sdEfh8jofGwHudwdkrsXoIv/WTYANyg2h//6xh
+qPtyTnrApHAKTsnVbbMt/+4tnw==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/third_party/blink/web_tests/external/wpt/tools/certs/cacert.pem b/third_party/blink/web_tests/external/wpt/tools/certs/cacert.pem
index eeba528..f450f01 100644
--- a/third_party/blink/web_tests/external/wpt/tools/certs/cacert.pem
+++ b/third_party/blink/web_tests/external/wpt/tools/certs/cacert.pem
@@ -1,344 +1,347 @@
------BEGIN CERTIFICATE-----

-MIJAGzCCPwOgAwIBAgIDC/OuMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl

-Yi1wbGF0Zm9ybS10ZXN0czAeFw0yMDAyMTgyMDI5NDdaFw0zMDAyMTUyMDI5NDda

-MB0xGzAZBgNVBAMMEndlYi1wbGF0Zm9ybS10ZXN0czCCASIwDQYJKoZIhvcNAQEB

-BQADggEPADCCAQoCggEBAL99aWk3dRiYxIjNHlxLzZLMqafa/wArG5Q9T2ELxb0r

-OgDkVUMpiVBmA4rWpGIu8Rge/tHoa3FM76vkxyu3B6/sIfSPWpnU7YN/PQ94bjB4

-WTUFQR0LBnKUGbY1XVxe5AO1d1fY3tAmz3NHA46ifWzbVqRPZSzXpuNg5etBmfJ2

-fZ6reYtgS9VIquUoPSAFMKMt3J46bD6VP8QPcVFzYIL0DrnRlqd1ooMFFBMizXq6

-9ZSlY2SXA+M57a4lLmvUT51f5W/BtB7ucKbaOnxeZZLYAL9+0+rp922Ee2DroItF

-MgkAQQcvcuDotWS86VgSF7dPTjQ12E/7eH+9oPQFSxsCAwEAAaOCPWIwgj1eMAwG

-A1UdEwQFMAMBAf8wHQYDVR0OBBYEFPa52hYHBbtvyWMwxmdAywPTHpDsMEcGA1Ud

-IwRAMD6AFPa52hYHBbtvyWMwxmdAywPTHpDsoSGkHzAdMRswGQYDVQQDDBJ3ZWIt

-cGxhdGZvcm0tdGVzdHOCAwvzrjALBgNVHQ8EBAMCAgQwgh9jBgNVHR4Egh9aMIIf

-VqCCH1IwE4IRd2ViLXBsYXRmb3JtLnRlc3QwF4IVb3AyLndlYi1wbGF0Zm9ybS50

-ZXN0MBeCFW9wOS53ZWItcGxhdGZvcm0udGVzdDAXghVvcDcud2ViLXBsYXRmb3Jt

-LnRlc3QwF4IVb3AxLndlYi1wbGF0Zm9ybS50ZXN0MBeCFW9wMy53ZWItcGxhdGZv

-cm0udGVzdDAXghVvcDYud2ViLXBsYXRmb3JtLnRlc3QwF4IVbm90LXdlYi1wbGF0

-Zm9ybS50ZXN0MBeCFW9wNS53ZWItcGxhdGZvcm0udGVzdDAXghVvcDQud2ViLXBs

-YXRmb3JtLnRlc3QwF4IVb3A4LndlYi1wbGF0Zm9ybS50ZXN0MBeCFXd3dy53ZWIt

-cGxhdGZvcm0udGVzdDAYghZvcDg3LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wODAu

-d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A5NC53ZWItcGxhdGZvcm0udGVzdDAYghZv

-cDE2LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNDAud2ViLXBsYXRmb3JtLnRlc3Qw

-GIIWb3AxNy53ZWItcGxhdGZvcm0udGVzdDAYghZvcDcyLndlYi1wbGF0Zm9ybS50

-ZXN0MBiCFm9wNjQud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AyMy53ZWItcGxhdGZv

-cm0udGVzdDAYghZvcDI4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMTMud2ViLXBs

-YXRmb3JtLnRlc3QwGIIWb3AzNi53ZWItcGxhdGZvcm0udGVzdDAYghZvcDExLndl

-Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wNzkud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2

-MS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDQ4LndlYi1wbGF0Zm9ybS50ZXN0MBiC

-Fm9wMTkud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A0Mi53ZWItcGxhdGZvcm0udGVz

-dDAYghZvcDQ2LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzcud2ViLXBsYXRmb3Jt

-LnRlc3QwGIIWb3A5OC53ZWItcGxhdGZvcm0udGVzdDAYghZvcDY2LndlYi1wbGF0

-Zm9ybS50ZXN0MBiCFnd3dzEud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AyNi53ZWIt

-cGxhdGZvcm0udGVzdDAYghZvcDY3LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNzMu

-d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AzOC53ZWItcGxhdGZvcm0udGVzdDAYghZv

-cDYyLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTgud2ViLXBsYXRmb3JtLnRlc3Qw

-GIIWb3A1Ni53ZWItcGxhdGZvcm0udGVzdDAYghZvcDIyLndlYi1wbGF0Zm9ybS50

-ZXN0MBiCFm9wMjQud2ViLXBsYXRmb3JtLnRlc3QwGIIWd3d3Mi53ZWItcGxhdGZv

-cm0udGVzdDAYghZvcDE4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNzQud2ViLXBs

-YXRmb3JtLnRlc3QwGIIWb3A5MS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDMzLndl

-Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wNjkud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3Az

-MC53ZWItcGxhdGZvcm0udGVzdDAYghZvcDM5LndlYi1wbGF0Zm9ybS50ZXN0MBiC

-Fm9wNTIud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A0My53ZWItcGxhdGZvcm0udGVz

-dDAYghZvcDg1LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzQud2ViLXBsYXRmb3Jt

-LnRlc3QwGIIWb3AyMS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDcxLndlYi1wbGF0

-Zm9ybS50ZXN0MBiCFm9wNTAud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4NC53ZWIt

-cGxhdGZvcm0udGVzdDAYghZvcDMxLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTQu

-d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A0OS53ZWItcGxhdGZvcm0udGVzdDAYghZv

-cDQ0LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNDUud2ViLXBsYXRmb3JtLnRlc3Qw

-GIIWb3AzNS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDc2LndlYi1wbGF0Zm9ybS50

-ZXN0MBiCFm9wMTQud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4MS53ZWItcGxhdGZv

-cm0udGVzdDAYghZvcDg4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMjAud2ViLXBs

-YXRmb3JtLnRlc3QwGIIWb3A5NS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDUxLndl

-Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wODYud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A1

-NS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDI3LndlYi1wbGF0Zm9ybS50ZXN0MBiC

-Fm9wMTIud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A3NS53ZWItcGxhdGZvcm0udGVz

-dDAYghZvcDQ3LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wOTYud2ViLXBsYXRmb3Jt

-LnRlc3QwGIIWb3A5My53ZWItcGxhdGZvcm0udGVzdDAYghZvcDU3LndlYi1wbGF0

-Zm9ybS50ZXN0MBiCFm9wNjMud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A1My53ZWIt

-cGxhdGZvcm0udGVzdDAYghZvcDI5LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMjUu

-d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4My53ZWItcGxhdGZvcm0udGVzdDAYghZv

-cDk3LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNDEud2ViLXBsYXRmb3JtLnRlc3Qw

-GIIWb3AzMi53ZWItcGxhdGZvcm0udGVzdDAYghZvcDcwLndlYi1wbGF0Zm9ybS50

-ZXN0MBiCFm9wNjAud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A5Mi53ZWItcGxhdGZv

-cm0udGVzdDAYghZvcDc4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wODkud2ViLXBs

-YXRmb3JtLnRlc3QwGIIWb3AxMC53ZWItcGxhdGZvcm0udGVzdDAYghZvcDc3Lndl

-Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTkud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3Ax

-NS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDY1LndlYi1wbGF0Zm9ybS50ZXN0MBiC

-Fm9wNjgud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A5MC53ZWItcGxhdGZvcm0udGVz

-dDAYghZvcDgyLndlYi1wbGF0Zm9ybS50ZXN0MBuCGW9wNi5ub3Qtd2ViLXBsYXRm

-b3JtLnRlc3QwG4IZb3A4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAbghlvcDkubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0MBuCGW9wNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw

-G4IZb3A3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAbghl3d3cud3d3LndlYi1wbGF0

-Zm9ybS50ZXN0MBuCGW9wMi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwG4IZb3AxLm5v

-dC13ZWItcGxhdGZvcm0udGVzdDAbghl3d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0

-MBuCGW9wNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwG4IZb3AzLm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDI3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQw

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQ1Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDk2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDI4Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDgzLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDMzLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDU2Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghp3d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDYy

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDE4Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDQ4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQzLm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDg5Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDYwLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDk1Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDczLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDkx

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQyLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDI2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDY5Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDMyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDM3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDk4Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDE5Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDc2

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDEzLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDc5Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cyLnd3dy53

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDg2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDc3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDI5Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDU1Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDky

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQ0Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDU0Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDk0Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDM0Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDMwLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cxLnd3dy53ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDI1Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDY0

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDIwLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDUxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDQxLm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDEyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDEwLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDcyLm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDIyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDUy

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDc0Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDY3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDgwLm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDg0Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDMxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDUzLm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDIzLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDM1

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDE2Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDYzLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDM4Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDU4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDYxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDE0Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDkwLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDcw

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDExLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDE1Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDY1Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDUwLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDY4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDg3Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDc4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cu

-d3d3Mi53ZWItcGxhdGZvcm0udGVzdDAcghpvcDgyLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDkzLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghp3d3cud3d3MS53

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDIxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDcxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDk3Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDg4Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDI0

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDY2Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDQ5Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDU5Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghpvcDQ2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDM2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDM5Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAcghpvcDQ3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDE3

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDc1Lm5vdC13ZWItcGxhdGZvcm0u

-dGVzdDAcghpvcDg1Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAcghpvcDU3Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdDAcghp3d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdDAc

-ghpvcDgxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAdght3d3cyLnd3dzEud2ViLXBs

-YXRmb3JtLnRlc3QwHYIbd3d3MS53d3cyLndlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3

-dzIud3d3Mi53ZWItcGxhdGZvcm0udGVzdDAdght3d3cxLnd3dzEud2ViLXBsYXRm

-b3JtLnRlc3QwH4Idd3d3Lnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3

-Mi53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCCCHnhuLS1sdmUtNmxhZC53ZWIt

-cGxhdGZvcm0udGVzdDAggh53d3cxLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw

-IIIed3d3Lnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCCCHnd3dy53d3cyLm5v

-dC13ZWItcGxhdGZvcm0udGVzdDAhgh93d3cxLnd3dzIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0MCGCH3d3dzEud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIYIfd3d3

-Mi53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdDAhgh93d3cyLnd3dzIubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0MCSCInhuLS1sdmUtNmxhZC53d3cud2ViLXBsYXRmb3Jt

-LnRlc3QwJIIieG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDAkgiJ3

-d3cueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MCWCI3d3dzEueG4tLWx2

-ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MCWCI3d3dzIueG4tLWx2ZS02bGFkLndl

-Yi1wbGF0Zm9ybS50ZXN0MCWCI3huLS1sdmUtNmxhZC53d3cyLndlYi1wbGF0Zm9y

-bS50ZXN0MCWCI3huLS1sdmUtNmxhZC53d3cxLndlYi1wbGF0Zm9ybS50ZXN0MCiC

-Jnd3dy54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCiCJnhuLS1s

-dmUtNmxhZC53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3d3dzEueG4tLWx2

-ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDApgid3d3cyLnhuLS1sdmUtNmxh

-ZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYIneG4tLWx2ZS02bGFkLnd3dzEubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3huLS1sdmUtNmxhZC53d3cyLm5vdC13ZWIt

-cGxhdGZvcm0udGVzdDArgil4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxh

-dGZvcm0udGVzdDAtgit4bi0tbHZlLTZsYWQueG4tLWx2ZS02bGFkLndlYi1wbGF0

-Zm9ybS50ZXN0MC+CLXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxh

-dGZvcm0udGVzdDAvgi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cud2ViLXBs

-YXRmb3JtLnRlc3QwL4Itd3d3LnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1w

-bGF0Zm9ybS50ZXN0MDCCLnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi

-LXBsYXRmb3JtLnRlc3QwMIIud3d3MS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53

-ZWItcGxhdGZvcm0udGVzdDAwgi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cx

-LndlYi1wbGF0Zm9ybS50ZXN0MDCCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3

-dzIud2ViLXBsYXRmb3JtLnRlc3QwMYIveG4tLWx2ZS02bGFkLnhuLS1sdmUtNmxh

-ZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwM4IxeG4tLW44ajZkczUzbHd3a3JxaHYy

-OGEud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAzgjF3d3cueG4tLW44ajZkczUz

-bHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSCMnd3dzEueG4tLW44

-ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSCMnhuLS1u

-OGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDSC

-Mnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0MDSCMnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIubm90LXdlYi1wbGF0

-Zm9ybS50ZXN0MDiCNnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1sdmUtNmxh

-ZC53ZWItcGxhdGZvcm0udGVzdDA4gjZ4bi0tbHZlLTZsYWQueG4tLW44ajZkczUz

-bHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3QwPII6eG4tLWx2ZS02bGFkLnhu

-LS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdDA8gjp4

-bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0

-Zm9ybS50ZXN0MEOCQXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1uOGo2ZHM1

-M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0MEeCRXhuLS1uOGo2ZHM1M2x3

-d2tycWh2MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZv

-cm0udGVzdDATBgNVHSUEDDAKBggrBgEFBQcDATCCHVsGA1UdEQSCHVIwgh1OghF3

-ZWItcGxhdGZvcm0udGVzdIIVb3AyLndlYi1wbGF0Zm9ybS50ZXN0ghVvcDkud2Vi

-LXBsYXRmb3JtLnRlc3SCFW9wNy53ZWItcGxhdGZvcm0udGVzdIIVb3AxLndlYi1w

-bGF0Zm9ybS50ZXN0ghVvcDMud2ViLXBsYXRmb3JtLnRlc3SCFW9wNi53ZWItcGxh

-dGZvcm0udGVzdIIVbm90LXdlYi1wbGF0Zm9ybS50ZXN0ghVvcDUud2ViLXBsYXRm

-b3JtLnRlc3SCFW9wNC53ZWItcGxhdGZvcm0udGVzdIIVb3A4LndlYi1wbGF0Zm9y

-bS50ZXN0ghV3d3cud2ViLXBsYXRmb3JtLnRlc3SCFm9wODcud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wODAud2ViLXBsYXRmb3JtLnRlc3SCFm9wOTQud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMTYud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDAud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMTcud2ViLXBsYXRmb3JtLnRlc3SCFm9wNzIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjQud2ViLXBsYXRmb3JtLnRlc3SCFm9wMjMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMjgud2ViLXBsYXRmb3JtLnRlc3SCFm9wMTMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzYud2ViLXBsYXRmb3JtLnRlc3SCFm9wMTEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNzkud2ViLXBsYXRmb3JtLnRlc3SCFm9wNjEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNDgud2ViLXBsYXRmb3JtLnRlc3SCFm9wMTkud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNDIud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDYud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzcud2ViLXBsYXRmb3JtLnRlc3SCFm9wOTgud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjYud2ViLXBsYXRmb3JtLnRlc3SCFnd3dzEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMjYud2ViLXBsYXRmb3JtLnRlc3SCFm9wNjcud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNzMud2ViLXBsYXRmb3JtLnRlc3SCFm9wMzgud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjIud2ViLXBsYXRmb3JtLnRlc3SCFm9wNTgud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNTYud2ViLXBsYXRmb3JtLnRlc3SCFm9wMjIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMjQud2ViLXBsYXRmb3JtLnRlc3SCFnd3dzIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMTgud2ViLXBsYXRmb3JtLnRlc3SCFm9wNzQud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wOTEud2ViLXBsYXRmb3JtLnRlc3SCFm9wMzMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjkud2ViLXBsYXRmb3JtLnRlc3SCFm9wMzAud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzkud2ViLXBsYXRmb3JtLnRlc3SCFm9wNTIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNDMud2ViLXBsYXRmb3JtLnRlc3SCFm9wODUud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzQud2ViLXBsYXRmb3JtLnRlc3SCFm9wMjEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNzEud2ViLXBsYXRmb3JtLnRlc3SCFm9wNTAud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wODQud2ViLXBsYXRmb3JtLnRlc3SCFm9wMzEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNTQud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDkud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNDQud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDUud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzUud2ViLXBsYXRmb3JtLnRlc3SCFm9wNzYud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMTQud2ViLXBsYXRmb3JtLnRlc3SCFm9wODEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wODgud2ViLXBsYXRmb3JtLnRlc3SCFm9wMjAud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wOTUud2ViLXBsYXRmb3JtLnRlc3SCFm9wNTEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wODYud2ViLXBsYXRmb3JtLnRlc3SCFm9wNTUud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMjcud2ViLXBsYXRmb3JtLnRlc3SCFm9wMTIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNzUud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDcud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wOTYud2ViLXBsYXRmb3JtLnRlc3SCFm9wOTMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNTcud2ViLXBsYXRmb3JtLnRlc3SCFm9wNjMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNTMud2ViLXBsYXRmb3JtLnRlc3SCFm9wMjkud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMjUud2ViLXBsYXRmb3JtLnRlc3SCFm9wODMud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wOTcud2ViLXBsYXRmb3JtLnRlc3SCFm9wNDEud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMzIud2ViLXBsYXRmb3JtLnRlc3SCFm9wNzAud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjAud2ViLXBsYXRmb3JtLnRlc3SCFm9wOTIud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNzgud2ViLXBsYXRmb3JtLnRlc3SCFm9wODkud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wMTAud2ViLXBsYXRmb3JtLnRlc3SCFm9wNzcud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNTkud2ViLXBsYXRmb3JtLnRlc3SCFm9wMTUud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wNjUud2ViLXBsYXRmb3JtLnRlc3SCFm9wNjgud2ViLXBsYXRmb3Jt

-LnRlc3SCFm9wOTAud2ViLXBsYXRmb3JtLnRlc3SCFm9wODIud2ViLXBsYXRmb3Jt

-LnRlc3SCGW9wNi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGW9wOC5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGW9wOS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGW9wNC5ub3Qt

-d2ViLXBsYXRmb3JtLnRlc3SCGW9wNy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGXd3

-dy53d3cud2ViLXBsYXRmb3JtLnRlc3SCGW9wMi5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGW9wMS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGXd3dy5ub3Qtd2ViLXBsYXRm

-b3JtLnRlc3SCGW9wNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGW9wMy5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wMjcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQw

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0NS5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wOTYubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDI4Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3A4My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzMubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-d3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDE4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0OC5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wNDMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg5

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2MC5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wOTUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDczLm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3A5MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNDIubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDI2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A2OS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDM3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5OC5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wMTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDc2

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AxMy5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wNzkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cyLnd3dy53ZWItcGxh

-dGZvcm0udGVzdIIab3A4Ni5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzcubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDI5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A1NS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wOTIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDQ0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A1NC5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wOTQubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDM0

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AzMC5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGnd3dzEud3d3LndlYi1wbGF0Zm9ybS50ZXN0ghpvcDI1Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3A2NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjAubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDUxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A0MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDEwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3Mi5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wMjIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDUy

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3NC5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wNjcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDgwLm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3A4NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzEubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDUzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3AyMy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzUubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDE2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2My5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wMzgubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU4

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2MS5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wMTQubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDkwLm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3A3MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTEubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE1Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A2NS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTAubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDY4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A4Ny5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wNzgubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cu

-d3d3Mi53ZWItcGxhdGZvcm0udGVzdIIab3A4Mi5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wOTMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cud3d3MS53ZWItcGxh

-dGZvcm0udGVzdIIab3AyMS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzEubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDk3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A4OC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjQubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDY2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0OS5ub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCGm9wNTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQ2

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AzNi5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCGm9wMzkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQ3Lm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIab3AxNy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzUubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg1Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa

-b3A1Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0ghpvcDgxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIbd3d3Mi53d3cxLndl

-Yi1wbGF0Zm9ybS50ZXN0ght3d3cxLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCG3d3

-dzIud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cxLndlYi1wbGF0Zm9y

-bS50ZXN0gh13d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3Mi53d3cu

-bm90LXdlYi1wbGF0Zm9ybS50ZXN0gh54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3Jt

-LnRlc3SCHnd3dzEud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3Lnd3dzEu

-bm90LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3Mi5ub3Qtd2ViLXBsYXRmb3Jt

-LnRlc3SCH3d3dzEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3

-MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRm

-b3JtLnRlc3SCH3d3dzIud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCInhuLS1s

-dmUtNmxhZC53d3cud2ViLXBsYXRmb3JtLnRlc3SCInhuLS1sdmUtNmxhZC5ub3Qt

-d2ViLXBsYXRmb3JtLnRlc3SCInd3dy54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3Jt

-LnRlc3SCI3d3dzEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giN3d3cy

-LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIjeG4tLWx2ZS02bGFkLnd3

-dzIud2ViLXBsYXRmb3JtLnRlc3SCI3huLS1sdmUtNmxhZC53d3cxLndlYi1wbGF0

-Zm9ybS50ZXN0giZ3d3cueG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVz

-dIImeG4tLWx2ZS02bGFkLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3d3dzEu

-eG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIInd3d3Mi54bi0tbHZl

-LTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gid4bi0tbHZlLTZsYWQud3d3MS5u

-b3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53d3cyLm5vdC13ZWIt

-cGxhdGZvcm0udGVzdIIpeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRm

-b3JtLnRlc3SCK3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3Jt

-LnRlc3SCLXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdIIteG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3LndlYi1wbGF0Zm9ybS50

-ZXN0gi13d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRl

-c3SCLnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRl

-c3SCLnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRl

-c3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEud2ViLXBsYXRmb3JtLnRl

-c3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIud2ViLXBsYXRmb3JtLnRl

-c3SCL3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0gjF4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0gjF3d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0

-Zm9ybS50ZXN0gjJ3d3cxLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWIt

-cGxhdGZvcm0udGVzdIIyeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3MS5ub3Qt

-d2ViLXBsYXRmb3JtLnRlc3SCMnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEu

-bm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53

-d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdII2eG4tLW44ajZkczUzbHd3a3JxaHYy

-OGEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0gjZ4bi0tbHZlLTZsYWQu

-eG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1s

-dmUtNmxhZC54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3Jt

-LnRlc3SCOnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1sdmUtNmxhZC5ub3Qt

-d2ViLXBsYXRmb3JtLnRlc3SCQXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1u

-OGo2ZHM1M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0gkV4bi0tbjhqNmRz

-NTNsd3drcnFodjI4YS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3QwDQYJKoZIhvcNAQELBQADggEBAIeTu2IyTpAPbUYCxfR3T6Bq

-d5Ymo3TG8pnZrsYqzHtCIvGoO81JEIJdhPyitbJd/usbtkEThLhafeQi9RmiCZYv

-CUex0IdUxHaW36Zx4kIzNLf02zcxwBJtAFpf/yAsQdKII0ZFNGR1WkRqnatfz5ty

-SK/S593MY9sO7xdxsPcQnJ7WPaXK660yO1Gotbh4bRwpdL8uJvFVpe6+UAOS64Mk

-jKyFIy3Z9Hlb+HPV0wFBS89WqqEfAoLkbrf0KEjoBrvIlIXf8/tLogTTUSbZd667

-qf88SX/0tYVMEYC6/IUiyigAx/hMiuWCDCS10mWLwYfPs2JwDQRlSIoveNBp+wg=

------END CERTIFICATE-----

+-----BEGIN CERTIFICATE-----
+MIJAhzCCP2+gAwIBAgIDC+NXMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl
+Yi1wbGF0Zm9ybS10ZXN0czAeFw0yMDA3MzAyMDEyNDhaFw0yMjEwMDgyMDEyNDha
+MB0xGzAZBgNVBAMMEndlYi1wbGF0Zm9ybS10ZXN0czCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAONFL+vCrQenoebExCh0nArZa2+BRz3NmEkS0z7EBtc0
+i6FDQr3lwo+b2zDSqllvrpQHCFReuSagHAW1wPRo0mHicdvhHOCfFc2+bBPXS4db
+8cUNUOc4ClRqOLPwGu+yPteWv/OJPx4nS9COU3HWj+KIAINtKtlxoRe6XbXs2D5J
+3iMfJcI3ZINVWmnhAlMTKqzMLjn8ouIDAsyCf7aZj+JS39B4GN1CzBbomXEeJHad
+36PChji2R+k7LJPK/4gwOsfSpiTfOoF0FK1IxZwQ9cWRhqEEgcFpt4CZSR0HadlG
+MYnrgG4a0v/A1BbBQYDe1M0UPttUOHy2+7XHaEdB/vUCAwEAAaOCPc4wgj3KMAwG
+A1UdEwQFMAMBAf8wHQYDVR0OBBYEFLN13aCb8lr+F42Asfynt8EreSkrMEcGA1Ud
+IwRAMD6AFLN13aCb8lr+F42Asfynt8EreSkroSGkHzAdMRswGQYDVQQDDBJ3ZWIt
+cGxhdGZvcm0tdGVzdHOCAwvjVzALBgNVHQ8EBAMCAgQwgh+bBgNVHR4Egh+SMIIf
+jqCCH4owE4IRd2ViLXBsYXRmb3JtLnRlc3QwF4IVb3A4LndlYi1wbGF0Zm9ybS50
+ZXN0MBeCFW9wNy53ZWItcGxhdGZvcm0udGVzdDAXghVvcDkud2ViLXBsYXRmb3Jt
+LnRlc3QwF4IVb3A0LndlYi1wbGF0Zm9ybS50ZXN0MBeCFW5vdC13ZWItcGxhdGZv
+cm0udGVzdDAXghVvcDYud2ViLXBsYXRmb3JtLnRlc3QwF4IVb3AzLndlYi1wbGF0
+Zm9ybS50ZXN0MBeCFW9wMi53ZWItcGxhdGZvcm0udGVzdDAXghVvcDEud2ViLXBs
+YXRmb3JtLnRlc3QwF4IVd3d3LndlYi1wbGF0Zm9ybS50ZXN0MBeCFW9wNS53ZWIt
+cGxhdGZvcm0udGVzdDAYghZvcDg4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wOTgu
+d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4NS53ZWItcGxhdGZvcm0udGVzdDAYghZv
+cDg5LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNjYud2ViLXBsYXRmb3JtLnRlc3Qw
+GIIWb3A3Mi53ZWItcGxhdGZvcm0udGVzdDAYghZvcDI0LndlYi1wbGF0Zm9ybS50
+ZXN0MBiCFm9wNDEud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A3OS53ZWItcGxhdGZv
+cm0udGVzdDAYghZvcDkxLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTkud2ViLXBs
+YXRmb3JtLnRlc3QwGIIWb3AzOS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDYwLndl
+Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTgud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3Ay
+OC53ZWItcGxhdGZvcm0udGVzdDAYghZ3d3cxLndlYi1wbGF0Zm9ybS50ZXN0MBiC
+Fm9wMTQud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2OS53ZWItcGxhdGZvcm0udGVz
+dDAYghZvcDQwLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNzQud2ViLXBsYXRmb3Jt
+LnRlc3QwGIIWb3AzMS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDE4LndlYi1wbGF0
+Zm9ybS50ZXN0MBiCFm9wNzMud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A3Ny53ZWIt
+cGxhdGZvcm0udGVzdDAYghZvcDEyLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNTQu
+d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2My53ZWItcGxhdGZvcm0udGVzdDAYghZv
+cDcxLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wOTUud2ViLXBsYXRmb3JtLnRlc3Qw
+GIIWb3AxNi53ZWItcGxhdGZvcm0udGVzdDAYghZvcDM2LndlYi1wbGF0Zm9ybS50
+ZXN0MBiCFm9wMjcud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AyOS53ZWItcGxhdGZv
+cm0udGVzdDAYghZvcDk0LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNDQud2ViLXBs
+YXRmb3JtLnRlc3QwGIIWb3AzMy53ZWItcGxhdGZvcm0udGVzdDAYghZvcDg0Lndl
+Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzIud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2
+MS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDcwLndlYi1wbGF0Zm9ybS50ZXN0MBiC
+Fnd3dzIud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A0My53ZWItcGxhdGZvcm0udGVz
+dDAYghZvcDc4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMjYud2ViLXBsYXRmb3Jt
+LnRlc3QwGIIWb3A3Ni53ZWItcGxhdGZvcm0udGVzdDAYghZvcDUyLndlYi1wbGF0
+Zm9ybS50ZXN0MBiCFm9wOTkud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4Ni53ZWIt
+cGxhdGZvcm0udGVzdDAYghZvcDQ2LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMTcu
+d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A5MC53ZWItcGxhdGZvcm0udGVzdDAYghZv
+cDkzLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMTAud2ViLXBsYXRmb3JtLnRlc3Qw
+GIIWb3A1NS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDQ3LndlYi1wbGF0Zm9ybS50
+ZXN0MBiCFm9wNTEud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A0NS53ZWItcGxhdGZv
+cm0udGVzdDAYghZvcDgwLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNjgud2ViLXBs
+YXRmb3JtLnRlc3QwGIIWb3A0OS53ZWItcGxhdGZvcm0udGVzdDAYghZvcDU3Lndl
+Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzUud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2
+Ny53ZWItcGxhdGZvcm0udGVzdDAYghZvcDkyLndlYi1wbGF0Zm9ybS50ZXN0MBiC
+Fm9wMTUud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AxMy53ZWItcGxhdGZvcm0udGVz
+dDAYghZvcDc1LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNjQud2ViLXBsYXRmb3Jt
+LnRlc3QwGIIWb3A5Ny53ZWItcGxhdGZvcm0udGVzdDAYghZvcDM3LndlYi1wbGF0
+Zm9ybS50ZXN0MBiCFm9wNTYud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A2Mi53ZWIt
+cGxhdGZvcm0udGVzdDAYghZvcDgyLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMjUu
+d2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AxMS53ZWItcGxhdGZvcm0udGVzdDAYghZv
+cDUwLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzgud2ViLXBsYXRmb3JtLnRlc3Qw
+GIIWb3A4My53ZWItcGxhdGZvcm0udGVzdDAYghZvcDgxLndlYi1wbGF0Zm9ybS50
+ZXN0MBiCFm9wMjAud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AyMS53ZWItcGxhdGZv
+cm0udGVzdDAYghZvcDIzLndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wNDIud2ViLXBs
+YXRmb3JtLnRlc3QwGIIWb3AyMi53ZWItcGxhdGZvcm0udGVzdDAYghZvcDY1Lndl
+Yi1wbGF0Zm9ybS50ZXN0MBiCFm9wOTYud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3A4
+Ny53ZWItcGxhdGZvcm0udGVzdDAYghZvcDE5LndlYi1wbGF0Zm9ybS50ZXN0MBiC
+Fm9wNTMud2ViLXBsYXRmb3JtLnRlc3QwGIIWb3AzMC53ZWItcGxhdGZvcm0udGVz
+dDAYghZvcDQ4LndlYi1wbGF0Zm9ybS50ZXN0MBiCFm9wMzQud2ViLXBsYXRmb3Jt
+LnRlc3QwG4IZb3A2Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAbghlvcDMubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0MBuCGW9wMi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwG4IZ
+b3A1Lm5vdC13ZWItcGxhdGZvcm0udGVzdDAbghl3d3cubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MBuCGXd3dy53d3cud2ViLXBsYXRmb3JtLnRlc3QwG4IZb3A3Lm5vdC13
+ZWItcGxhdGZvcm0udGVzdDAbghlvcDQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MBuC
+GW9wOC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwG4IZb3A5Lm5vdC13ZWItcGxhdGZv
+cm0udGVzdDAbghlvcDEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMzYubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTMubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNTAubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMjQubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wMzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+OTUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wODMubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNzMubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wMjEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wODEubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wNzAubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+Nzgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDAubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMjUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNjUubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dy53d3cyLndlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wODAubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTIubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wNjgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+NDUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNzEubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wNzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTAubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wODkubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNDkubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNzcubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wNzkubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+ODIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dy53d3cxLndlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMTIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMzkubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDQubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTgubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wMTQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+MzAubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNjIubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wNjEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTIubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMjkubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wOTgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNjQubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wMjYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+MjIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTQubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMzgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMzMubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMjMubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNTcubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTQubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wODUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+NDYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTcubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNjAubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTYubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNTEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDEubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wMzUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+OTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDIubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wNjcubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMzcubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDgubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNTUubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTYubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wODQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+MzQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNjkubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMTEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTMubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dzEud3d3LndlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wODYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMTMubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wMjAubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+NzYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMjcubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMTcubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNzUubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMTUubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNDcubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMTgubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wNjMubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+Mjgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNDMubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wNjYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGnd3dzIud3d3
+LndlYi1wbGF0Zm9ybS50ZXN0MByCGm9wOTEubm90LXdlYi1wbGF0Zm9ybS50ZXN0
+MByCGm9wNzQubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wNTkubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0MByCGm9wODgubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9w
+ODcubm90LXdlYi1wbGF0Zm9ybS50ZXN0MByCGm9wMTAubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0MByCGm9wMTYubm90LXdlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3dzEud3d3
+Mi53ZWItcGxhdGZvcm0udGVzdDAdght3d3cyLnd3dzIud2ViLXBsYXRmb3JtLnRl
+c3QwHYIbd3d3Mi53d3cxLndlYi1wbGF0Zm9ybS50ZXN0MB2CG3d3dzEud3d3MS53
+ZWItcGxhdGZvcm0udGVzdDAfgh13d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVz
+dDAggh54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3MS53d3cu
+bm90LXdlYi1wbGF0Zm9ybS50ZXN0MCCCHnd3dy53d3cyLm5vdC13ZWItcGxhdGZv
+cm0udGVzdDAggh53d3cyLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwIIIed3d3
+Lnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCGCH3d3dzIud3d3Mi5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3QwIYIfd3d3Mi53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVz
+dDAhgh93d3cxLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCGCH3d3dzEud3d3
+Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwJIIieG4tLWx2ZS02bGFkLnd3dy53ZWIt
+cGxhdGZvcm0udGVzdDAkgiJ4bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0MCSCInd3dy54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3QwJYIjd3d3
+Mi54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3QwJYIjeG4tLWx2ZS02bGFk
+Lnd3dzIud2ViLXBsYXRmb3JtLnRlc3QwJYIjeG4tLWx2ZS02bGFkLnd3dzEud2Vi
+LXBsYXRmb3JtLnRlc3QwJYIjd3d3MS54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3Jt
+LnRlc3QwKIImeG4tLWx2ZS02bGFkLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw
+KIImd3d3LnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYIneG4t
+LWx2ZS02bGFkLnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MCmCJ3d3dzIueG4t
+LWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDApgid3d3cxLnhuLS1sdmUt
+NmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwKYIneG4tLWx2ZS02bGFkLnd3dzIu
+bm90LXdlYi1wbGF0Zm9ybS50ZXN0MCuCKXhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh
+LndlYi1wbGF0Zm9ybS50ZXN0MC2CK3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQu
+d2ViLXBsYXRmb3JtLnRlc3QwL4Itd3d3LnhuLS1uOGo2ZHM1M2x3d2tycWh2Mjhh
+LndlYi1wbGF0Zm9ybS50ZXN0MC+CLXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLm5v
+dC13ZWItcGxhdGZvcm0udGVzdDAvgi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS53
+d3cud2ViLXBsYXRmb3JtLnRlc3QwMIIud3d3MS54bi0tbjhqNmRzNTNsd3drcnFo
+djI4YS53ZWItcGxhdGZvcm0udGVzdDAwgi54bi0tbjhqNmRzNTNsd3drcnFodjI4
+YS53d3cyLndlYi1wbGF0Zm9ybS50ZXN0MDCCLnhuLS1uOGo2ZHM1M2x3d2tycWh2
+MjhhLnd3dzEud2ViLXBsYXRmb3JtLnRlc3QwMIIud3d3Mi54bi0tbjhqNmRzNTNs
+d3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdDAxgi94bi0tbHZlLTZsYWQueG4t
+LWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdDAzgjF3d3cueG4tLW44ajZk
+czUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0MDOCMXhuLS1uOGo2
+ZHM1M2x3d2tycWh2MjhhLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwNIIyeG4t
+LW44ajZkczUzbHd3a3JxaHYyOGEud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3Qw
+NIIyd3d3MS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3Jt
+LnRlc3QwNIIyd3d3Mi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3QwNIIyeG4tLW44ajZkczUzbHd3a3JxaHYyOGEud3d3MS5ub3Qt
+d2ViLXBsYXRmb3JtLnRlc3QwOII2eG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4t
+LWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0MDiCNnhuLS1sdmUtNmxhZC54bi0t
+bjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdDA8gjp4bi0tbjhq
+NmRzNTNsd3drcnFodjI4YS54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0MDyCOnhuLS1sdmUtNmxhZC54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qt
+d2ViLXBsYXRmb3JtLnRlc3QwQ4JBeG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4t
+LW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3QwR4JFeG4tLW44
+ajZkczUzbHd3a3JxaHYyOGEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMIIdjwYDVR0RBIId
+hjCCHYKCEXdlYi1wbGF0Zm9ybS50ZXN0ghVvcDgud2ViLXBsYXRmb3JtLnRlc3SC
+FW9wNy53ZWItcGxhdGZvcm0udGVzdIIVb3A5LndlYi1wbGF0Zm9ybS50ZXN0ghVv
+cDQud2ViLXBsYXRmb3JtLnRlc3SCFW5vdC13ZWItcGxhdGZvcm0udGVzdIIVb3A2
+LndlYi1wbGF0Zm9ybS50ZXN0ghVvcDMud2ViLXBsYXRmb3JtLnRlc3SCFW9wMi53
+ZWItcGxhdGZvcm0udGVzdIIVb3AxLndlYi1wbGF0Zm9ybS50ZXN0ghV3d3cud2Vi
+LXBsYXRmb3JtLnRlc3SCFW9wNS53ZWItcGxhdGZvcm0udGVzdIIWb3A4OC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5OC53ZWItcGxhdGZvcm0udGVzdIIWb3A4NS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A4OS53ZWItcGxhdGZvcm0udGVzdIIWb3A2Ni53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A3Mi53ZWItcGxhdGZvcm0udGVzdIIWb3AyNC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A0MS53ZWItcGxhdGZvcm0udGVzdIIWb3A3OS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5MS53ZWItcGxhdGZvcm0udGVzdIIWb3A1OS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzOS53ZWItcGxhdGZvcm0udGVzdIIWb3A2MC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1OC53ZWItcGxhdGZvcm0udGVzdIIWb3AyOC53ZWIt
+cGxhdGZvcm0udGVzdIIWd3d3MS53ZWItcGxhdGZvcm0udGVzdIIWb3AxNC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A2OS53ZWItcGxhdGZvcm0udGVzdIIWb3A0MC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A3NC53ZWItcGxhdGZvcm0udGVzdIIWb3AzMS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AxOC53ZWItcGxhdGZvcm0udGVzdIIWb3A3My53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A3Ny53ZWItcGxhdGZvcm0udGVzdIIWb3AxMi53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1NC53ZWItcGxhdGZvcm0udGVzdIIWb3A2My53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A3MS53ZWItcGxhdGZvcm0udGVzdIIWb3A5NS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AxNi53ZWItcGxhdGZvcm0udGVzdIIWb3AzNi53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyNy53ZWItcGxhdGZvcm0udGVzdIIWb3AyOS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5NC53ZWItcGxhdGZvcm0udGVzdIIWb3A0NC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzMy53ZWItcGxhdGZvcm0udGVzdIIWb3A4NC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzMi53ZWItcGxhdGZvcm0udGVzdIIWb3A2MS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A3MC53ZWItcGxhdGZvcm0udGVzdIIWd3d3Mi53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A0My53ZWItcGxhdGZvcm0udGVzdIIWb3A3OC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyNi53ZWItcGxhdGZvcm0udGVzdIIWb3A3Ni53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A5OS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A4Ni53ZWItcGxhdGZvcm0udGVzdIIWb3A0Ni53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AxNy53ZWItcGxhdGZvcm0udGVzdIIWb3A5MC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5My53ZWItcGxhdGZvcm0udGVzdIIWb3AxMC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1NS53ZWItcGxhdGZvcm0udGVzdIIWb3A0Ny53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1MS53ZWItcGxhdGZvcm0udGVzdIIWb3A0NS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A4MC53ZWItcGxhdGZvcm0udGVzdIIWb3A2OC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A0OS53ZWItcGxhdGZvcm0udGVzdIIWb3A1Ny53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzNS53ZWItcGxhdGZvcm0udGVzdIIWb3A2Ny53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5Mi53ZWItcGxhdGZvcm0udGVzdIIWb3AxNS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AxMy53ZWItcGxhdGZvcm0udGVzdIIWb3A3NS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A2NC53ZWItcGxhdGZvcm0udGVzdIIWb3A5Ny53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzNy53ZWItcGxhdGZvcm0udGVzdIIWb3A1Ni53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A2Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A4Mi53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyNS53ZWItcGxhdGZvcm0udGVzdIIWb3AxMS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A1MC53ZWItcGxhdGZvcm0udGVzdIIWb3AzOC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A4My53ZWItcGxhdGZvcm0udGVzdIIWb3A4MS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyMC53ZWItcGxhdGZvcm0udGVzdIIWb3AyMS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyMy53ZWItcGxhdGZvcm0udGVzdIIWb3A0Mi53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AyMi53ZWItcGxhdGZvcm0udGVzdIIWb3A2NS53ZWIt
+cGxhdGZvcm0udGVzdIIWb3A5Ni53ZWItcGxhdGZvcm0udGVzdIIWb3A4Ny53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AxOS53ZWItcGxhdGZvcm0udGVzdIIWb3A1My53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzMC53ZWItcGxhdGZvcm0udGVzdIIWb3A0OC53ZWIt
+cGxhdGZvcm0udGVzdIIWb3AzNC53ZWItcGxhdGZvcm0udGVzdIIZb3A2Lm5vdC13
+ZWItcGxhdGZvcm0udGVzdIIZb3AzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3Ay
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A1Lm5vdC13ZWItcGxhdGZvcm0udGVz
+dIIZd3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZd3d3Lnd3dy53ZWItcGxhdGZv
+cm0udGVzdIIZb3A3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A0Lm5vdC13ZWIt
+cGxhdGZvcm0udGVzdIIZb3A4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A5Lm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIZb3AxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3AzNi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTMubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDUwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AyNC5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wMzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDk1
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A4My5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDczLm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3AxOS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjEubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDgxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3A3MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzgubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDQwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AyNS5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wNjUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cu
+d3d3Mi53ZWItcGxhdGZvcm0udGVzdIIab3A4MC5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wNTIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDY4Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3A0NS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzEubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDcyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3A5MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wODkubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDQ5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3Ny5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wNzkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDgy
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3Lnd3dzEud2ViLXBsYXRmb3JtLnRl
+c3SCGm9wMTIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDM5Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3A0NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzEubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3AxNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzAubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDYyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2MS5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wOTIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDI5
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5OC5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wNjQubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDI2Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3AyMi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wOTQubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDM4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3AzMy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjMubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDU3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A1NC5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wODUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQ2
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5Ny5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wMzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDYwLm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3A5Ni5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTEubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3AzNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wOTkubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDQyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2Ny5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wMzcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQ4
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A1NS5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wNTYubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg0Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3AzNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjkubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDExLm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3A5My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzEud3d3LndlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDg2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AxMy5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGm9wMjAubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDc2
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AyNy5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wMTcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDc1Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3AxNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNDcubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIa
+b3A2My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjgubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0ghpvcDQzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2Ni5ub3Qtd2Vi
+LXBsYXRmb3JtLnRlc3SCGnd3dzIud3d3LndlYi1wbGF0Zm9ybS50ZXN0ghpvcDkx
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3NC5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCGm9wNTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg4Lm5vdC13ZWItcGxh
+dGZvcm0udGVzdIIab3A4Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTAubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIb
+d3d3MS53d3cyLndlYi1wbGF0Zm9ybS50ZXN0ght3d3cyLnd3dzIud2ViLXBsYXRm
+b3JtLnRlc3SCG3d3dzIud3d3MS53ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cx
+LndlYi1wbGF0Zm9ybS50ZXN0gh13d3cud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVz
+dIIeeG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0gh53d3cxLnd3dy5ub3Qt
+d2ViLXBsYXRmb3JtLnRlc3SCHnd3dy53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVz
+dIIed3d3Mi53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3MS5ub3Qt
+d2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCH3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3MS5u
+b3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEud3d3Mi5ub3Qtd2ViLXBsYXRmb3Jt
+LnRlc3SCInhuLS1sdmUtNmxhZC53d3cud2ViLXBsYXRmb3JtLnRlc3SCInhuLS1s
+dmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCInd3dy54bi0tbHZlLTZsYWQu
+d2ViLXBsYXRmb3JtLnRlc3SCI3d3dzIueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9y
+bS50ZXN0giN4bi0tbHZlLTZsYWQud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIjeG4t
+LWx2ZS02bGFkLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCI3d3dzEueG4tLWx2ZS02
+bGFkLndlYi1wbGF0Zm9ybS50ZXN0giZ4bi0tbHZlLTZsYWQud3d3Lm5vdC13ZWIt
+cGxhdGZvcm0udGVzdIImd3d3LnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3Jt
+LnRlc3SCJ3huLS1sdmUtNmxhZC53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIn
+d3d3Mi54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gid3d3cxLnhu
+LS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53
+d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIpeG4tLW44ajZkczUzbHd3a3JxaHYy
+OGEud2ViLXBsYXRmb3JtLnRlc3SCK3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQu
+d2ViLXBsYXRmb3JtLnRlc3SCLXd3dy54bi0tbjhqNmRzNTNsd3drcnFodjI4YS53
+ZWItcGxhdGZvcm0udGVzdIIteG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0gi14bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cud2Vi
+LXBsYXRmb3JtLnRlc3SCLnd3dzEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi
+LXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIud2Vi
+LXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzEud2Vi
+LXBsYXRmb3JtLnRlc3SCLnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2Vi
+LXBsYXRmb3JtLnRlc3SCL3huLS1sdmUtNmxhZC54bi0tbHZlLTZsYWQubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0gjF3d3cueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90
+LXdlYi1wbGF0Zm9ybS50ZXN0gjF4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cu
+bm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53
+d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIyd3d3MS54bi0tbjhqNmRzNTNsd3dr
+cnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMnd3dzIueG4tLW44ajZkczUz
+bHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0tbjhqNmRzNTNs
+d3drcnFodjI4YS53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdII2eG4tLW44ajZk
+czUzbHd3a3JxaHYyOGEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0gjZ4
+bi0tbHZlLTZsYWQueG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3Jt
+LnRlc3SCOnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1sdmUtNmxhZC5ub3Qt
+d2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1sdmUtNmxhZC54bi0tbjhqNmRzNTNsd3dr
+cnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCQXhuLS1uOGo2ZHM1M2x3d2ty
+cWh2MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLndlYi1wbGF0Zm9ybS50ZXN0
+gkV4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbjhqNmRzNTNsd3drcnFodjI4
+YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwDQYJKoZIhvcNAQELBQADggEBAHjDIDWw
+i7O1qdt/nBYLqerRN8HqAY6CRWENg50zWKGIPCr2lz2vLDfASy4pUH2ZgPVXWCrN
+Nkw2gHUtMYf1KdY6FOVvRvEWbccsUUR/mPDpjxXkbiALo1WHm/h7NSMg4aqyZi8q
+IJfWwVOgxCOYj5AroHguRG5NvyQ0pcvrVAYUN03DvnV0AT4jxzDi6mo9zLkpgmsM
+GLE4LaHgJfkbhuaX2g0tPSee7pJeXAz/2BaGWyPtb0XGTn5GEPLNDlMKuNCVZewX
+k1Ukk3EAUph+VJXTro3qscP4AJRknLLfoM7LIwPgVrN+4bvHA3w0XIlnreQ25dhF
+1Z567hdoFFgoHdY=
+-----END CERTIFICATE-----
diff --git a/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.key b/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.key
index cfaccce4..0d422053 100644
--- a/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.key
+++ b/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.key
@@ -1,28 +1,28 @@
------BEGIN PRIVATE KEY-----

-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/fuYqbJLYKoTw

-FzaunSJ362mpA7BoWOIMiTFkGK1tZAgpz2rvzBD5szNMIrHaJF/DMfHxe2CXsnkD

-XWbc0cuD7NMM4dKbfRbjntxY3WyJd5ijDLJ8btC/PSwZocmHwgpOqB40qG/aLQpN

-wLRxBklh6hrAZMHTsI/AO4IBKMToMYsHS7X7YhdMKg3eq87cgGi/qx1F4qSiAWoF

-30Hm/fiULuKfpAFVfevBPT5hUKDqNyrVxxhM7PUNOW1U0wQxRtgSoAqCY22CpI7W

-gkNhmx2UmrAdNQL4u1V/jPch4mU2QqmLWBGQoHwoRdibiJWaJun9RweDcIqYGwtO

-hIwGt+LjAgMBAAECggEAcDeoH7JSdzSrhJrF45uXqFifKXlM9kkn5pq7A+JmNxWI

-px+yleWrCPjXlcU7Hg90wslQ8+cOGrdurOceMUcMETpGD2WCarXqJOdiTv0q7n/U

-RbBaJAs4buklH7wsgk7WhXOFh+ww59S/FgNYemdpt2Rd2uLwpuHvy4HT1GQUx8/C

-9qhNuu92BNEw5YXZjWlUXsX4/MOhQs6iaEfeGpho20uhURRZlG5kv/zCq9yCX+sa

-O5C504zkZgXojCveahOXeWLrhNnRp1dt3DHVp3cF2fyP0IRb++yw0ZYdvcbyc82s

-BHenjC3vBwng7aA95QehyeLQO3PVVj8QPndVB72aQQKBgQD71yY2tByXzjHgDRaG

-dDDYQtgyVfz4cX+kS+BYWWzuCQo9/UobwucUTmUz1Rc04/quSk/p63ag1vbqxyoG

-pVyV2P6IY5+F3pEklWtfXmy7Anuk8jUgXjgS2+78gxPzy49NweTNTUclLAZJSFkL

-GAB6oXW0taeVRsCZ9ggpv0USoQKBgQDCqJh+Mmtp04zcjRm0gUZmf8ErFXYj6uqr

-rVsGQLn6wRRcc8JrNA4Xblq7rjf7B5D2Ds8IpoPeFoB8Ga+PGe4MQJZdG0UmvQFg

-RXpAiB6O7n4+8oaXSOmFpFL5Jd0/CdGutWG44CwJorbCBYqV8fIF5UaYFGigJEUT

-WrcPQ0PLAwKBgHRXnGvBIURwGVJsOW+71aTSnJYEa21K4bDA7M9j4JLG0lh43vec

-Pqx+2vnrA2GHwJMr+WcTRCZhqIgloiCX3AHN0Sio/VUW0O6ZqJTSRmDOcNhunGRr

-onPz7p/w3hLOg1FktZKylJ9ziyPnrFsXp4D/fiURlm271dZKdtLybbKBAoGASREv

-7G7QkvCttzvfojnES0U5JQrxRZowbDCuMjKpnM5M7kcle0gW4gSyWjCTIs88QqBc

-ZkraxMp9gBfEJlr9V+wGhPxvgJMBqTlrIj31+oDbMpWmn7LmtRtxacQkwDzXUFUV

-UWgUH6nMIBgkZRRkXIIrdXpzq2jx5MnwXPJKyDECgYEA09P2ZweBJE9a9ooKGWoi

-2iRV4GAeIZGUXy1sT/DWM6eUspuFsIE1dak0J5VVKdIce7CV3IpDE8PZ5P0iUfie

-gL170KxfJRkOfI6px4wBWGe/RM0nInWJIIR5oGcifzBx7tVQqKbzNclLUkMOhhg7

-epZdPJJuZSgrixaPo7ymz40=

------END PRIVATE KEY-----

+-----BEGIN PRIVATE KEY-----
+MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQDIC2Z1QbJG1A+y
+gY1nqcGHWaXyNIFx4uwS0h88ayz8kE6c2JEvUqfMYVuC40f1chv63rsruV9Pusn+
+fptnshAyOcbko5R6Hpw5hHFPGztfhmPMn8swt+FO8FpJNCyx0X5bRG6+N/UyQpra
+WsLpuYUNlIUCirZGBLFX6Uwk2gQWzxY9NUSBue8azNm3l6NskbyURReX27SxaKpW
+3Q8Yt3ay0j0QM6DD7KZ4Dvk9zlbLPStFB2lukV3a+M+YpAyG8jYR5Py40ZkJ4RIc
+yWLvel3dERHraxSAU2hTWsScxCli7mMhDbUtoCfkpP4Wh0H2hT5dIc/ATDbO39dJ
+l2vmphtNAgMBAAECggEAHQKKOTbtw5e9LwXam83iYt59UkKLAxkFYzVVkk14mKfU
+vqopY9N4wgrcWn7bUJzbseXa/txDFizgXie+IauQ7bezQDT4szz9KtoqFG6+jXvP
+vTzvGoGQCwKQFU2bra3TxSiHZs52oHNIQaIn4f0lbnK7V0MGa+ECVt1eTXnQXf4o
+M1dkN6NHvizwG9YWZf3EdgVRmSnFl2IoiCkw4kjh76iHD02OgOpMtFEKScirxGbo
+OFZGcQ3nID0rcGlPqA0IeM1LblS8qFH2DlE+I4cDDoLsHIREZaE6BZtttdvGnGo6
+2fNv6U5K/NFVonWXWQF9EIunm509LrIOcfttmOoMAQKBgQD30rrNOfeRxJ1F2Ucf
+1dEY0sI1KHJHkXYITWfsair39CqmObehICUN62vlp7dvcSJQ7H5QNNymbUoSWq5I
+jtUTpNV4GGpGREenx4CrXsJBcosoKX6SGuUrUk/kpvurgGaMphNEMnCjO9oEo6R2
+xPTy1mJN1HhOPrkgOnYyLOS3uQKBgQDOpRonk2i8+WZbmupP+jIiyrq0yudOEDlQ
+vEQxBqLKzCn+fgKFtu+9po5tXmnuweXvDZYPi+fISV1mrlEhdFL+ERt4rVQQexPb
+PdCR8R6Bi/pr7XE5ucAiGXYZPsssNa+5D7YU1wgvBthExHgUEQCdyb7bXlZB4nz8
+xLxjadGiNQKBgCVaV9mTASOxdNsQUs4Tlj6dlbQZcpAi9p1tvVo+7lcNMFh5npnk
+lHEyqMKmstlTPg7gdnF0ZkWXd3CoxlgdXzRkxeAiHfKVXA+H3Hb4A2OF9j+JcZBo
+CV6sO2qFWK2S3uIYLhM7XwrbfJLyb1mPejQX6B0/BxsUDSc0aJhLd/XRAn91Cw7F
+W7j3UEuplxUgN5YuHqWhwUtB6+6KzBfTrO6H7xvaCYVkNzmTMcN6Lv/RPAIAZLGa
+HKQrzWIZxqItULWxMf9dWs9ChnO4ukpoXynoNmCgwNxg1dT9e25o3ig14jKln0CC
+jUkVWcslKCLbOsYemSaBGe3BY4dnpAcQR991AoGAR5F0Q8rd8WleWFDJAOY2t5jR
+oqQ98iH2pQ23fFxwnebnPnyMsX0bG+zXuHtGpEEuFOGc7xqjNTm8MigLcLZ0PAzO
+tscuFcjPG6QwWVjylC2/7+DiAiOHrhsx8jEXMc63Rb9fn3ILH55ZOeZig+A3+ZLk
+pDcbFQ8tKaSChRCy6c0=
+-----END PRIVATE KEY-----
diff --git a/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.pem b/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.pem
index 68a9b96..e7b1b01 100644
--- a/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.pem
+++ b/third_party/blink/web_tests/external/wpt/tools/certs/web-platform.test.pem
@@ -1,239 +1,240 @@
-Certificate:

-    Data:

-        Version: 3 (0x2)

-        Serial Number: 783279 (0xbf3af)

-        Signature Algorithm: sha256WithRSAEncryption

-        Issuer: CN=web-platform-tests

-        Validity

-            Not Before: Feb 18 20:29:47 2020 GMT

-            Not After : Feb 15 20:29:47 2030 GMT

-        Subject: CN=web-platform.test

-        Subject Public Key Info:

-            Public Key Algorithm: rsaEncryption

-                RSA Public-Key: (2048 bit)

-                Modulus:

-                    00:bf:7e:e6:2a:6c:92:d8:2a:84:f0:17:36:ae:9d:

-                    22:77:eb:69:a9:03:b0:68:58:e2:0c:89:31:64:18:

-                    ad:6d:64:08:29:cf:6a:ef:cc:10:f9:b3:33:4c:22:

-                    b1:da:24:5f:c3:31:f1:f1:7b:60:97:b2:79:03:5d:

-                    66:dc:d1:cb:83:ec:d3:0c:e1:d2:9b:7d:16:e3:9e:

-                    dc:58:dd:6c:89:77:98:a3:0c:b2:7c:6e:d0:bf:3d:

-                    2c:19:a1:c9:87:c2:0a:4e:a8:1e:34:a8:6f:da:2d:

-                    0a:4d:c0:b4:71:06:49:61:ea:1a:c0:64:c1:d3:b0:

-                    8f:c0:3b:82:01:28:c4:e8:31:8b:07:4b:b5:fb:62:

-                    17:4c:2a:0d:de:ab:ce:dc:80:68:bf:ab:1d:45:e2:

-                    a4:a2:01:6a:05:df:41:e6:fd:f8:94:2e:e2:9f:a4:

-                    01:55:7d:eb:c1:3d:3e:61:50:a0:ea:37:2a:d5:c7:

-                    18:4c:ec:f5:0d:39:6d:54:d3:04:31:46:d8:12:a0:

-                    0a:82:63:6d:82:a4:8e:d6:82:43:61:9b:1d:94:9a:

-                    b0:1d:35:02:f8:bb:55:7f:8c:f7:21:e2:65:36:42:

-                    a9:8b:58:11:90:a0:7c:28:45:d8:9b:88:95:9a:26:

-                    e9:fd:47:07:83:70:8a:98:1b:0b:4e:84:8c:06:b7:

-                    e2:e3

-                Exponent: 65537 (0x10001)

-        X509v3 extensions:

-            X509v3 Basic Constraints: 

-                CA:FALSE

-            X509v3 Subject Key Identifier: 

-                AE:D8:2F:99:BA:B1:E8:03:D2:A5:C5:2C:0D:BB:16:5C:9B:9F:F7:08

-            X509v3 Authority Key Identifier: 

-                keyid:F6:B9:DA:16:07:05:BB:6F:C9:63:30:C6:67:40:CB:03:D3:1E:90:EC

-

-            X509v3 Key Usage: 

-                Digital Signature, Non Repudiation, Key Encipherment

-            X509v3 Extended Key Usage: 

-                TLS Web Server Authentication

-            X509v3 Subject Alternative Name: 

-                DNS:web-platform.test, DNS:op2.web-platform.test, DNS:op9.web-platform.test, DNS:op7.web-platform.test, DNS:op1.web-platform.test, DNS:op3.web-platform.test, DNS:op6.web-platform.test, DNS:not-web-platform.test, DNS:op5.web-platform.test, DNS:op4.web-platform.test, DNS:op8.web-platform.test, DNS:www.web-platform.test, DNS:op87.web-platform.test, DNS:op80.web-platform.test, DNS:op94.web-platform.test, DNS:op16.web-platform.test, DNS:op40.web-platform.test, DNS:op17.web-platform.test, DNS:op72.web-platform.test, DNS:op64.web-platform.test, DNS:op23.web-platform.test, DNS:op28.web-platform.test, DNS:op13.web-platform.test, DNS:op36.web-platform.test, DNS:op11.web-platform.test, DNS:op79.web-platform.test, DNS:op61.web-platform.test, DNS:op48.web-platform.test, DNS:op19.web-platform.test, DNS:op42.web-platform.test, DNS:op46.web-platform.test, DNS:op37.web-platform.test, DNS:op98.web-platform.test, DNS:op66.web-platform.test, DNS:www1.web-platform.test, DNS:op26.web-platform.test, DNS:op67.web-platform.test, DNS:op73.web-platform.test, DNS:op38.web-platform.test, DNS:op62.web-platform.test, DNS:op58.web-platform.test, DNS:op56.web-platform.test, DNS:op22.web-platform.test, DNS:op24.web-platform.test, DNS:www2.web-platform.test, DNS:op18.web-platform.test, DNS:op74.web-platform.test, DNS:op91.web-platform.test, DNS:op33.web-platform.test, DNS:op69.web-platform.test, DNS:op30.web-platform.test, DNS:op39.web-platform.test, DNS:op52.web-platform.test, DNS:op43.web-platform.test, DNS:op85.web-platform.test, DNS:op34.web-platform.test, DNS:op21.web-platform.test, DNS:op71.web-platform.test, DNS:op50.web-platform.test, DNS:op84.web-platform.test, DNS:op31.web-platform.test, DNS:op54.web-platform.test, DNS:op49.web-platform.test, DNS:op44.web-platform.test, DNS:op45.web-platform.test, DNS:op35.web-platform.test, DNS:op76.web-platform.test, DNS:op14.web-platform.test, DNS:op81.web-platform.test, DNS:op88.web-platform.test, DNS:op20.web-platform.test, DNS:op95.web-platform.test, DNS:op51.web-platform.test, DNS:op86.web-platform.test, DNS:op55.web-platform.test, DNS:op27.web-platform.test, DNS:op12.web-platform.test, DNS:op75.web-platform.test, DNS:op47.web-platform.test, DNS:op96.web-platform.test, DNS:op93.web-platform.test, DNS:op57.web-platform.test, DNS:op63.web-platform.test, DNS:op53.web-platform.test, DNS:op29.web-platform.test, DNS:op25.web-platform.test, DNS:op83.web-platform.test, DNS:op97.web-platform.test, DNS:op41.web-platform.test, DNS:op32.web-platform.test, DNS:op70.web-platform.test, DNS:op60.web-platform.test, DNS:op92.web-platform.test, DNS:op78.web-platform.test, DNS:op89.web-platform.test, DNS:op10.web-platform.test, DNS:op77.web-platform.test, DNS:op59.web-platform.test, DNS:op15.web-platform.test, DNS:op65.web-platform.test, DNS:op68.web-platform.test, DNS:op90.web-platform.test, DNS:op82.web-platform.test, DNS:op6.not-web-platform.test, DNS:op8.not-web-platform.test, DNS:op9.not-web-platform.test, DNS:op4.not-web-platform.test, DNS:op7.not-web-platform.test, DNS:www.www.web-platform.test, DNS:op2.not-web-platform.test, DNS:op1.not-web-platform.test, DNS:www.not-web-platform.test, DNS:op5.not-web-platform.test, DNS:op3.not-web-platform.test, DNS:op27.not-web-platform.test, DNS:op40.not-web-platform.test, DNS:op45.not-web-platform.test, DNS:op96.not-web-platform.test, DNS:op28.not-web-platform.test, DNS:op83.not-web-platform.test, DNS:op33.not-web-platform.test, DNS:op56.not-web-platform.test, DNS:www1.not-web-platform.test, DNS:op62.not-web-platform.test, DNS:op18.not-web-platform.test, DNS:op48.not-web-platform.test, DNS:op43.not-web-platform.test, DNS:op89.not-web-platform.test, DNS:op60.not-web-platform.test, DNS:op95.not-web-platform.test, DNS:op73.not-web-platform.test, DNS:op91.not-web-platform.test, DNS:op42.not-web-platform.test, DNS:op26.not-web-platform.test, DNS:op69.not-web-platform.test, DNS:op32.not-web-platform.test, DNS:op37.not-web-platform.test, DNS:op98.not-web-platform.test, DNS:op19.not-web-platform.test, DNS:op76.not-web-platform.test, DNS:op13.not-web-platform.test, DNS:op79.not-web-platform.test, DNS:www2.www.web-platform.test, DNS:op86.not-web-platform.test, DNS:op77.not-web-platform.test, DNS:op29.not-web-platform.test, DNS:op55.not-web-platform.test, DNS:op92.not-web-platform.test, DNS:op44.not-web-platform.test, DNS:op54.not-web-platform.test, DNS:op94.not-web-platform.test, DNS:op34.not-web-platform.test, DNS:op30.not-web-platform.test, DNS:www1.www.web-platform.test, DNS:op25.not-web-platform.test, DNS:op64.not-web-platform.test, DNS:op20.not-web-platform.test, DNS:op51.not-web-platform.test, DNS:op41.not-web-platform.test, DNS:op12.not-web-platform.test, DNS:op10.not-web-platform.test, DNS:op72.not-web-platform.test, DNS:op22.not-web-platform.test, DNS:op52.not-web-platform.test, DNS:op74.not-web-platform.test, DNS:op67.not-web-platform.test, DNS:op80.not-web-platform.test, DNS:op84.not-web-platform.test, DNS:op31.not-web-platform.test, DNS:op53.not-web-platform.test, DNS:op23.not-web-platform.test, DNS:op35.not-web-platform.test, DNS:op16.not-web-platform.test, DNS:op63.not-web-platform.test, DNS:op38.not-web-platform.test, DNS:op58.not-web-platform.test, DNS:op61.not-web-platform.test, DNS:op14.not-web-platform.test, DNS:op90.not-web-platform.test, DNS:op70.not-web-platform.test, DNS:op11.not-web-platform.test, DNS:op15.not-web-platform.test, DNS:op65.not-web-platform.test, DNS:op50.not-web-platform.test, DNS:op68.not-web-platform.test, DNS:op87.not-web-platform.test, DNS:op78.not-web-platform.test, DNS:www.www2.web-platform.test, DNS:op82.not-web-platform.test, DNS:op93.not-web-platform.test, DNS:www.www1.web-platform.test, DNS:op21.not-web-platform.test, DNS:op71.not-web-platform.test, DNS:op97.not-web-platform.test, DNS:op88.not-web-platform.test, DNS:op24.not-web-platform.test, DNS:op66.not-web-platform.test, DNS:op49.not-web-platform.test, DNS:op59.not-web-platform.test, DNS:op46.not-web-platform.test, DNS:op36.not-web-platform.test, DNS:op39.not-web-platform.test, DNS:op47.not-web-platform.test, DNS:op17.not-web-platform.test, DNS:op75.not-web-platform.test, DNS:op85.not-web-platform.test, DNS:op57.not-web-platform.test, DNS:www2.not-web-platform.test, DNS:op81.not-web-platform.test, DNS:www2.www1.web-platform.test, DNS:www1.www2.web-platform.test, DNS:www2.www2.web-platform.test, DNS:www1.www1.web-platform.test, DNS:www.www.not-web-platform.test, DNS:www2.www.not-web-platform.test, DNS:xn--lve-6lad.web-platform.test, DNS:www1.www.not-web-platform.test, DNS:www.www1.not-web-platform.test, DNS:www.www2.not-web-platform.test, DNS:www1.www2.not-web-platform.test, DNS:www1.www1.not-web-platform.test, DNS:www2.www1.not-web-platform.test, DNS:www2.www2.not-web-platform.test, DNS:xn--lve-6lad.www.web-platform.test, DNS:xn--lve-6lad.not-web-platform.test, DNS:www.xn--lve-6lad.web-platform.test, DNS:www1.xn--lve-6lad.web-platform.test, DNS:www2.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www2.web-platform.test, DNS:xn--lve-6lad.www1.web-platform.test, DNS:www.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www.not-web-platform.test, DNS:www1.xn--lve-6lad.not-web-platform.test, DNS:www2.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www1.not-web-platform.test, DNS:xn--lve-6lad.www2.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.not-web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.not-web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test

-    Signature Algorithm: sha256WithRSAEncryption

-         89:a4:44:43:ef:0f:a6:36:72:31:87:44:75:86:b6:5b:58:2c:

-         cb:1c:0a:2e:35:32:83:80:70:70:1c:b7:4a:d1:45:44:78:c4:

-         17:d8:77:34:4e:42:d2:72:22:fe:0d:0a:ae:b8:06:94:d0:6d:

-         7a:21:d8:a4:83:33:17:d3:04:a8:93:6f:66:f0:33:19:05:07:

-         b5:35:83:28:a9:8f:85:18:1a:86:df:e8:be:8d:cf:6a:24:c1:

-         08:26:dd:02:98:1c:01:d8:81:4a:e4:20:14:19:7c:ef:91:b5:

-         3e:da:5a:f6:14:45:18:7d:45:4b:28:76:33:58:c5:8c:c9:2d:

-         ef:89:11:70:7d:eb:47:9e:12:b0:81:19:c8:07:d9:cc:87:f1:

-         1b:fe:f0:8f:b2:c3:f1:da:f0:55:e5:4a:9b:ff:0d:01:5f:65:

-         95:07:92:c6:7b:73:95:59:aa:6b:c6:9c:01:4e:a2:2b:ea:77:

-         d4:f4:ab:d6:e5:94:eb:81:37:55:9c:90:3f:73:23:1d:84:c2:

-         82:42:56:9a:13:69:33:48:d6:0d:0e:58:82:ac:90:ef:b3:a0:

-         6c:de:79:f6:17:c5:f0:1e:f3:37:74:01:f0:47:9c:77:9c:a7:

-         af:e0:60:ca:d7:02:dd:50:48:69:b1:1b:83:87:5a:7c:74:44:

-         da:c5:de:b8

------BEGIN CERTIFICATE-----

-MIIgiDCCH3CgAwIBAgIDC/OvMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl

-Yi1wbGF0Zm9ybS10ZXN0czAeFw0yMDAyMTgyMDI5NDdaFw0zMDAyMTUyMDI5NDda

-MBwxGjAYBgNVBAMMEXdlYi1wbGF0Zm9ybS50ZXN0MIIBIjANBgkqhkiG9w0BAQEF

-AAOCAQ8AMIIBCgKCAQEAv37mKmyS2CqE8Bc2rp0id+tpqQOwaFjiDIkxZBitbWQI

-Kc9q78wQ+bMzTCKx2iRfwzHx8Xtgl7J5A11m3NHLg+zTDOHSm30W457cWN1siXeY

-owyyfG7Qvz0sGaHJh8IKTqgeNKhv2i0KTcC0cQZJYeoawGTB07CPwDuCASjE6DGL

-B0u1+2IXTCoN3qvO3IBov6sdReKkogFqBd9B5v34lC7in6QBVX3rwT0+YVCg6jcq

-1ccYTOz1DTltVNMEMUbYEqAKgmNtgqSO1oJDYZsdlJqwHTUC+LtVf4z3IeJlNkKp

-i1gRkKB8KEXYm4iVmibp/UcHg3CKmBsLToSMBrfi4wIDAQABo4Id0DCCHcwwCQYD

-VR0TBAIwADAdBgNVHQ4EFgQUrtgvmbqx6APSpcUsDbsWXJuf9wgwHwYDVR0jBBgw

-FoAU9rnaFgcFu2/JYzDGZ0DLA9MekOwwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoG

-CCsGAQUFBwMBMIIdWwYDVR0RBIIdUjCCHU6CEXdlYi1wbGF0Zm9ybS50ZXN0ghVv

-cDIud2ViLXBsYXRmb3JtLnRlc3SCFW9wOS53ZWItcGxhdGZvcm0udGVzdIIVb3A3

-LndlYi1wbGF0Zm9ybS50ZXN0ghVvcDEud2ViLXBsYXRmb3JtLnRlc3SCFW9wMy53

-ZWItcGxhdGZvcm0udGVzdIIVb3A2LndlYi1wbGF0Zm9ybS50ZXN0ghVub3Qtd2Vi

-LXBsYXRmb3JtLnRlc3SCFW9wNS53ZWItcGxhdGZvcm0udGVzdIIVb3A0LndlYi1w

-bGF0Zm9ybS50ZXN0ghVvcDgud2ViLXBsYXRmb3JtLnRlc3SCFXd3dy53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A4MC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A5NC53ZWItcGxhdGZvcm0udGVzdIIWb3AxNi53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0MC53ZWItcGxhdGZvcm0udGVzdIIWb3AxNy53ZWItcGxh

-dGZvcm0udGVzdIIWb3A3Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A2NC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AyMy53ZWItcGxhdGZvcm0udGVzdIIWb3AyOC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AxMy53ZWItcGxhdGZvcm0udGVzdIIWb3AzNi53ZWItcGxh

-dGZvcm0udGVzdIIWb3AxMS53ZWItcGxhdGZvcm0udGVzdIIWb3A3OS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A2MS53ZWItcGxhdGZvcm0udGVzdIIWb3A0OC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AxOS53ZWItcGxhdGZvcm0udGVzdIIWb3A0Mi53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0Ni53ZWItcGxhdGZvcm0udGVzdIIWb3AzNy53ZWItcGxh

-dGZvcm0udGVzdIIWb3A5OC53ZWItcGxhdGZvcm0udGVzdIIWb3A2Ni53ZWItcGxh

-dGZvcm0udGVzdIIWd3d3MS53ZWItcGxhdGZvcm0udGVzdIIWb3AyNi53ZWItcGxh

-dGZvcm0udGVzdIIWb3A2Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A3My53ZWItcGxh

-dGZvcm0udGVzdIIWb3AzOC53ZWItcGxhdGZvcm0udGVzdIIWb3A2Mi53ZWItcGxh

-dGZvcm0udGVzdIIWb3A1OC53ZWItcGxhdGZvcm0udGVzdIIWb3A1Ni53ZWItcGxh

-dGZvcm0udGVzdIIWb3AyMi53ZWItcGxhdGZvcm0udGVzdIIWb3AyNC53ZWItcGxh

-dGZvcm0udGVzdIIWd3d3Mi53ZWItcGxhdGZvcm0udGVzdIIWb3AxOC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A3NC53ZWItcGxhdGZvcm0udGVzdIIWb3A5MS53ZWItcGxh

-dGZvcm0udGVzdIIWb3AzMy53ZWItcGxhdGZvcm0udGVzdIIWb3A2OS53ZWItcGxh

-dGZvcm0udGVzdIIWb3AzMC53ZWItcGxhdGZvcm0udGVzdIIWb3AzOS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A1Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A0My53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4NS53ZWItcGxhdGZvcm0udGVzdIIWb3AzNC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AyMS53ZWItcGxhdGZvcm0udGVzdIIWb3A3MS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A1MC53ZWItcGxhdGZvcm0udGVzdIIWb3A4NC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AzMS53ZWItcGxhdGZvcm0udGVzdIIWb3A1NC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0OS53ZWItcGxhdGZvcm0udGVzdIIWb3A0NC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0NS53ZWItcGxhdGZvcm0udGVzdIIWb3AzNS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A3Ni53ZWItcGxhdGZvcm0udGVzdIIWb3AxNC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4MS53ZWItcGxhdGZvcm0udGVzdIIWb3A4OC53ZWItcGxh

-dGZvcm0udGVzdIIWb3AyMC53ZWItcGxhdGZvcm0udGVzdIIWb3A5NS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A1MS53ZWItcGxhdGZvcm0udGVzdIIWb3A4Ni53ZWItcGxh

-dGZvcm0udGVzdIIWb3A1NS53ZWItcGxhdGZvcm0udGVzdIIWb3AyNy53ZWItcGxh

-dGZvcm0udGVzdIIWb3AxMi53ZWItcGxhdGZvcm0udGVzdIIWb3A3NS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A5Ni53ZWItcGxh

-dGZvcm0udGVzdIIWb3A5My53ZWItcGxhdGZvcm0udGVzdIIWb3A1Ny53ZWItcGxh

-dGZvcm0udGVzdIIWb3A2My53ZWItcGxhdGZvcm0udGVzdIIWb3A1My53ZWItcGxh

-dGZvcm0udGVzdIIWb3AyOS53ZWItcGxhdGZvcm0udGVzdIIWb3AyNS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4My53ZWItcGxhdGZvcm0udGVzdIIWb3A5Ny53ZWItcGxh

-dGZvcm0udGVzdIIWb3A0MS53ZWItcGxhdGZvcm0udGVzdIIWb3AzMi53ZWItcGxh

-dGZvcm0udGVzdIIWb3A3MC53ZWItcGxhdGZvcm0udGVzdIIWb3A2MC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A5Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A3OC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4OS53ZWItcGxhdGZvcm0udGVzdIIWb3AxMC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A3Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A1OS53ZWItcGxh

-dGZvcm0udGVzdIIWb3AxNS53ZWItcGxhdGZvcm0udGVzdIIWb3A2NS53ZWItcGxh

-dGZvcm0udGVzdIIWb3A2OC53ZWItcGxhdGZvcm0udGVzdIIWb3A5MC53ZWItcGxh

-dGZvcm0udGVzdIIWb3A4Mi53ZWItcGxhdGZvcm0udGVzdIIZb3A2Lm5vdC13ZWIt

-cGxhdGZvcm0udGVzdIIZb3A4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A5Lm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIZb3A0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZ

-b3A3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZd3d3Lnd3dy53ZWItcGxhdGZvcm0u

-dGVzdIIZb3AyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3AxLm5vdC13ZWItcGxh

-dGZvcm0udGVzdIIZd3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A1Lm5vdC13

-ZWItcGxhdGZvcm0udGVzdIIZb3AzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3Ay

-Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNDAubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDQ1Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5Ni5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGm9wMjgubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDgzLm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3AzMy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wNTYubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghp3d3cxLm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3A2Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTgubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDQ4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0

-My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wODkubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDYwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5NS5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGm9wNzMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDkxLm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3A0Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wMjYubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDY5Lm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3AzMi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzcubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDk4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3Ax

-OS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzYubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDEzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3OS5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGnd3dzIud3d3LndlYi1wbGF0Zm9ybS50ZXN0ghpvcDg2Lm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3A3Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wMjkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU1Lm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3A5Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNDQubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDU0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5

-NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzQubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDMwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3MS53d3cud2ViLXBs

-YXRmb3JtLnRlc3SCGm9wMjUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDY0Lm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3AyMC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wNTEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQxLm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3AxMi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTAubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDcyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3Ay

-Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTIubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDc0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A2Ny5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGm9wODAubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg0Lm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3AzMS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wNTMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDIzLm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3AzNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTYubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDYzLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3Az

-OC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTgubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDYxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AxNC5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGm9wOTAubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDcwLm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3AxMS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wMTUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDY1Lm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3A1MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjgubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDg3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3

-OC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dy53d3cyLndlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDgyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5My5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGnd3dy53d3cxLndlYi1wbGF0Zm9ybS50ZXN0ghpvcDIxLm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3A3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wOTcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDg4Lm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIab3AyNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjYubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ghpvcDQ5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A1

-OS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNDYubm90LXdlYi1wbGF0Zm9ybS50

-ZXN0ghpvcDM2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AzOS5ub3Qtd2ViLXBs

-YXRmb3JtLnRlc3SCGm9wNDcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE3Lm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIab3A3NS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC

-Gm9wODUubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU3Lm5vdC13ZWItcGxhdGZv

-cm0udGVzdIIad3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wODEubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0ght3d3cyLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCG3d3

-dzEud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIbd3d3Mi53d3cyLndlYi1wbGF0Zm9y

-bS50ZXN0ght3d3cxLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCHXd3dy53d3cubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cyLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCHnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIed3d3MS53d3cubm90

-LXdlYi1wbGF0Zm9ybS50ZXN0gh53d3cud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCHnd3dy53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIfd3d3MS53d3cyLm5v

-dC13ZWItcGxhdGZvcm0udGVzdIIfd3d3MS53d3cxLm5vdC13ZWItcGxhdGZvcm0u

-dGVzdIIfd3d3Mi53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIfd3d3Mi53d3cy

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIieG4tLWx2ZS02bGFkLnd3dy53ZWItcGxh

-dGZvcm0udGVzdIIieG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIIi

-d3d3LnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIjd3d3MS54bi0tbHZl

-LTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCI3d3dzIueG4tLWx2ZS02bGFkLndlYi1w

-bGF0Zm9ybS50ZXN0giN4bi0tbHZlLTZsYWQud3d3Mi53ZWItcGxhdGZvcm0udGVz

-dIIjeG4tLWx2ZS02bGFkLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCJnd3dy54bi0t

-bHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0giZ4bi0tbHZlLTZsYWQud3d3

-Lm5vdC13ZWItcGxhdGZvcm0udGVzdIInd3d3MS54bi0tbHZlLTZsYWQubm90LXdl

-Yi1wbGF0Zm9ybS50ZXN0gid3d3cyLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRm

-b3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVz

-dIIneG4tLWx2ZS02bGFkLnd3dzIubm90LXdlYi1wbGF0Zm9ybS50ZXN0gil4bi0t

-bjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIreG4tLWx2ZS02

-bGFkLnhuLS1sdmUtNmxhZC53ZWItcGxhdGZvcm0udGVzdIIteG4tLW44ajZkczUz

-bHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gi14bi0tbjhqNmRzNTNs

-d3drcnFodjI4YS53d3cud2ViLXBsYXRmb3JtLnRlc3SCLXd3dy54bi0tbjhqNmRz

-NTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIud3d3Mi54bi0tbjhqNmRz

-NTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIud3d3MS54bi0tbjhqNmRz

-NTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIueG4tLW44ajZkczUzbHd3

-a3JxaHYyOGEud3d3MS53ZWItcGxhdGZvcm0udGVzdIIueG4tLW44ajZkczUzbHd3

-a3JxaHYyOGEud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIveG4tLWx2ZS02bGFkLnhu

-LS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMXhuLS1uOGo2ZHM1M2x3

-d2tycWh2MjhhLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMXd3dy54bi0tbjhq

-NmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCMnd3dzEueG4t

-LW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0t

-bjhqNmRzNTNsd3drcnFodjI4YS53d3cxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIy

-d3d3Mi54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRl

-c3SCMnhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnd3dzIubm90LXdlYi1wbGF0Zm9y

-bS50ZXN0gjZ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54bi0tbHZlLTZsYWQud2Vi

-LXBsYXRmb3JtLnRlc3SCNnhuLS1sdmUtNmxhZC54bi0tbjhqNmRzNTNsd3drcnFo

-djI4YS53ZWItcGxhdGZvcm0udGVzdII6eG4tLWx2ZS02bGFkLnhuLS1uOGo2ZHM1

-M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdII6eG4tLW44ajZkczUz

-bHd3a3JxaHYyOGEueG4tLWx2ZS02bGFkLm5vdC13ZWItcGxhdGZvcm0udGVzdIJB

-eG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4tLW44ajZkczUzbHd3a3JxaHYyOGEu

-d2ViLXBsYXRmb3JtLnRlc3SCRXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1u

-OGo2ZHM1M2x3d2tycWh2MjhhLm5vdC13ZWItcGxhdGZvcm0udGVzdDANBgkqhkiG

-9w0BAQsFAAOCAQEAiaREQ+8PpjZyMYdEdYa2W1gsyxwKLjUyg4BwcBy3StFFRHjE

-F9h3NE5C0nIi/g0KrrgGlNBteiHYpIMzF9MEqJNvZvAzGQUHtTWDKKmPhRgaht/o

-vo3PaiTBCCbdApgcAdiBSuQgFBl875G1Ptpa9hRFGH1FSyh2M1jFjMkt74kRcH3r

-R54SsIEZyAfZzIfxG/7wj7LD8drwVeVKm/8NAV9llQeSxntzlVmqa8acAU6iK+p3

-1PSr1uWU64E3VZyQP3MjHYTCgkJWmhNpM0jWDQ5YgqyQ77OgbN559hfF8B7zN3QB

-8Eecd5ynr+BgytcC3VBIabEbg4dafHRE2sXeuA==

------END CERTIFICATE-----

+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 779096 (0xbe358)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=web-platform-tests
+        Validity
+            Not Before: Jul 30 20:12:48 2020 GMT
+            Not After : Oct  8 20:12:48 2022 GMT
+        Subject: CN=web-platform.test
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c8:0b:66:75:41:b2:46:d4:0f:b2:81:8d:67:a9:
+                    c1:87:59:a5:f2:34:81:71:e2:ec:12:d2:1f:3c:6b:
+                    2c:fc:90:4e:9c:d8:91:2f:52:a7:cc:61:5b:82:e3:
+                    47:f5:72:1b:fa:de:bb:2b:b9:5f:4f:ba:c9:fe:7e:
+                    9b:67:b2:10:32:39:c6:e4:a3:94:7a:1e:9c:39:84:
+                    71:4f:1b:3b:5f:86:63:cc:9f:cb:30:b7:e1:4e:f0:
+                    5a:49:34:2c:b1:d1:7e:5b:44:6e:be:37:f5:32:42:
+                    9a:da:5a:c2:e9:b9:85:0d:94:85:02:8a:b6:46:04:
+                    b1:57:e9:4c:24:da:04:16:cf:16:3d:35:44:81:b9:
+                    ef:1a:cc:d9:b7:97:a3:6c:91:bc:94:45:17:97:db:
+                    b4:b1:68:aa:56:dd:0f:18:b7:76:b2:d2:3d:10:33:
+                    a0:c3:ec:a6:78:0e:f9:3d:ce:56:cb:3d:2b:45:07:
+                    69:6e:91:5d:da:f8:cf:98:a4:0c:86:f2:36:11:e4:
+                    fc:b8:d1:99:09:e1:12:1c:c9:62:ef:7a:5d:dd:11:
+                    11:eb:6b:14:80:53:68:53:5a:c4:9c:c4:29:62:ee:
+                    63:21:0d:b5:2d:a0:27:e4:a4:fe:16:87:41:f6:85:
+                    3e:5d:21:cf:c0:4c:36:ce:df:d7:49:97:6b:e6:a6:
+                    1b:4d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            X509v3 Subject Key Identifier: 
+                D4:78:96:D1:22:40:93:76:CE:17:EB:B6:70:B6:09:05:E0:A3:17:F8
+            X509v3 Authority Key Identifier: 
+                keyid:B3:75:DD:A0:9B:F2:5A:FE:17:8D:80:B1:FC:A7:B7:C1:2B:79:29:2B
+
+            X509v3 Key Usage: 
+                Digital Signature, Non Repudiation, Key Encipherment
+            X509v3 Extended Key Usage: 
+                TLS Web Server Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:web-platform.test, DNS:op8.web-platform.test, DNS:op7.web-platform.test, DNS:op9.web-platform.test, DNS:op4.web-platform.test, DNS:not-web-platform.test, DNS:op6.web-platform.test, DNS:op3.web-platform.test, DNS:op2.web-platform.test, DNS:op1.web-platform.test, DNS:www.web-platform.test, DNS:op5.web-platform.test, DNS:op88.web-platform.test, DNS:op98.web-platform.test, DNS:op85.web-platform.test, DNS:op89.web-platform.test, DNS:op66.web-platform.test, DNS:op72.web-platform.test, DNS:op24.web-platform.test, DNS:op41.web-platform.test, DNS:op79.web-platform.test, DNS:op91.web-platform.test, DNS:op59.web-platform.test, DNS:op39.web-platform.test, DNS:op60.web-platform.test, DNS:op58.web-platform.test, DNS:op28.web-platform.test, DNS:www1.web-platform.test, DNS:op14.web-platform.test, DNS:op69.web-platform.test, DNS:op40.web-platform.test, DNS:op74.web-platform.test, DNS:op31.web-platform.test, DNS:op18.web-platform.test, DNS:op73.web-platform.test, DNS:op77.web-platform.test, DNS:op12.web-platform.test, DNS:op54.web-platform.test, DNS:op63.web-platform.test, DNS:op71.web-platform.test, DNS:op95.web-platform.test, DNS:op16.web-platform.test, DNS:op36.web-platform.test, DNS:op27.web-platform.test, DNS:op29.web-platform.test, DNS:op94.web-platform.test, DNS:op44.web-platform.test, DNS:op33.web-platform.test, DNS:op84.web-platform.test, DNS:op32.web-platform.test, DNS:op61.web-platform.test, DNS:op70.web-platform.test, DNS:www2.web-platform.test, DNS:op43.web-platform.test, DNS:op78.web-platform.test, DNS:op26.web-platform.test, DNS:op76.web-platform.test, DNS:op52.web-platform.test, DNS:op99.web-platform.test, DNS:op86.web-platform.test, DNS:op46.web-platform.test, DNS:op17.web-platform.test, DNS:op90.web-platform.test, DNS:op93.web-platform.test, DNS:op10.web-platform.test, DNS:op55.web-platform.test, DNS:op47.web-platform.test, DNS:op51.web-platform.test, DNS:op45.web-platform.test, DNS:op80.web-platform.test, DNS:op68.web-platform.test, DNS:op49.web-platform.test, DNS:op57.web-platform.test, DNS:op35.web-platform.test, DNS:op67.web-platform.test, DNS:op92.web-platform.test, DNS:op15.web-platform.test, DNS:op13.web-platform.test, DNS:op75.web-platform.test, DNS:op64.web-platform.test, DNS:op97.web-platform.test, DNS:op37.web-platform.test, DNS:op56.web-platform.test, DNS:op62.web-platform.test, DNS:op82.web-platform.test, DNS:op25.web-platform.test, DNS:op11.web-platform.test, DNS:op50.web-platform.test, DNS:op38.web-platform.test, DNS:op83.web-platform.test, DNS:op81.web-platform.test, DNS:op20.web-platform.test, DNS:op21.web-platform.test, DNS:op23.web-platform.test, DNS:op42.web-platform.test, DNS:op22.web-platform.test, DNS:op65.web-platform.test, DNS:op96.web-platform.test, DNS:op87.web-platform.test, DNS:op19.web-platform.test, DNS:op53.web-platform.test, DNS:op30.web-platform.test, DNS:op48.web-platform.test, DNS:op34.web-platform.test, DNS:op6.not-web-platform.test, DNS:op3.not-web-platform.test, DNS:op2.not-web-platform.test, DNS:op5.not-web-platform.test, DNS:www.not-web-platform.test, DNS:www.www.web-platform.test, DNS:op7.not-web-platform.test, DNS:op4.not-web-platform.test, DNS:op8.not-web-platform.test, DNS:op9.not-web-platform.test, DNS:op1.not-web-platform.test, DNS:op36.not-web-platform.test, DNS:op53.not-web-platform.test, DNS:op50.not-web-platform.test, DNS:op24.not-web-platform.test, DNS:op31.not-web-platform.test, DNS:op95.not-web-platform.test, DNS:op83.not-web-platform.test, DNS:www2.not-web-platform.test, DNS:op73.not-web-platform.test, DNS:op19.not-web-platform.test, DNS:op21.not-web-platform.test, DNS:op81.not-web-platform.test, DNS:op70.not-web-platform.test, DNS:op78.not-web-platform.test, DNS:op40.not-web-platform.test, DNS:op25.not-web-platform.test, DNS:op65.not-web-platform.test, DNS:www.www2.web-platform.test, DNS:op80.not-web-platform.test, DNS:op52.not-web-platform.test, DNS:op68.not-web-platform.test, DNS:op45.not-web-platform.test, DNS:op71.not-web-platform.test, DNS:op72.not-web-platform.test, DNS:op90.not-web-platform.test, DNS:op89.not-web-platform.test, DNS:op49.not-web-platform.test, DNS:op77.not-web-platform.test, DNS:op79.not-web-platform.test, DNS:op82.not-web-platform.test, DNS:www.www1.web-platform.test, DNS:op12.not-web-platform.test, DNS:op39.not-web-platform.test, DNS:op44.not-web-platform.test, DNS:www1.not-web-platform.test, DNS:op58.not-web-platform.test, DNS:op14.not-web-platform.test, DNS:op30.not-web-platform.test, DNS:op62.not-web-platform.test, DNS:op61.not-web-platform.test, DNS:op92.not-web-platform.test, DNS:op29.not-web-platform.test, DNS:op98.not-web-platform.test, DNS:op64.not-web-platform.test, DNS:op26.not-web-platform.test, DNS:op22.not-web-platform.test, DNS:op94.not-web-platform.test, DNS:op38.not-web-platform.test, DNS:op33.not-web-platform.test, DNS:op23.not-web-platform.test, DNS:op57.not-web-platform.test, DNS:op54.not-web-platform.test, DNS:op85.not-web-platform.test, DNS:op46.not-web-platform.test, DNS:op97.not-web-platform.test, DNS:op32.not-web-platform.test, DNS:op60.not-web-platform.test, DNS:op96.not-web-platform.test, DNS:op51.not-web-platform.test, DNS:op41.not-web-platform.test, DNS:op35.not-web-platform.test, DNS:op99.not-web-platform.test, DNS:op42.not-web-platform.test, DNS:op67.not-web-platform.test, DNS:op37.not-web-platform.test, DNS:op48.not-web-platform.test, DNS:op55.not-web-platform.test, DNS:op56.not-web-platform.test, DNS:op84.not-web-platform.test, DNS:op34.not-web-platform.test, DNS:op69.not-web-platform.test, DNS:op11.not-web-platform.test, DNS:op93.not-web-platform.test, DNS:www1.www.web-platform.test, DNS:op86.not-web-platform.test, DNS:op13.not-web-platform.test, DNS:op20.not-web-platform.test, DNS:op76.not-web-platform.test, DNS:op27.not-web-platform.test, DNS:op17.not-web-platform.test, DNS:op75.not-web-platform.test, DNS:op15.not-web-platform.test, DNS:op47.not-web-platform.test, DNS:op18.not-web-platform.test, DNS:op63.not-web-platform.test, DNS:op28.not-web-platform.test, DNS:op43.not-web-platform.test, DNS:op66.not-web-platform.test, DNS:www2.www.web-platform.test, DNS:op91.not-web-platform.test, DNS:op74.not-web-platform.test, DNS:op59.not-web-platform.test, DNS:op88.not-web-platform.test, DNS:op87.not-web-platform.test, DNS:op10.not-web-platform.test, DNS:op16.not-web-platform.test, DNS:www1.www2.web-platform.test, DNS:www2.www2.web-platform.test, DNS:www2.www1.web-platform.test, DNS:www1.www1.web-platform.test, DNS:www.www.not-web-platform.test, DNS:xn--lve-6lad.web-platform.test, DNS:www1.www.not-web-platform.test, DNS:www.www2.not-web-platform.test, DNS:www2.www.not-web-platform.test, DNS:www.www1.not-web-platform.test, DNS:www2.www2.not-web-platform.test, DNS:www2.www1.not-web-platform.test, DNS:www1.www1.not-web-platform.test, DNS:www1.www2.not-web-platform.test, DNS:xn--lve-6lad.www.web-platform.test, DNS:xn--lve-6lad.not-web-platform.test, DNS:www.xn--lve-6lad.web-platform.test, DNS:www2.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www2.web-platform.test, DNS:xn--lve-6lad.www1.web-platform.test, DNS:www1.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.www.not-web-platform.test, DNS:www.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www1.not-web-platform.test, DNS:www2.xn--lve-6lad.not-web-platform.test, DNS:www1.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.www2.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--lve-6lad.xn--lve-6lad.not-web-platform.test, DNS:www.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www2.not-web-platform.test, DNS:www1.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:www2.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.www1.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--lve-6lad.not-web-platform.test, DNS:xn--lve-6lad.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.web-platform.test, DNS:xn--n8j6ds53lwwkrqhv28a.xn--n8j6ds53lwwkrqhv28a.not-web-platform.test
+    Signature Algorithm: sha256WithRSAEncryption
+         87:1a:f7:82:48:e1:85:0a:cd:c9:eb:26:3a:f0:d2:70:1e:cc:
+         1e:1e:8f:61:ed:41:a5:72:4c:0b:dd:7f:9f:6d:eb:f6:96:6c:
+         f5:41:3d:78:6e:69:74:bb:49:d4:d1:8b:e1:5f:c9:1e:43:7f:
+         19:6b:db:fe:37:52:d7:3a:88:a9:29:df:64:63:ae:82:2d:e1:
+         8f:19:10:13:8a:73:c6:8d:ae:ca:99:50:89:49:90:a5:4f:cf:
+         ec:13:5b:2f:eb:dc:a0:d2:53:15:1a:d1:93:4c:47:f0:9b:6f:
+         65:1a:51:e2:4b:73:56:de:57:2a:11:ad:5a:68:92:ad:36:be:
+         b8:f5:b9:72:28:b8:ec:d7:55:d1:0d:e1:40:27:b9:e4:2b:c0:
+         de:a1:e9:38:25:4e:b6:43:dc:1a:0b:38:96:2b:14:5f:88:1a:
+         75:92:fc:bf:76:3a:23:96:37:7f:f4:83:62:8e:fd:5f:29:06:
+         0c:52:2b:e5:23:95:9b:0f:b0:1e:1a:bb:99:b4:3c:1b:83:c9:
+         4d:f5:b7:2c:6b:98:fa:67:48:63:8a:9e:1e:6c:ef:cb:d4:eb:
+         82:a8:49:21:68:a2:d1:34:35:b0:9b:ef:a8:51:22:8b:3a:fd:
+         87:8e:5a:d6:1f:b2:1c:64:c3:10:e2:7d:b6:c9:ce:27:97:16:
+         1a:a6:66:4f
+-----BEGIN CERTIFICATE-----
+MIIgvDCCH6SgAwIBAgIDC+NYMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEndl
+Yi1wbGF0Zm9ybS10ZXN0czAeFw0yMDA3MzAyMDEyNDhaFw0yMjEwMDgyMDEyNDha
+MBwxGjAYBgNVBAMMEXdlYi1wbGF0Zm9ybS50ZXN0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAyAtmdUGyRtQPsoGNZ6nBh1ml8jSBceLsEtIfPGss/JBO
+nNiRL1KnzGFbguNH9XIb+t67K7lfT7rJ/n6bZ7IQMjnG5KOUeh6cOYRxTxs7X4Zj
+zJ/LMLfhTvBaSTQssdF+W0Ruvjf1MkKa2lrC6bmFDZSFAoq2RgSxV+lMJNoEFs8W
+PTVEgbnvGszZt5ejbJG8lEUXl9u0sWiqVt0PGLd2stI9EDOgw+ymeA75Pc5Wyz0r
+RQdpbpFd2vjPmKQMhvI2EeT8uNGZCeESHMli73pd3RER62sUgFNoU1rEnMQpYu5j
+IQ21LaAn5KT+FodB9oU+XSHPwEw2zt/XSZdr5qYbTQIDAQABo4IeBDCCHgAwCQYD
+VR0TBAIwADAdBgNVHQ4EFgQU1HiW0SJAk3bOF+u2cLYJBeCjF/gwHwYDVR0jBBgw
+FoAUs3XdoJvyWv4XjYCx/Ke3wSt5KSswCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoG
+CCsGAQUFBwMBMIIdjwYDVR0RBIIdhjCCHYKCEXdlYi1wbGF0Zm9ybS50ZXN0ghVv
+cDgud2ViLXBsYXRmb3JtLnRlc3SCFW9wNy53ZWItcGxhdGZvcm0udGVzdIIVb3A5
+LndlYi1wbGF0Zm9ybS50ZXN0ghVvcDQud2ViLXBsYXRmb3JtLnRlc3SCFW5vdC13
+ZWItcGxhdGZvcm0udGVzdIIVb3A2LndlYi1wbGF0Zm9ybS50ZXN0ghVvcDMud2Vi
+LXBsYXRmb3JtLnRlc3SCFW9wMi53ZWItcGxhdGZvcm0udGVzdIIVb3AxLndlYi1w
+bGF0Zm9ybS50ZXN0ghV3d3cud2ViLXBsYXRmb3JtLnRlc3SCFW9wNS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4OC53ZWItcGxhdGZvcm0udGVzdIIWb3A5OC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4NS53ZWItcGxhdGZvcm0udGVzdIIWb3A4OS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2Ni53ZWItcGxhdGZvcm0udGVzdIIWb3A3Mi53ZWItcGxh
+dGZvcm0udGVzdIIWb3AyNC53ZWItcGxhdGZvcm0udGVzdIIWb3A0MS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A3OS53ZWItcGxhdGZvcm0udGVzdIIWb3A5MS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A1OS53ZWItcGxhdGZvcm0udGVzdIIWb3AzOS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2MC53ZWItcGxhdGZvcm0udGVzdIIWb3A1OC53ZWItcGxh
+dGZvcm0udGVzdIIWb3AyOC53ZWItcGxhdGZvcm0udGVzdIIWd3d3MS53ZWItcGxh
+dGZvcm0udGVzdIIWb3AxNC53ZWItcGxhdGZvcm0udGVzdIIWb3A2OS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0MC53ZWItcGxhdGZvcm0udGVzdIIWb3A3NC53ZWItcGxh
+dGZvcm0udGVzdIIWb3AzMS53ZWItcGxhdGZvcm0udGVzdIIWb3AxOC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A3My53ZWItcGxhdGZvcm0udGVzdIIWb3A3Ny53ZWItcGxh
+dGZvcm0udGVzdIIWb3AxMi53ZWItcGxhdGZvcm0udGVzdIIWb3A1NC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2My53ZWItcGxhdGZvcm0udGVzdIIWb3A3MS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A5NS53ZWItcGxhdGZvcm0udGVzdIIWb3AxNi53ZWItcGxh
+dGZvcm0udGVzdIIWb3AzNi53ZWItcGxhdGZvcm0udGVzdIIWb3AyNy53ZWItcGxh
+dGZvcm0udGVzdIIWb3AyOS53ZWItcGxhdGZvcm0udGVzdIIWb3A5NC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0NC53ZWItcGxhdGZvcm0udGVzdIIWb3AzMy53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4NC53ZWItcGxhdGZvcm0udGVzdIIWb3AzMi53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2MS53ZWItcGxhdGZvcm0udGVzdIIWb3A3MC53ZWItcGxh
+dGZvcm0udGVzdIIWd3d3Mi53ZWItcGxhdGZvcm0udGVzdIIWb3A0My53ZWItcGxh
+dGZvcm0udGVzdIIWb3A3OC53ZWItcGxhdGZvcm0udGVzdIIWb3AyNi53ZWItcGxh
+dGZvcm0udGVzdIIWb3A3Ni53ZWItcGxhdGZvcm0udGVzdIIWb3A1Mi53ZWItcGxh
+dGZvcm0udGVzdIIWb3A5OS53ZWItcGxhdGZvcm0udGVzdIIWb3A4Ni53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0Ni53ZWItcGxhdGZvcm0udGVzdIIWb3AxNy53ZWItcGxh
+dGZvcm0udGVzdIIWb3A5MC53ZWItcGxhdGZvcm0udGVzdIIWb3A5My53ZWItcGxh
+dGZvcm0udGVzdIIWb3AxMC53ZWItcGxhdGZvcm0udGVzdIIWb3A1NS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A1MS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0NS53ZWItcGxhdGZvcm0udGVzdIIWb3A4MC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2OC53ZWItcGxhdGZvcm0udGVzdIIWb3A0OS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A1Ny53ZWItcGxhdGZvcm0udGVzdIIWb3AzNS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2Ny53ZWItcGxhdGZvcm0udGVzdIIWb3A5Mi53ZWItcGxh
+dGZvcm0udGVzdIIWb3AxNS53ZWItcGxhdGZvcm0udGVzdIIWb3AxMy53ZWItcGxh
+dGZvcm0udGVzdIIWb3A3NS53ZWItcGxhdGZvcm0udGVzdIIWb3A2NC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A5Ny53ZWItcGxhdGZvcm0udGVzdIIWb3AzNy53ZWItcGxh
+dGZvcm0udGVzdIIWb3A1Ni53ZWItcGxhdGZvcm0udGVzdIIWb3A2Mi53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4Mi53ZWItcGxhdGZvcm0udGVzdIIWb3AyNS53ZWItcGxh
+dGZvcm0udGVzdIIWb3AxMS53ZWItcGxhdGZvcm0udGVzdIIWb3A1MC53ZWItcGxh
+dGZvcm0udGVzdIIWb3AzOC53ZWItcGxhdGZvcm0udGVzdIIWb3A4My53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4MS53ZWItcGxhdGZvcm0udGVzdIIWb3AyMC53ZWItcGxh
+dGZvcm0udGVzdIIWb3AyMS53ZWItcGxhdGZvcm0udGVzdIIWb3AyMy53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0Mi53ZWItcGxhdGZvcm0udGVzdIIWb3AyMi53ZWItcGxh
+dGZvcm0udGVzdIIWb3A2NS53ZWItcGxhdGZvcm0udGVzdIIWb3A5Ni53ZWItcGxh
+dGZvcm0udGVzdIIWb3A4Ny53ZWItcGxhdGZvcm0udGVzdIIWb3AxOS53ZWItcGxh
+dGZvcm0udGVzdIIWb3A1My53ZWItcGxhdGZvcm0udGVzdIIWb3AzMC53ZWItcGxh
+dGZvcm0udGVzdIIWb3A0OC53ZWItcGxhdGZvcm0udGVzdIIWb3AzNC53ZWItcGxh
+dGZvcm0udGVzdIIZb3A2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3AzLm5vdC13
+ZWItcGxhdGZvcm0udGVzdIIZb3AyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A1
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZd3d3Lm5vdC13ZWItcGxhdGZvcm0udGVz
+dIIZd3d3Lnd3dy53ZWItcGxhdGZvcm0udGVzdIIZb3A3Lm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIZb3A0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3A4Lm5vdC13ZWIt
+cGxhdGZvcm0udGVzdIIZb3A5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIZb3AxLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3AzNi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wNTMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDUwLm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3AyNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzEubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDk1Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A4
+My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDczLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AxOS5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wMjEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDgxLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3A3MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wNzgubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQwLm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3AyNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjUubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghp3d3cud3d3Mi53ZWItcGxhdGZvcm0udGVzdIIab3A4
+MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTIubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDY4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0NS5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wNzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDcyLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3A5MC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wODkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQ5Lm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3A3Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNzkubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDgyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIad3d3
+Lnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCGm9wMTIubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDM5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A0NC5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGnd3dzEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU4Lm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3AxNC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wMzAubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDYyLm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3A2MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wOTIubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDI5Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5
+OC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNjQubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDI2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AyMi5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wOTQubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDM4Lm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3AzMy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wMjMubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDU3Lm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3A1NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wODUubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDQ2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5
+Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzIubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDYwLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A5Ni5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wNTEubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQxLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3AzNS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wOTkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQyLm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3A2Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMzcubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDQ4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A1
+NS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTYubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDg0Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AzNC5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wNjkubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDExLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3A5My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gnd3dzEud3d3LndlYi1wbGF0Zm9ybS50ZXN0ghpvcDg2Lm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3AxMy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMjAubm90LXdl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDc2Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3Ay
+Ny5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wMTcubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDc1Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3AxNS5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wNDcubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE4Lm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIab3A2My5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SC
+Gm9wMjgubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDQzLm5vdC13ZWItcGxhdGZv
+cm0udGVzdIIab3A2Ni5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGnd3dzIud3d3Lndl
+Yi1wbGF0Zm9ybS50ZXN0ghpvcDkxLm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A3
+NC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCGm9wNTkubm90LXdlYi1wbGF0Zm9ybS50
+ZXN0ghpvcDg4Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIab3A4Ny5ub3Qtd2ViLXBs
+YXRmb3JtLnRlc3SCGm9wMTAubm90LXdlYi1wbGF0Zm9ybS50ZXN0ghpvcDE2Lm5v
+dC13ZWItcGxhdGZvcm0udGVzdIIbd3d3MS53d3cyLndlYi1wbGF0Zm9ybS50ZXN0
+ght3d3cyLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCG3d3dzIud3d3MS53ZWItcGxh
+dGZvcm0udGVzdIIbd3d3MS53d3cxLndlYi1wbGF0Zm9ybS50ZXN0gh13d3cud3d3
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIeeG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9y
+bS50ZXN0gh53d3cxLnd3dy5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCHnd3dy53d3cy
+Lm5vdC13ZWItcGxhdGZvcm0udGVzdIIed3d3Mi53d3cubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0gh53d3cud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3
+Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzIud3d3MS5ub3Qtd2ViLXBsYXRm
+b3JtLnRlc3SCH3d3dzEud3d3MS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCH3d3dzEu
+d3d3Mi5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCInhuLS1sdmUtNmxhZC53d3cud2Vi
+LXBsYXRmb3JtLnRlc3SCInhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCInd3dy54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCI3d3dzIueG4t
+LWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giN4bi0tbHZlLTZsYWQud3d3Mi53
+ZWItcGxhdGZvcm0udGVzdIIjeG4tLWx2ZS02bGFkLnd3dzEud2ViLXBsYXRmb3Jt
+LnRlc3SCI3d3dzEueG4tLWx2ZS02bGFkLndlYi1wbGF0Zm9ybS50ZXN0giZ4bi0t
+bHZlLTZsYWQud3d3Lm5vdC13ZWItcGxhdGZvcm0udGVzdIImd3d3LnhuLS1sdmUt
+NmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCJ3huLS1sdmUtNmxhZC53d3cxLm5v
+dC13ZWItcGxhdGZvcm0udGVzdIInd3d3Mi54bi0tbHZlLTZsYWQubm90LXdlYi1w
+bGF0Zm9ybS50ZXN0gid3d3cxLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3Jt
+LnRlc3SCJ3huLS1sdmUtNmxhZC53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIp
+eG4tLW44ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCK3huLS1s
+dmUtNmxhZC54bi0tbHZlLTZsYWQud2ViLXBsYXRmb3JtLnRlc3SCLXd3dy54bi0t
+bjhqNmRzNTNsd3drcnFodjI4YS53ZWItcGxhdGZvcm0udGVzdIIteG4tLW44ajZk
+czUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gi14bi0tbjhqNmRz
+NTNsd3drcnFodjI4YS53d3cud2ViLXBsYXRmb3JtLnRlc3SCLnd3dzEueG4tLW44
+ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1
+M2x3d2tycWh2MjhhLnd3dzIud2ViLXBsYXRmb3JtLnRlc3SCLnhuLS1uOGo2ZHM1
+M2x3d2tycWh2MjhhLnd3dzEud2ViLXBsYXRmb3JtLnRlc3SCLnd3dzIueG4tLW44
+ajZkczUzbHd3a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCL3huLS1sdmUtNmxh
+ZC54bi0tbHZlLTZsYWQubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjF3d3cueG4tLW44
+ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjF4bi0tbjhq
+NmRzNTNsd3drcnFodjI4YS53d3cubm90LXdlYi1wbGF0Zm9ybS50ZXN0gjJ4bi0t
+bjhqNmRzNTNsd3drcnFodjI4YS53d3cyLm5vdC13ZWItcGxhdGZvcm0udGVzdIIy
+d3d3MS54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCMnd3dzIueG4tLW44ajZkczUzbHd3a3JxaHYyOGEubm90LXdlYi1wbGF0Zm9y
+bS50ZXN0gjJ4bi0tbjhqNmRzNTNsd3drcnFodjI4YS53d3cxLm5vdC13ZWItcGxh
+dGZvcm0udGVzdII2eG4tLW44ajZkczUzbHd3a3JxaHYyOGEueG4tLWx2ZS02bGFk
+LndlYi1wbGF0Zm9ybS50ZXN0gjZ4bi0tbHZlLTZsYWQueG4tLW44ajZkczUzbHd3
+a3JxaHYyOGEud2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1uOGo2ZHM1M2x3d2tycWh2
+MjhhLnhuLS1sdmUtNmxhZC5ub3Qtd2ViLXBsYXRmb3JtLnRlc3SCOnhuLS1sdmUt
+NmxhZC54bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRl
+c3SCQXhuLS1uOGo2ZHM1M2x3d2tycWh2MjhhLnhuLS1uOGo2ZHM1M2x3d2tycWh2
+MjhhLndlYi1wbGF0Zm9ybS50ZXN0gkV4bi0tbjhqNmRzNTNsd3drcnFodjI4YS54
+bi0tbjhqNmRzNTNsd3drcnFodjI4YS5ub3Qtd2ViLXBsYXRmb3JtLnRlc3QwDQYJ
+KoZIhvcNAQELBQADggEBAIca94JI4YUKzcnrJjrw0nAezB4ej2HtQaVyTAvdf59t
+6/aWbPVBPXhuaXS7SdTRi+FfyR5Dfxlr2/43Utc6iKkp32RjroIt4Y8ZEBOKc8aN
+rsqZUIlJkKVPz+wTWy/r3KDSUxUa0ZNMR/Cbb2UaUeJLc1beVyoRrVpokq02vrj1
+uXIouOzXVdEN4UAnueQrwN6h6TglTrZD3BoLOJYrFF+IGnWS/L92OiOWN3/0g2KO
+/V8pBgxSK+UjlZsPsB4au5m0PBuDyU31tyxrmPpnSGOKnh5s78vU64KoSSFootE0
+NbCb76hRIos6/YeOWtYfshxkwxDifbbJzieXFhqmZk8=
+-----END CERTIFICATE-----
diff --git a/third_party/blink/web_tests/external/wpt/user-timing/case-sensitivity.any.js b/third_party/blink/web_tests/external/wpt/user-timing/case-sensitivity.any.js
new file mode 100644
index 0000000..1c0b0dc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/user-timing/case-sensitivity.any.js
@@ -0,0 +1,25 @@
+  test(function () {
+    assert_equals(typeof self.performance, "object");
+    assert_equals(typeof self.performance.getEntriesByType, "function");
+
+    self.performance.mark("mark1");
+    self.performance.measure("measure1");
+
+    const type = [
+      'mark',
+      'measure',
+    ];
+    type.forEach(function(entryType) {
+      if (PerformanceObserver.supportedEntryTypes.includes(entryType)) {
+        const entryTypeUpperCased = entryType.toUpperCase();
+        const entryTypeCapitalized = entryType[0].toUpperCase() + entryType.substring(1);
+        const lowerList = self.performance.getEntriesByType(entryType);
+        const upperList = self.performance.getEntriesByType(entryTypeUpperCased);
+        const mixedList = self.performance.getEntriesByType(entryTypeCapitalized);
+
+        assert_greater_than(lowerList.length, 0, "Entries exist");
+        assert_equals(upperList.length, 0, "getEntriesByType('" + entryTypeCapitalized + "').length");
+        assert_equals(mixedList.length, 0, "getEntriesByType('" + entryTypeCapitalized + "').length");
+      }
+    });
+  }, "getEntriesByType values are case sensitive");
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html
index b556e31..0bf2cfbb 100644
--- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html
@@ -180,6 +180,20 @@
                 },
                 'context = new AudioContext({sampleRate: 1000000})')
                 .throw(DOMException);
+            // A negative sample rate should not be accepted
+            should(
+                () => {
+                  context = new AudioContext({sampleRate: -1})
+                },
+                'context = new AudioContext({sampleRate: -1})')
+                .throw(DOMException);
+            // A null sample rate should not be accepted
+            should(
+                () => {
+                  context = new AudioContext({sampleRate: 0})
+                },
+                'context = new AudioContext({sampleRate: 0})')
+                .throw(DOMException);
 
             should(
                 () => {
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave-expected.txt
new file mode 100644
index 0000000..8d26f7e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave-expected.txt
@@ -0,0 +1,34 @@
+This is a testharness.js-based test.
+PASS # AUDIT TASK RUNNER STARTED.
+PASS Executing "create with factory method"
+PASS Executing "different length with factory method"
+PASS Executing "too small with factory method"
+PASS Executing "create with constructor"
+PASS Executing "different length with constructor"
+PASS Executing "too small with constructor"
+PASS Executing "output test"
+PASS Audit report
+PASS > [create with factory method] 
+PASS   context.createPeriodicWave(new Float32Array(4096), new Float32Array(4096)) did not throw an exception.
+PASS < [create with factory method] All assertions passed. (total 1 assertions)
+PASS > [different length with factory method] 
+PASS   context.createPeriodicWave(new Float32Array(512), new Float32Array(4)) threw IndexSizeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': length of real array (512) and length of imaginary array (4) must match.".
+PASS < [different length with factory method] All assertions passed. (total 1 assertions)
+PASS > [too small with factory method] 
+FAIL X context.createPeriodicWave(new Float32Array(1), new Float32Array(1)) did not throw an exception. assert_true: expected true got false
+FAIL < [too small with factory method] 1 out of 1 assertions were failed. assert_true: expected true got false
+PASS > [create with constructor] 
+PASS   new PeriodicWave(context, { real : new Float32Array(4096), imag : new Float32Array(4096) }) did not throw an exception.
+PASS < [create with constructor] All assertions passed. (total 1 assertions)
+PASS > [different length with constructor] 
+PASS   new PeriodicWave(context, { real : new Float32Array(4096), imag : new Float32Array(4) }) threw IndexSizeError: "Failed to construct 'PeriodicWave': length of real array (4096) and length of imaginary array (4) must match.".
+PASS < [different length with constructor] All assertions passed. (total 1 assertions)
+PASS > [too small with constructor] 
+FAIL X new PeriodicWave(context, { real : new Float32Array(1), imag : new Float32Array(1) }) did not throw an exception. assert_true: expected true got false
+FAIL < [too small with constructor] 1 out of 1 assertions were failed. assert_true: expected true got false
+PASS > [output test] 
+PASS   rendering PeriodicWave is identical to the array AudioBuffer.
+PASS < [output test] All assertions passed. (total 1 assertions)
+FAIL # AUDIT TASK RUNNER FINISHED: 2 out of 7 tasks were failed. assert_true: expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html
new file mode 100644
index 0000000..bd42453
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      Test Constructor: MediaStreamAudioDestinationNode
+    </title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      // real and imag are used in separate PeriodicWaves to make their peak values
+      // easy to determine.
+      const realMax = 99;
+      var real = new Float32Array(realMax + 1);
+      real[1] = 2.0; // fundamental
+      real[realMax] = 3.0;
+      const realPeak = real[1] + real[realMax];
+      const realFundamental = 19.0;
+      var imag = new Float32Array(4);
+      imag[0] = 6.0; // should be ignored.
+      imag[3] = 0.5;
+      const imagPeak = imag[3];
+      const imagFundamental = 551.0;
+
+      const testLength = 4096;
+      let context = new AudioContext();
+
+      let audit = Audit.createTaskRunner();
+
+      // Create with the factory method
+
+      audit.define('create with factory method', (task, should) => {
+        should(() => {
+          context.createPeriodicWave(new Float32Array(4096), new Float32Array(4096));
+        }, 'context.createPeriodicWave(new Float32Array(4096), ' +
+        'new Float32Array(4096))').notThrow();
+        task.done();
+      });
+
+      audit.define('different length with factory method', (task, should) => {
+        should(() => {
+          context.createPeriodicWave(new Float32Array(512), new Float32Array(4));
+        }, 'context.createPeriodicWave(new Float32Array(512), ' +
+        'new Float32Array(4))').throw(DOMException, "IndexSizeError");
+        task.done();
+      });
+
+      audit.define('too small with factory method', (task, should) => {
+        should(() => {
+          context.createPeriodicWave(new Float32Array(1), new Float32Array(1));
+        }, 'context.createPeriodicWave(new Float32Array(1), ' +
+        'new Float32Array(1))').throw(DOMException, "IndexSizeError");
+        task.done();
+      });
+
+      // Create with the constructor
+
+      audit.define('create with constructor', (task, should) => {
+        should(() => {
+          new PeriodicWave(context, { real: new Float32Array(4096), imag: new Float32Array(4096) });
+        }, 'new PeriodicWave(context, { real : new Float32Array(4096), ' +
+        'imag : new Float32Array(4096) })').notThrow();
+        task.done();
+      });
+
+      audit.define('different length with constructor', (task, should) => {
+        should(() => {
+          new PeriodicWave(context, { real: new Float32Array(4096), imag: new Float32Array(4) });
+        }, 'new PeriodicWave(context, { real : new Float32Array(4096), ' +
+        'imag : new Float32Array(4) })').throw(DOMException, "IndexSizeError");
+        task.done();
+      });
+
+      audit.define('too small with constructor', (task, should) => {
+        should(() => {
+          new PeriodicWave(context, { real: new Float32Array(1), imag: new Float32Array(1) });
+        }, 'new PeriodicWave(context, { real : new Float32Array(1), ' +
+        'imag : new Float32Array(1) })').throw(DOMException, "IndexSizeError");
+        task.done();
+      });
+
+      audit.define('output test', (task, should) => {
+        let context = new OfflineAudioContext(2, 4096, 44100);
+        // Create the expected output buffer
+        let expectations = context.createBuffer(2, testLength, context.sampleRate);
+        for (var i = 0; i < expectations.length; ++i) {
+
+          expectations.getChannelData(0)[i] = 1.0 / realPeak *
+            (real[1] * Math.cos(2 * Math.PI * realFundamental * i /
+                                context.sampleRate) +
+             real[realMax] * Math.cos(2 * Math.PI * realMax * realFundamental * i /
+                                context.sampleRate));
+
+          expectations.getChannelData(1)[i] = 1.0 / imagPeak *
+             imag[3] * Math.sin(2 * Math.PI * 3 * imagFundamental * i /
+                                context.sampleRate);
+        }
+
+        // Create the real output buffer
+        let merger = context.createChannelMerger();
+
+        let osc1 = context.createOscillator();
+        let osc2 = context.createOscillator();
+
+        osc1.setPeriodicWave(context.createPeriodicWave(
+                                real, new Float32Array(real.length)));
+        osc2.setPeriodicWave(context.createPeriodicWave(
+                                new Float32Array(imag.length), imag));
+        osc1.frequency.value = realFundamental;
+        osc2.frequency.value = imagFundamental;
+
+        osc1.start();
+        osc2.start();
+
+        osc1.connect(merger, 0, 0);
+        osc2.connect(merger, 0, 1);
+
+        context.startRendering().then(reality => {
+          should(reality, 'rendering PeriodicWave').beEqualToArray(expectations);
+          task.done();
+        });
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
index c69b336..dd981326 100644
--- a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 112 tests; 111 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 112 tests; 103 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Navigator: original interface defined
@@ -58,21 +58,18 @@
 PASS HIDReportItem interface: attribute usages
 PASS HIDReportItem interface: attribute usageMinimum
 PASS HIDReportItem interface: attribute usageMaximum
+FAIL HIDReportItem interface: attribute designatorMinimum assert_true: The prototype object must have a property "designatorMinimum" expected true got false
+FAIL HIDReportItem interface: attribute designatorMaximum assert_true: The prototype object must have a property "designatorMaximum" expected true got false
+FAIL HIDReportItem interface: attribute stringMinimum assert_true: The prototype object must have a property "stringMinimum" expected true got false
+FAIL HIDReportItem interface: attribute stringMaximum assert_true: The prototype object must have a property "stringMaximum" expected true got false
 PASS HIDReportItem interface: attribute reportSize
 PASS HIDReportItem interface: attribute reportCount
 PASS HIDReportItem interface: attribute unitExponent
-PASS HIDReportItem interface: attribute unitSystem
-PASS HIDReportItem interface: attribute unitFactorLengthExponent
-PASS HIDReportItem interface: attribute unitFactorMassExponent
-PASS HIDReportItem interface: attribute unitFactorTimeExponent
-PASS HIDReportItem interface: attribute unitFactorTemperatureExponent
-PASS HIDReportItem interface: attribute unitFactorCurrentExponent
-PASS HIDReportItem interface: attribute unitFactorLuminousIntensityExponent
+FAIL HIDReportItem interface: attribute unit assert_true: The prototype object must have a property "unit" expected true got false
 PASS HIDReportItem interface: attribute logicalMinimum
 PASS HIDReportItem interface: attribute logicalMaximum
 PASS HIDReportItem interface: attribute physicalMinimum
 PASS HIDReportItem interface: attribute physicalMaximum
-PASS HIDReportItem interface: attribute strings
 PASS HIDReportInfo interface: existence and properties of interface object
 PASS HIDReportInfo interface object length
 PASS HIDReportInfo interface object name
@@ -93,6 +90,9 @@
 PASS HIDCollectionInfo interface: attribute inputReports
 PASS HIDCollectionInfo interface: attribute outputReports
 PASS HIDCollectionInfo interface: attribute featureReports
+FAIL HIDCollectionInfo interface: attribute reportIds assert_true: The prototype object must have a property "reportIds" expected true got false
+FAIL HIDCollectionInfo interface: operation getField(BufferSource, HIDFieldOptions) assert_own_property: interface prototype object missing non-static operation expected property "getField" missing
+FAIL HIDCollectionInfo interface: operation setField(BufferSource, HIDFieldOptions, double) assert_own_property: interface prototype object missing non-static operation expected property "setField" missing
 PASS HIDDevice interface: existence and properties of interface object
 PASS HIDDevice interface object length
 PASS HIDDevice interface object name
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js
new file mode 100644
index 0000000..52da60b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js
@@ -0,0 +1,47 @@
+// META: global=worker
+
+const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+const redirectToCrossOrigin = "/common/redirect.py?location=" + crossOrigin;
+
+test(function() {
+  assert_throws_js(SyntaxError, function() {
+    importScripts("/workers/modules/resources/syntax-error.js");
+  });
+}, "Same-origin syntax error");
+
+test(function() {
+  assert_throws_js(Error, function() {
+    importScripts("/workers/modules/resources/throw.js");
+  });
+}, "Same-origin throw");
+
+// https://html.spec.whatwg.org/C/#run-a-classic-script
+// Step 8.2. If rethrow errors is true and script's muted errors is true, then:
+// Step 8.2.2. Throw a "NetworkError" DOMException.
+test(function() {
+  assert_throws_dom("NetworkError", function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  });
+}, "Cross-origin syntax error");
+
+test(function() {
+  assert_throws_dom("NetworkError", function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/throw.js");
+  });
+}, "Cross-origin throw");
+
+test(function() {
+  assert_throws_dom("NetworkError", function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  });
+}, "Redirect-to-cross-origin syntax error");
+
+test(function() {
+  assert_throws_dom("NetworkError", function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/throw.js");
+  });
+}, "Redirect-to-Cross-origin throw");
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt
new file mode 100644
index 0000000..32ebda0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+PASS Same-origin syntax error
+PASS Same-origin throw
+FAIL Cross-origin syntax error assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  }" threw null, not an object
+FAIL Cross-origin throw assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/throw.js");
+  }" threw null, not an object
+PASS Redirect-to-cross-origin syntax error
+PASS Redirect-to-Cross-origin throw
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..1942e64d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Same-origin syntax error
+PASS Same-origin throw
+FAIL Cross-origin syntax error assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  }" threw null, not an object
+FAIL Cross-origin throw assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/throw.js");
+  }" threw null, not an object
+FAIL Redirect-to-cross-origin syntax error assert_throws_dom: function "function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  }" threw null, not an object
+FAIL Redirect-to-Cross-origin throw assert_throws_dom: function "function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/throw.js");
+  }" threw null, not an object
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt
new file mode 100644
index 0000000..1942e64d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+PASS Same-origin syntax error
+PASS Same-origin throw
+FAIL Cross-origin syntax error assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  }" threw null, not an object
+FAIL Cross-origin throw assert_throws_dom: function "function() {
+    importScripts(crossOrigin +
+                  "/workers/modules/resources/throw.js");
+  }" threw null, not an object
+FAIL Redirect-to-cross-origin syntax error assert_throws_dom: function "function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/syntax-error.js");
+  }" threw null, not an object
+FAIL Redirect-to-Cross-origin throw assert_throws_dom: function "function() {
+    importScripts(redirectToCrossOrigin +
+                  "/workers/modules/resources/throw.js");
+  }" threw null, not an object
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js
new file mode 100644
index 0000000..4fd8914
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js
@@ -0,0 +1,8 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+runTest(
+  crossOrigin + "/workers/modules/resources/syntax-error.js",
+  false,
+  "NetworkError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..db410757
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt
new file mode 100644
index 0000000..db410757
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js
new file mode 100644
index 0000000..7fc6d0d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js
@@ -0,0 +1,80 @@
+setup({ allow_uncaught_exception:true });
+
+// For SyntaxError, the line in doImportScripts() is expected to be reported
+// as `e.lineno` etc. below.
+// doImportScripts() is introduced here to prevent the line number from being
+// affected by changes in runTest(), use of setTimeout(), etc.
+function doImportScripts(url) {
+  importScripts(url);
+}
+
+const t0 = async_test("WorkerGlobalScope error event: error");
+const t1 = async_test("WorkerGlobalScope error event: message");
+const t2 = async_test("WorkerGlobalScope error event: filename");
+const t3 = async_test("WorkerGlobalScope error event: lineno");
+
+function runTest(importScriptUrl, shouldUseSetTimeout, expected) {
+  self.addEventListener("error", e => {
+    if (expected === "NetworkError") {
+      t0.step_func_done(() => {
+        assert_equals(e.error.constructor, DOMException,
+            "e.error should be a DOMException")
+        assert_equals(e.error.name, "NetworkError");
+      })();
+
+      t1.step_func_done(() => {
+        assert_not_equals(e.message, "Script error.",
+            "e.message should not be muted to 'Script error.'");
+      })();
+
+      // filename, lineno etc. should NOT point to the location within
+      // `syntax-error.js` (otherwise parse errors to be muted are
+      // leaked to JavaScript).
+      // we expect they point to the caller of `importScripts()`,
+      // while this is not explicitly stated in the spec.
+      t2.step_func_done(() => {
+        assert_equals(e.filename, self.location.origin +
+            '/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js');
+      })();
+      t3.step_func_done(() => {
+        assert_equals(e.lineno, 8);
+      })();
+      // We don't check `e.colno` for now, because browsers set different
+      // `colno` values.
+    } else if (expected === "SyntaxError") {
+      t0.step_func_done(() => {
+        assert_equals(e.error.constructor, SyntaxError);
+        assert_equals(e.error.name, "SyntaxError");
+      })();
+
+      t1.step_func_done(() => {
+        assert_not_equals(e.message, "Script error.",
+            "e.message should not be muted to 'Script error.'");
+      })();
+
+      // filename, lineno etc. are expected to point to the location within
+      // `syntax-error.js` because it is same-origin,
+      // while this is not explicitly stated in the spec.
+      t2.step_func_done(() => {
+        assert_equals(e.filename, self.location.origin +
+            '/workers/modules/resources/syntax-error.js');
+      })();
+      t3.step_func_done(() => {
+        assert_equals(e.lineno, 1);
+      })();
+      // We don't check `e.colno` for now, because browsers set different
+      // `colno` values.
+    }
+
+    // Because importScripts() throws, we call done() here.
+    done();
+  });
+
+  if (shouldUseSetTimeout) {
+    setTimeout(
+      () => doImportScripts(importScriptUrl),
+      0);
+  } else {
+    doImportScripts(importScriptUrl);
+  }
+}
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js
new file mode 100644
index 0000000..2b960097
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js
@@ -0,0 +1,9 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+runTest(
+  "/common/redirect.py?location=" + crossOrigin +
+      "/workers/modules/resources/syntax-error.js",
+  false,
+  "NetworkError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..db410757
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt
new file mode 100644
index 0000000..db410757
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js
new file mode 100644
index 0000000..f7de416
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js
@@ -0,0 +1,7 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+runTest(
+  "/workers/modules/resources/syntax-error.js",
+  false,
+  "SyntaxError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js
new file mode 100644
index 0000000..a1bbef7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js
@@ -0,0 +1,8 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+runTest(
+  crossOrigin + "/workers/modules/resources/syntax-error.js",
+  true,
+  "NetworkError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..81bc6ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+PASS WorkerGlobalScope error event: message
+PASS WorkerGlobalScope error event: filename
+PASS WorkerGlobalScope error event: lineno
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt
new file mode 100644
index 0000000..81bc6ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+PASS WorkerGlobalScope error event: message
+PASS WorkerGlobalScope error event: filename
+PASS WorkerGlobalScope error event: lineno
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js
new file mode 100644
index 0000000..2755b33
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js
@@ -0,0 +1,9 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+runTest(
+  "/common/redirect.py?location=" + crossOrigin +
+      "/workers/modules/resources/syntax-error.js",
+  true,
+  "NetworkError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..81bc6ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+PASS WorkerGlobalScope error event: message
+PASS WorkerGlobalScope error event: filename
+PASS WorkerGlobalScope error event: lineno
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt
new file mode 100644
index 0000000..81bc6ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
+PASS WorkerGlobalScope error event: message
+PASS WorkerGlobalScope error event: filename
+PASS WorkerGlobalScope error event: lineno
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js
new file mode 100644
index 0000000..c4f70eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js
@@ -0,0 +1,7 @@
+// META: global=dedicatedworker,sharedworker
+// META: script=report-error-helper.js
+runTest(
+  "/workers/modules/resources/syntax-error.js",
+  true,
+  "SyntaxError"
+);
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt
new file mode 100644
index 0000000..736c8c6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS WorkerGlobalScope error event: error
+PASS WorkerGlobalScope error event: message
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/modules/resources/syntax-error.js" but got "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js"
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 1 but got 8
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt
new file mode 100644
index 0000000..736c8c6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS WorkerGlobalScope error event: error
+PASS WorkerGlobalScope error event: message
+FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/modules/resources/syntax-error.js" but got "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js"
+FAIL WorkerGlobalScope error event: lineno assert_equals: expected 1 but got 8
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/workers/modules/resources/throw.js b/third_party/blink/web_tests/external/wpt/workers/modules/resources/throw.js
new file mode 100644
index 0000000..3d876d4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/workers/modules/resources/throw.js
@@ -0,0 +1 @@
+throw new Error('custom message');
diff --git a/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt b/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
index ce17ccb..1e6e880 100644
--- a/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
+++ b/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls-expected.txt
@@ -2,6 +2,7 @@
 
 Should have single rect on document before fullscreen
 handler: layer(800x600) has hit test rect (0,0 800x600)
+handler: layer(800x600) has hit test rect (0,0 800x600)
 
 EVENT(webkitfullscreenchange)
 Should keep rect on document
@@ -9,6 +10,7 @@
 handler: layer(800x600) has hit test rect (0,0 800x600)
 handler: layer(800x600) has hit test rect (0,0 800x600)
 handler: layer(800x600) has hit test rect (0,0 800x600)
+handler: layer(800x600) has hit test rect (0,0 800x600)
 
 END OF TEST
 
diff --git a/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls.html b/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls.html
index 2de39b1..a808564 100644
--- a/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls.html
+++ b/third_party/blink/web_tests/fullscreen/compositor-touch-hit-rects-fullscreen-video-controls.html
@@ -21,7 +21,6 @@
     document.addEventListener('touchstart', function() { }, {passive: false});
 
     consoleWrite("Should have single rect on document before fullscreen");
-    internals.forceCompositingUpdate(document);
     logRects('handler');
 
     waitForEvent(document, 'webkitfullscreenchange', function() {
@@ -29,7 +28,6 @@
             consoleWrite("Should report no rect or another rect which is not on the document");
         else
             consoleWrite("Should keep rect on document");
-        internals.forceCompositingUpdate(document);
         logRects('handler');
         endTest();
     });
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-area-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-area-expected.txt
index e500a7d..acdf751 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-area-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-area-expected.txt
@@ -350,14 +350,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-expected.txt
index 3e4f72ac..2408dc8 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-expected.txt
@@ -293,14 +293,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
@@ -592,14 +594,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-huge-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-huge-expected.txt
index 6b26f0a..5522bd5 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-huge-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-huge-expected.txt
@@ -8340,14 +8340,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-line-names-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-line-names-expected.txt
index 135ab35..817c27f0 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-line-names-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-grid-line-names-expected.txt
@@ -507,14 +507,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-persistent-grid-huge-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-persistent-grid-huge-expected.txt
index 9f132259..6a0d341 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-persistent-grid-huge-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-css-persistent-grid-huge-expected.txt
@@ -8246,14 +8246,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-multiple-css-grid-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-multiple-css-grid-expected.txt
index 50fc05a..237aeb6 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-multiple-css-grid-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-multiple-css-grid-expected.txt
@@ -198,14 +198,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
@@ -410,14 +412,16 @@
       ],
       "gridHighlightConfig": {
         "gridBorderDash": false,
-        "cellBorderDash": true,
+        "rowLineDash": true,
+        "columnLineDash": true,
         "showGridExtensionLines": true,
         "showPositiveLineNumbers": true,
         "showNegativeLineNumbers": true,
         "showAreaNames": true,
         "showLineNames": true,
         "gridBorderColor": "rgba(255, 0, 0, 0)",
-        "cellBorderColor": "rgba(128, 0, 0, 0)",
+        "rowLineColor": "rgba(128, 0, 0, 0)",
+        "columnLineColor": "rgba(128, 0, 0, 0)",
         "rowGapColor": "rgba(0, 255, 0, 0)",
         "columnGapColor": "rgba(0, 0, 255, 0)",
         "rowHatchColor": "rgba(255, 255, 255, 0)",
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry-expected.txt
new file mode 100644
index 0000000..cf7f146
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry-expected.txt
@@ -0,0 +1,3 @@
+Tests that Frame objects include the registered domain of the frames URL
+Reported registered domain: devtools.test
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry.js b/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry.js
new file mode 100644
index 0000000..c9b0b567
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/page/frame-includes-domain-and-registry.js
@@ -0,0 +1,12 @@
+(async function(testRunner) {
+  const {page, dp} = await testRunner.startBlank(
+      `Tests that Frame objects include the registered domain of the frames URL`);
+
+  await dp.Page.enable();
+
+  page.navigate('http://devtools.test:8000/inspector-protocol/resources/empty.html');
+
+  const notification = await dp.Page.onceFrameNavigated();
+  testRunner.log('Reported registered domain: ' + notification.params.frame.domainAndRegistry);
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-crossorigin.js b/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-crossorigin.js
deleted file mode 100644
index 66da50b..0000000
--- a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-crossorigin.js
+++ /dev/null
@@ -1,5 +0,0 @@
-self.onerror = function (message, filename, lineno, colno, error) {
-    postMessage({ 'message': message, 'filename': filename, 'lineno': lineno, 'colno': colno, 'error': error });
-};
-
-importScripts('http://localhost:8000/workers/resources/worker-importScripts-throw.js');
diff --git a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-redirect-to-crossorigin.js b/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-redirect-to-crossorigin.js
deleted file mode 100644
index 86c9cd4..0000000
--- a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-redirect-to-crossorigin.js
+++ /dev/null
@@ -1,6 +0,0 @@
-self.onerror = function (message, filename, lineno, colno, error) {
-    postMessage({ 'message': message, 'filename': filename, 'lineno': lineno, 'colno': colno, 'error': error });
-};
-
-var differentRedirectOrigin = "/resources/redirect.php?url=http://localhost:8000/workers/resources/worker-importScripts-throw.js";
-importScripts(differentRedirectOrigin)
diff --git a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-sameorigin.js b/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-sameorigin.js
deleted file mode 100644
index c76ebd5..0000000
--- a/third_party/blink/web_tests/http/tests/workers/resources/worker-importscripts-onerror-sameorigin.js
+++ /dev/null
@@ -1,5 +0,0 @@
-self.onerror = function (message, filename, lineno, colno, error) {
-    postMessage({ 'message': message, 'filename': filename, 'lineno': lineno, 'colno': colno, 'error': error });
-};
-
-importScripts('/workers/resources/worker-importScripts-throw.js');
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin-expected.txt b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin-expected.txt
deleted file mode 100644
index 8e24a0420..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Ensure that scripts imported into a Worker from cross-origin hosts trigger sanitized onerror messages.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS workerOnerror.message is "Script error."
-PASS workerOnerror.filename is ""
-PASS workerOnerror.lineno is 0
-PASS workerOnerror.colno is 0
-PASS workerOnerror.error is null
-PASS pageOnerror.message is "Script error."
-PASS pageOnerror.filename is ""
-PASS pageOnerror.lineno is 0
-PASS pageOnerror.colno is 0
-PASS pageOnerror.error is null
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin.html b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin.html
deleted file mode 100644
index 3a47627..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-crossorigin.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <script>
-        window.jsTestIsAsync = true;
-        window.isOnErrorTest = true;
-    </script>
-    <script src="/js-test-resources/js-test.js"></script>
-</head>
-<body>
-    <script>
-        description("Ensure that scripts imported into a Worker from cross-origin hosts trigger sanitized onerror messages.");
-
-        var worker = new Worker('resources/worker-importscripts-onerror-crossorigin.js');
-
-        var workerOnerror, pageOnerror;
-        worker.onmessage = function (e) {
-            workerOnerror = e.data;
-            shouldBeEqualToString("workerOnerror.message", "Script error.");
-            shouldBeEqualToString("workerOnerror.filename", "");
-            shouldEvaluateTo("workerOnerror.lineno", 0);
-            shouldEvaluateTo("workerOnerror.colno", 0);
-            shouldBeNull("workerOnerror.error");
-        };
-
-        var onerrorMessage, onerrorURL, onerrorLine;
-        worker.onerror = function (e) {
-            pageOnerror = e;
-            shouldBeEqualToString("pageOnerror.message", "Script error.");
-            shouldBeEqualToString("pageOnerror.filename", "");
-            shouldEvaluateTo("pageOnerror.lineno", 0);
-            shouldEvaluateTo("pageOnerror.colno", 0);
-            shouldBeNull("pageOnerror.error");
-
-            e.preventDefault();
-            finishJSTest();
-        };
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin-expected.txt b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin-expected.txt
deleted file mode 100644
index 7064271..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Ensure that scripts imported into a Worker from a redirect to a cross-origin host trigger sanitized onerror messages.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS workerOnerror.message is "Script error."
-PASS workerOnerror.filename is ""
-PASS workerOnerror.lineno is 0
-PASS workerOnerror.colno is 0
-PASS workerOnerror.error is null
-PASS pageOnerror.message is "Script error."
-PASS pageOnerror.filename is ""
-PASS pageOnerror.lineno is 0
-PASS pageOnerror.colno is 0
-PASS pageOnerror.error is null
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin.html b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin.html
deleted file mode 100644
index f4508671..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-redirect-to-crossorigin.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <script>
-        window.jsTestIsAsync = true;
-        window.isOnErrorTest = true;
-    </script>
-    <script src="/js-test-resources/js-test.js"></script>
-</head>
-<body>
-    <script>
-        description("Ensure that scripts imported into a Worker from a redirect to a cross-origin host trigger sanitized onerror messages.");
-
-        var worker = new Worker('resources/worker-importscripts-onerror-redirect-to-crossorigin.js');
-
-        var workerOnerror, pageOnerror;
-        worker.onmessage = function (e) {
-            workerOnerror = e.data;
-            shouldBeEqualToString("workerOnerror.message", "Script error.");
-            shouldBeEqualToString("workerOnerror.filename", "");
-            shouldEvaluateTo("workerOnerror.lineno", 0);
-            shouldEvaluateTo("workerOnerror.colno", 0);
-            shouldBeNull("workerOnerror.error");
-        };
-
-        var onerrorMessage, onerrorURL, onerrorLine;
-        worker.onerror = function (e) {
-            pageOnerror = e;
-            shouldBeEqualToString("pageOnerror.message", "Script error.");
-            shouldBeEqualToString("pageOnerror.filename", "");
-            shouldEvaluateTo("pageOnerror.lineno", 0);
-            shouldEvaluateTo("pageOnerror.colno", 0);
-            shouldBeNull("pageOnerror.error");
-
-            e.preventDefault();
-            finishJSTest();
-        };
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin-expected.txt b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin-expected.txt
deleted file mode 100644
index a5cd7b36..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Ensure that scripts imported into a Worker from same-origin hosts trigger detailed onerror messages.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-PASS workerOnerror.message is "Uncaught This is a custom error message."
-PASS workerOnerror.filename is "http://127.0.0.1:8000/workers/resources/worker-importScripts-throw.js"
-PASS workerOnerror.lineno is 1
-PASS workerOnerror.colno is 1
-PASS workerOnerror.error is not null
-PASS workerOnerror.error is "This is a custom error message."
-PASS pageOnerror.message is "Uncaught This is a custom error message."
-PASS pageOnerror.filename is "http://127.0.0.1:8000/workers/resources/worker-importScripts-throw.js"
-PASS pageOnerror.lineno is 1
-PASS pageOnerror.colno is 1
-PASS pageOnerror.error is null
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin.html b/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin.html
deleted file mode 100644
index 6632cc0..0000000
--- a/third_party/blink/web_tests/http/tests/workers/worker-importScripts-onerror-sameorigin.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <script>
-        window.jsTestIsAsync = true;
-        window.isOnErrorTest = true;
-    </script>
-    <script src="/js-test-resources/js-test.js"></script>
-</head>
-<body>
-    <script>
-        description("Ensure that scripts imported into a Worker from same-origin hosts trigger detailed onerror messages.");
-
-        var worker = new Worker('resources/worker-importscripts-onerror-sameorigin.js');
-
-        var workerOnerror;
-        worker.onmessage = function (e) {
-            workerOnerror = e.data;
-            shouldBeEqualToString("workerOnerror.message", "Uncaught This is a custom error message.");
-            shouldBeEqualToString("workerOnerror.filename", "http://127.0.0.1:8000/workers/resources/worker-importScripts-throw.js");
-            shouldEvaluateTo("workerOnerror.lineno", 1);
-            shouldEvaluateTo("workerOnerror.colno", 1);
-            shouldNotBe("workerOnerror.error", "null");
-            shouldBeEqualToString("workerOnerror.error", "This is a custom error message.");
-        };
-
-        var onerrorMessage, onerrorURL, onerrorLine;
-        worker.onerror = function (e) {
-            pageOnerror = e;
-            shouldBeEqualToString("pageOnerror.message", "Uncaught This is a custom error message.");
-            shouldBeEqualToString("pageOnerror.filename", "http://127.0.0.1:8000/workers/resources/worker-importScripts-throw.js");
-            shouldEvaluateTo("pageOnerror.lineno", 1);
-            shouldEvaluateTo("pageOnerror.colno", 1);
-            shouldBeNull("pageOnerror.error");
-
-            e.preventDefault();
-            finishJSTest();
-        };
-    </script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates-expected.txt b/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates-expected.txt
new file mode 100644
index 0000000..009e538
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates-expected.txt
@@ -0,0 +1,24 @@
+Test CSS.trackComputedStyleUpdates and CSS.takeComputedStyleUpdates methods
+First round of updated nodes should contain the first item: true
+First round of updated nodes should not contain the second item: true
+First round of updated nodes should contain the third item: true
+First round of updated nodes should not contain the fourth item: true
+Updated nodes from the first session should contain the first item: true
+Updated nodes from the first session should contain the second item: true
+Updated nodes from the first session should not contain the third item: true
+Updated nodes from the first session should not contain the fourth item: true
+Updated nodes from the second session should not contain the first item: true
+Updated nodes from the second session should contain the second item: true
+Updated nodes from the second session should contain the third item: true
+Updated nodes from the second session should not contain the fourth item: true
+Sending a request before the previous one is resolved should fail with an error message:
+{
+    code : -32000
+    message : A previous request has not been resolved yet.
+}
+Sending a request while no style is being tracked should fail with an error message:
+{
+    code : -32000
+    message : No computed styles are being tracked right now.
+}
+
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates.js b/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates.js
new file mode 100644
index 0000000..137df724
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-poll-style-updates.js
@@ -0,0 +1,143 @@
+(async function (testRunner) {
+  const { page, session: firstSession, dp } = await testRunner.startURL(
+    'resources/css-poll-style-updates.html',
+    'Test CSS.trackComputedStyleUpdates and CSS.takeComputedStyleUpdates methods');
+
+  async function setupAndGetNodeIds(protocol) {
+    await protocol.DOM.enable();
+    await protocol.CSS.enable();
+
+    const CSSHelper = await testRunner.loadScript('../resources/css-helper.js');
+    const cssHelper = new CSSHelper(testRunner, protocol);
+
+    const documentNodeId = await cssHelper.requestDocumentNodeId();
+    const nodeIds = await cssHelper.requestAllNodeIds(documentNodeId, '.item');
+    return { protocol, nodeIds };
+  }
+
+  const { protocol: firstDP, nodeIds: firstSessionNodeIds } =
+    await setupAndGetNodeIds(dp);
+  const sencondSession = await page.createSession();
+  const { protocol: secondDP, nodeIds: secondSessionNodeIds } =
+    await setupAndGetNodeIds(sencondSession.protocol);
+
+  await firstDP.CSS.trackComputedStyleUpdates({
+    'propertiesToTrack': [
+      {
+        name: 'display',
+        value: 'grid',
+      },
+      {
+        name: 'width',
+        value: '100%',
+      }
+    ],
+  });
+
+  firstSession.evaluate(
+    () => document.querySelector('.container').classList.add('change-1'));
+  // Tracked style updates should send polling result back in a batch,
+  // and Untracked style updates should not be sent back.
+  const firstRoundResponse = await firstDP.CSS.takeComputedStyleUpdates();
+  const firstRoundNodeIds = firstRoundResponse.result.nodeIds;
+  testRunner.log(`First round of updated nodes should contain the first item: ${
+    firstRoundNodeIds.includes(firstSessionNodeIds[0])}`);
+  testRunner.log(
+    `First round of updated nodes should not contain the second item: ${
+    !firstRoundNodeIds.includes(firstSessionNodeIds[1])}`);
+  testRunner.log(
+    `First round of updated nodes should contain the third item: ${
+    firstRoundNodeIds.includes(firstSessionNodeIds[2])}`);
+  testRunner.log(
+    `First round of updated nodes should not contain the fourth item: ${
+    !firstRoundNodeIds.includes(firstSessionNodeIds[3])}`);
+
+  // Tests multiple sessions can track styles successfully and
+  // multiple values of the same CSS property should all be tracked correctly.
+  await firstDP.CSS.trackComputedStyleUpdates({
+    'propertiesToTrack': [
+      {
+        name: 'position',
+        value: 'relative',
+      },
+      {
+        name: 'position',
+        value: 'absolute',
+      }
+    ],
+  });
+
+  await secondDP.CSS.trackComputedStyleUpdates({
+    'propertiesToTrack': [
+      {
+        name: 'display',
+        value: 'flex',
+      },
+      {
+        name: 'display',
+        value: 'grid',
+      }
+    ],
+  });
+
+  firstSession.evaluate(
+    () => document.querySelector('.container').classList.add('change-2'));
+  sencondSession.evaluate(
+    () => document.querySelector('.container').classList.add('change-3'));
+  const [firstSessionResponse, secondSessionResponse] = await Promise.all([
+    firstDP.CSS.takeComputedStyleUpdates(),
+    secondDP.CSS.takeComputedStyleUpdates(),
+  ]);
+  const firstSessionRespondedIds = firstSessionResponse.result.nodeIds;
+  testRunner.log(
+    `Updated nodes from the first session should contain the first item: ${
+    firstSessionRespondedIds.includes(firstSessionNodeIds[0])}`);
+  testRunner.log(
+    `Updated nodes from the first session should contain the second item: ${
+    firstSessionRespondedIds.includes(firstSessionNodeIds[1])}`);
+  testRunner.log(
+    `Updated nodes from the first session should not contain the third item: ${
+    !firstSessionRespondedIds.includes(firstSessionNodeIds[2])}`);
+  testRunner.log(
+    `Updated nodes from the first session should not contain the fourth item: ${
+    !firstSessionRespondedIds.includes(firstSessionNodeIds[3])}`);
+
+  const secondSessionRespondedIds = secondSessionResponse.result.nodeIds;
+  testRunner.log(
+    `Updated nodes from the second session should not contain the first item: ${
+    !secondSessionRespondedIds.includes(secondSessionNodeIds[0])}`);
+  testRunner.log(
+    `Updated nodes from the second session should contain the second item: ${
+    secondSessionRespondedIds.includes(secondSessionNodeIds[1])}`);
+  testRunner.log(
+    `Updated nodes from the second session should contain the third item: ${
+    secondSessionRespondedIds.includes(secondSessionNodeIds[2])}`);
+  testRunner.log(
+    `Updated nodes from the second session should not contain the fourth item: ${
+    !secondSessionRespondedIds.includes(secondSessionNodeIds[3])}`);
+
+  firstSession.evaluate(
+    () =>
+      document.querySelector('.container').classList.remove('change-2'));
+  // Only one request can be active at a time; other requests should fail.
+  const multipleRequestsResponse = await Promise.all([
+    firstDP.CSS.takeComputedStyleUpdates(),
+    firstDP.CSS.takeComputedStyleUpdates(),
+  ]);
+  let errorResponse =
+    multipleRequestsResponse.find(result => Boolean(result.error));
+  testRunner.log(
+    'Sending a request before the previous one is resolved should fail with an error message:');
+  testRunner.log(errorResponse && errorResponse.error);
+
+  await firstDP.CSS.trackComputedStyleUpdates({
+    'propertiesToTrack': [],
+  });
+
+  errorResponse = await firstDP.CSS.takeComputedStyleUpdates();
+  testRunner.log(
+    'Sending a request while no style is being tracked should fail with an error message:');
+  testRunner.log(errorResponse.error);
+
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/inspector-protocol/css/resources/css-poll-style-updates.html b/third_party/blink/web_tests/inspector-protocol/css/resources/css-poll-style-updates.html
new file mode 100644
index 0000000..9f64fb3
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/resources/css-poll-style-updates.html
@@ -0,0 +1,32 @@
+<style>
+  .change-1 .item1 {
+    display: grid;
+  }
+  .change-1 .item2 {
+    position: absolute;
+  }
+  .change-1 .item3 {
+    width: 100%;
+  }
+  .change-1 .item4 {
+    width: 50%;
+  }
+  .change-2 .item1 {
+    position: absolute;
+  }
+  .change-2 .item2 {
+    position: relative; 
+  }
+  .change-3 .item2 {
+    display: flex;
+  }
+  .change-3 .item3 {
+    display: grid;
+  }
+</style>
+<div class="container">
+  <div class="item item1"></div>
+  <div class="item item2"></div>
+  <div class="item item3"></div>
+  <div class="item item4"></div>
+</div>
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js b/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
index 2726d3e5..d62b8e4 100644
--- a/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
+++ b/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
@@ -172,4 +172,9 @@
     var response = await this._dp.DOM.querySelector({nodeId, selector});
     return response.result.nodeId;
   }
+
+  async requestAllNodeIds(nodeId, selector) {
+    var response = await this._dp.DOM.querySelectorAll({nodeId, selector});
+    return response.result.nodeIds;
+  }
 });
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png b/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
new file mode 100644
index 0000000..6f407aa
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png b/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
new file mode 100644
index 0000000..491b81c5
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..85f7712
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..7c8932c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..890f7ed
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt
new file mode 100644
index 0000000..0f92eef4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-inline-template-columns-rows-resolved-values-001.tentative-expected.txt
@@ -0,0 +1,80 @@
+This is a testharness.js-based test.
+Found 76 tests; 40 PASS, 36 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px;
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
+PASS undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
+PASS undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px;
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt
new file mode 100644
index 0000000..0f92eef4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative-expected.txt
@@ -0,0 +1,80 @@
+This is a testharness.js-based test.
+Found 76 tests; 40 PASS, 36 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ; assert_in_array: gridTemplateRows value "10px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: auto auto; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateRows value "20px 20px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px;
+FAIL undefined 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px" not in array ["none"]
+PASS Children of 'grid' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px 20px" not in array ["50px"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px;
+FAIL undefined 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateRows value "50px 30px 20px" not in array ["50px 30px"]
+PASS Children of 'grid' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateRows value "50px 20px" not in array ["50px"]
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
+PASS undefined 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS Children of 'grid' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: ;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "110px 0px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 0px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px;
+FAIL undefined 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px 50px"]
+PASS Children of 'gridItemsPositions' with: grid-template-columns: 60px 50px; and grid-template-rows: 60px 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: auto auto;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "110px 50px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: ; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "60px 110px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px; assert_in_array: gridTemplateColumns value "60px 50px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px; assert_in_array: gridTemplateColumns value "100px 60px 50px" not in array ["100px 60px"]
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px;
+PASS undefined 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+PASS Children of 'gridAutoFlowColumn' with: grid-template-columns: 100px 60px; and grid-template-rows: 50px 30px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: ;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "110px 50px 0px 0px 100px" not in array ["none"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: ; and grid-template-rows: 60px 70px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 50px 0px 0px 100px" not in array ["60px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px; and grid-template-rows: 60px 70px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px;
+FAIL undefined 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px; assert_in_array: gridTemplateColumns value "60px 70px 0px 0px 100px" not in array ["60px 70px"]
+PASS Children of 'gridAutoFlowColumnItemsPositions' with: grid-template-columns: 60px 70px; and grid-template-rows: 60px 70px;
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt
new file mode 100644
index 0000000..f9802810
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/external/wpt/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt
@@ -0,0 +1,33 @@
+This is a testharness.js-based test.
+PASS undefined 'grid' with: grid-template-columns: 0fr; and grid-template-rows: 0fr;
+PASS undefined 'grid' with: grid-template-columns: 1fr; and grid-template-rows: 1fr;
+PASS undefined 'grid' with: grid-template-columns: 2fr; and grid-template-rows: 2fr;
+PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(0, .5fr); and grid-template-rows: minmax(0, .5fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
+FAIL undefined 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
+FAIL undefined 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["50px 50px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "12.5px 37.5px" not in array ["25px 75px"]
+FAIL undefined 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 50px" not in array ["50px 50px 0px"]
+PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
+PASS undefined 'grid' with: grid-template-columns: minmax(30px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(30px, 1fr) minmax(0, 1fr);
+FAIL undefined 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["75px 25px"]
+FAIL undefined 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+FAIL undefined 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
+FAIL undefined 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["0px 100px"]
+FAIL undefined 'grid' with: grid-template-columns: minmax(25px, 0fr) auto; and grid-template-rows: minmax(25px, 0fr) auto; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["25px 75px"]
+FAIL undefined 'grid' with: grid-template-columns: minmax(25px, 1fr) auto; and grid-template-rows: minmax(25px, 1fr) auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["25px 75px"]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/webhid/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/webhid/idlharness.https.window-expected.txt
new file mode 100644
index 0000000..c69b336
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/external/wpt/webhid/idlharness.https.window-expected.txt
@@ -0,0 +1,116 @@
+This is a testharness.js-based test.
+Found 112 tests; 111 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS idl_test setup
+PASS idl_test validation
+PASS Partial interface Navigator: original interface defined
+PASS Partial interface Navigator: member names are unique
+PASS Partial interface mixin NavigatorID: member names are unique
+PASS Navigator includes NavigatorID: member names are unique
+PASS Navigator includes NavigatorLanguage: member names are unique
+PASS Navigator includes NavigatorOnLine: member names are unique
+PASS Navigator includes NavigatorContentUtils: member names are unique
+PASS Navigator includes NavigatorCookies: member names are unique
+PASS Navigator includes NavigatorPlugins: member names are unique
+PASS Navigator includes NavigatorConcurrentHardware: member names are unique
+PASS HID interface: existence and properties of interface object
+PASS HID interface object length
+PASS HID interface object name
+PASS HID interface: existence and properties of interface prototype object
+PASS HID interface: existence and properties of interface prototype object's "constructor" property
+PASS HID interface: existence and properties of interface prototype object's @@unscopables property
+PASS HID interface: attribute onconnect
+PASS HID interface: attribute ondisconnect
+PASS HID interface: operation getDevices()
+PASS HID interface: operation requestDevice(HIDDeviceRequestOptions)
+PASS HID must be primary interface of navigator.hid
+PASS Stringification of navigator.hid
+PASS HID interface: navigator.hid must inherit property "onconnect" with the proper type
+PASS HID interface: navigator.hid must inherit property "ondisconnect" with the proper type
+PASS HID interface: navigator.hid must inherit property "getDevices()" with the proper type
+PASS HID interface: navigator.hid must inherit property "requestDevice(HIDDeviceRequestOptions)" with the proper type
+PASS HID interface: calling requestDevice(HIDDeviceRequestOptions) on navigator.hid with too few arguments must throw TypeError
+PASS HIDConnectionEvent interface: existence and properties of interface object
+PASS HIDConnectionEvent interface object length
+PASS HIDConnectionEvent interface object name
+PASS HIDConnectionEvent interface: existence and properties of interface prototype object
+PASS HIDConnectionEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDConnectionEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDConnectionEvent interface: attribute device
+PASS HIDInputReportEvent interface: existence and properties of interface object
+FAIL HIDInputReportEvent interface object length assert_equals: wrong value for HIDInputReportEvent.length expected 2 but got 0
+PASS HIDInputReportEvent interface object name
+PASS HIDInputReportEvent interface: existence and properties of interface prototype object
+PASS HIDInputReportEvent interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDInputReportEvent interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDInputReportEvent interface: attribute device
+PASS HIDInputReportEvent interface: attribute reportId
+PASS HIDInputReportEvent interface: attribute data
+PASS HIDReportItem interface: existence and properties of interface object
+PASS HIDReportItem interface object length
+PASS HIDReportItem interface object name
+PASS HIDReportItem interface: existence and properties of interface prototype object
+PASS HIDReportItem interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDReportItem interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDReportItem interface: attribute isAbsolute
+PASS HIDReportItem interface: attribute isArray
+PASS HIDReportItem interface: attribute isRange
+PASS HIDReportItem interface: attribute hasNull
+PASS HIDReportItem interface: attribute usages
+PASS HIDReportItem interface: attribute usageMinimum
+PASS HIDReportItem interface: attribute usageMaximum
+PASS HIDReportItem interface: attribute reportSize
+PASS HIDReportItem interface: attribute reportCount
+PASS HIDReportItem interface: attribute unitExponent
+PASS HIDReportItem interface: attribute unitSystem
+PASS HIDReportItem interface: attribute unitFactorLengthExponent
+PASS HIDReportItem interface: attribute unitFactorMassExponent
+PASS HIDReportItem interface: attribute unitFactorTimeExponent
+PASS HIDReportItem interface: attribute unitFactorTemperatureExponent
+PASS HIDReportItem interface: attribute unitFactorCurrentExponent
+PASS HIDReportItem interface: attribute unitFactorLuminousIntensityExponent
+PASS HIDReportItem interface: attribute logicalMinimum
+PASS HIDReportItem interface: attribute logicalMaximum
+PASS HIDReportItem interface: attribute physicalMinimum
+PASS HIDReportItem interface: attribute physicalMaximum
+PASS HIDReportItem interface: attribute strings
+PASS HIDReportInfo interface: existence and properties of interface object
+PASS HIDReportInfo interface object length
+PASS HIDReportInfo interface object name
+PASS HIDReportInfo interface: existence and properties of interface prototype object
+PASS HIDReportInfo interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDReportInfo interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDReportInfo interface: attribute reportId
+PASS HIDReportInfo interface: attribute items
+PASS HIDCollectionInfo interface: existence and properties of interface object
+PASS HIDCollectionInfo interface object length
+PASS HIDCollectionInfo interface object name
+PASS HIDCollectionInfo interface: existence and properties of interface prototype object
+PASS HIDCollectionInfo interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDCollectionInfo interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDCollectionInfo interface: attribute usagePage
+PASS HIDCollectionInfo interface: attribute usage
+PASS HIDCollectionInfo interface: attribute children
+PASS HIDCollectionInfo interface: attribute inputReports
+PASS HIDCollectionInfo interface: attribute outputReports
+PASS HIDCollectionInfo interface: attribute featureReports
+PASS HIDDevice interface: existence and properties of interface object
+PASS HIDDevice interface object length
+PASS HIDDevice interface object name
+PASS HIDDevice interface: existence and properties of interface prototype object
+PASS HIDDevice interface: existence and properties of interface prototype object's "constructor" property
+PASS HIDDevice interface: existence and properties of interface prototype object's @@unscopables property
+PASS HIDDevice interface: attribute oninputreport
+PASS HIDDevice interface: attribute opened
+PASS HIDDevice interface: attribute vendorId
+PASS HIDDevice interface: attribute productId
+PASS HIDDevice interface: attribute productName
+PASS HIDDevice interface: attribute collections
+PASS HIDDevice interface: operation open()
+PASS HIDDevice interface: operation close()
+PASS HIDDevice interface: operation sendReport(octet, BufferSource)
+PASS HIDDevice interface: operation sendFeatureReport(octet, BufferSource)
+PASS HIDDevice interface: operation receiveFeatureReport(octet)
+PASS Navigator interface: attribute hid
+PASS Navigator interface: navigator must inherit property "hid" with the proper type
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png b/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
new file mode 100644
index 0000000..1fa32df
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png b/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
new file mode 100644
index 0000000..f254477
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..ebe7dd2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..69c3e43
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png b/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
new file mode 100644
index 0000000..b83789c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-fail-manual.sub-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png b/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
new file mode 100644
index 0000000..6b2c3bb
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/appmanifest/start_url-member/start_url-member-pass-manual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..acb5a12
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..0abebca
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..906abfa
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png b/third_party/blink/web_tests/platform/win7/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
new file mode 100644
index 0000000..c6ca020f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win7/virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-intrinsic-track-sizes-001-expected.png
Binary files differ
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index 3511cbe..50540d9 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -23,6 +23,10 @@
     # Build code using -O3, see: crbug.com/1084371.
     configs = [ "//build/config/compiler:optimize_speed" ]
   }
+  if (is_debug || use_libfuzzer) {
+    # Enable zlib's asserts in debug and fuzzer builds.
+    defines += [ "ZLIB_DEBUG" ]
+  }
 }
 
 use_arm_neon_optimizations = false
diff --git a/third_party/zlib/contrib/optimizations/chunkcopy.h b/third_party/zlib/contrib/optimizations/chunkcopy.h
index 7cbcf82..25d4fe1 100644
--- a/third_party/zlib/contrib/optimizations/chunkcopy.h
+++ b/third_party/zlib/contrib/optimizations/chunkcopy.h
@@ -112,6 +112,10 @@
   Assert(out + len <= limit, "chunk copy exceeds safety limit");
   if ((limit - out) < (ptrdiff_t)CHUNKCOPY_CHUNK_SIZE) {
     const unsigned char FAR* Z_RESTRICT rfrom = from;
+    Assert((uintptr_t)out - (uintptr_t)from >= len,
+           "invalid restrict in chunkcopy_core_safe");
+    Assert((uintptr_t)from - (uintptr_t)out >= len,
+           "invalid restrict in chunkcopy_core_safe");
     if (len & 8) {
       Z_BUILTIN_MEMCPY(out, rfrom, 8);
       out += 8;
@@ -338,6 +342,10 @@
     unsigned char FAR* Z_RESTRICT out,
     const unsigned char FAR* Z_RESTRICT from,
     unsigned len) {
+  Assert((uintptr_t)out - (uintptr_t)from >= len,
+         "invalid restrict in chunkcopy_relaxed");
+  Assert((uintptr_t)from - (uintptr_t)out >= len,
+         "invalid restrict in chunkcopy_relaxed");
   return chunkcopy_core(out, from, len);
 }
 
@@ -360,6 +368,11 @@
     unsigned len,
     unsigned char FAR* limit) {
   Assert(out + len <= limit, "chunk copy exceeds safety limit");
+  Assert((uintptr_t)out - (uintptr_t)from >= len,
+         "invalid restrict in chunkcopy_safe");
+  Assert((uintptr_t)from - (uintptr_t)out >= len,
+         "invalid restrict in chunkcopy_safe");
+
   return chunkcopy_core_safe(out, from, len, limit);
 }
 
diff --git a/third_party/zlib/contrib/tests/fuzzers/BUILD.gn b/third_party/zlib/contrib/tests/fuzzers/BUILD.gn
index 34c3b43..10abe00 100644
--- a/third_party/zlib/contrib/tests/fuzzers/BUILD.gn
+++ b/third_party/zlib/contrib/tests/fuzzers/BUILD.gn
@@ -18,6 +18,12 @@
   deps = [ "../../../:zlib" ]
 }
 
+fuzzer_test("zlib_streaming_inflate_fuzzer") {
+  sources = [ "streaming_inflate_fuzzer.cc" ]
+  deps = [ "../../../:zlib" ]
+  libfuzzer_options = [ "max_len=256000" ]
+}
+
 fuzzer_test("zlib_deflate_set_dictionary_fuzzer") {
   sources = [ "deflate_set_dictionary_fuzzer.cc" ]
   deps = [ "../../../:zlib" ]
diff --git a/third_party/zlib/contrib/tests/fuzzers/streaming_inflate_fuzzer.cc b/third_party/zlib/contrib/tests/fuzzers/streaming_inflate_fuzzer.cc
new file mode 100644
index 0000000..de4d216
--- /dev/null
+++ b/third_party/zlib/contrib/tests/fuzzers/streaming_inflate_fuzzer.cc
@@ -0,0 +1,74 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "third_party/zlib/zlib.h"
+
+// Fuzzer builds often have NDEBUG set, so roll our own assert macro.
+#define ASSERT(cond)                                                           \
+  do {                                                                         \
+    if (!(cond)) {                                                             \
+      fprintf(stderr, "%s:%d Assert failed: %s\n", __FILE__, __LINE__, #cond); \
+      exit(1);                                                                 \
+    }                                                                          \
+  } while (0)
+
+// Entry point for LibFuzzer.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  // Deflate data.
+  z_stream comp_strm;
+  comp_strm.zalloc = Z_NULL;
+  comp_strm.zfree = Z_NULL;
+  comp_strm.opaque = Z_NULL;
+  int ret = deflateInit(&comp_strm, Z_DEFAULT_COMPRESSION);
+  ASSERT(ret == Z_OK);
+
+  size_t comp_buf_cap = deflateBound(&comp_strm, size);
+  uint8_t* comp_buf = (uint8_t*)malloc(comp_buf_cap);
+  ASSERT(comp_buf != nullptr);
+  comp_strm.next_out = comp_buf;
+  comp_strm.avail_out = comp_buf_cap;
+  comp_strm.next_in = (unsigned char*)data;
+  comp_strm.avail_in = size;
+  ret = deflate(&comp_strm, Z_FINISH);
+  ASSERT(ret == Z_STREAM_END);
+  size_t comp_sz = comp_buf_cap - comp_strm.avail_out;
+
+  // Inflate comp_buf one chunk at a time.
+  z_stream decomp_strm;
+  decomp_strm.zalloc = Z_NULL;
+  decomp_strm.zfree = Z_NULL;
+  decomp_strm.opaque = Z_NULL;
+  ret = inflateInit(&decomp_strm);
+  ASSERT(ret == Z_OK);
+  decomp_strm.next_in = comp_buf;
+  decomp_strm.avail_in = comp_sz;
+
+  while (decomp_strm.avail_in > 0) {
+    uint8_t decomp_buf[1024];
+    decomp_strm.next_out = decomp_buf;
+    decomp_strm.avail_out = sizeof(decomp_buf);
+    ret = inflate(&decomp_strm, Z_FINISH);
+    ASSERT(ret == Z_OK || ret == Z_STREAM_END || ret == Z_BUF_ERROR);
+
+    // Verify the output bytes.
+    size_t num_out = sizeof(decomp_buf) - decomp_strm.avail_out;
+    for (size_t i = 0; i < num_out; i++) {
+      ASSERT(decomp_buf[i] == data[decomp_strm.total_out - num_out + i]);
+    }
+  }
+
+  ret = deflateEnd(&comp_strm);
+  ASSERT(ret == Z_OK);
+  free(comp_buf);
+
+  inflateEnd(&decomp_strm);
+  ASSERT(ret == Z_OK);
+
+  return 0;
+}
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 40ead3f..2bf88e7 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -7409,6 +7409,11 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="IncognitoMenu_ExitClicked">
+  <owner>rhalavati@chromium.org</owner>
+  <description>User clicked on Exit Incognito button.</description>
+</action>
+
 <action name="IncognitoMenu_Show">
   <owner>rhalavati@chromium.org.</owner>
   <description>The user opened incognito menu.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index d70f5628..6260b11e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -70606,6 +70606,26 @@
   </summary>
 </histogram>
 
+<histogram name="InputMethod.Assistive.TimeToAccept.Emoji" units="ms"
+    expires_after="2021-01-01">
+  <owner>myy@google.com</owner>
+  <owner>essential-inputs-team@google.com</owner>
+  <summary>
+    The duration from when emoji suggestions show up to when users accept a
+    suggestion. Recorded when users accept the suggestion.
+  </summary>
+</histogram>
+
+<histogram name="InputMethod.Assistive.TimeToDismiss.Emoji" units="ms"
+    expires_after="2021-01-01">
+  <owner>myy@google.com</owner>
+  <owner>essential-inputs-team@google.com</owner>
+  <summary>
+    The duration from when emoji suggestions show up to when users dismiss a
+    suggestion. Recorded when users dismiss the suggestion.
+  </summary>
+</histogram>
+
 <histogram name="InputMethod.Assistive.UserPref.Emoji" enum="BooleanEnabled"
     expires_after="2021-01-01">
   <owner>myy@google.com</owner>
@@ -126689,8 +126709,8 @@
 
 <histogram
     name="PasswordManager.IsSyncPasswordHashSavedForAdvancedProtectionUser"
-    enum="IsSyncPasswordHashSaved" expires_after="2020-09-04">
-  <owner>vakh@chromium.org</owner>
+    enum="IsSyncPasswordHashSaved" expires_after="2021-02-04">
+  <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
     This metric is recorded shortly after Chrome Startup, only for Advanced
@@ -142040,7 +142060,7 @@
 </histogram>
 
 <histogram name="Quota.SkippedInvalidOriginUsage" enum="InvalidOriginReason"
-    expires_after="2020-08-04">
+    expires_after="2021-08-04">
   <owner>jarrydg@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index c9296f9..8a7b9cf6 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -10,7 +10,7 @@
         },
         "linux": {
             "hash": "8e5359ee0d4eb46c60cd654a9f918ead325ab596",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/9a482652ab182496ba1ea2d3f391b187f5ff80f7/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/f3bd050745701c186d8ee974b4843526ae154185/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/accessibility/ax_tree_combiner.cc b/ui/accessibility/ax_tree_combiner.cc
index 23200e1..9c251d1 100644
--- a/ui/accessibility/ax_tree_combiner.cc
+++ b/ui/accessibility/ax_tree_combiner.cc
@@ -17,6 +17,11 @@
 }
 
 void AXTreeCombiner::AddTree(const AXTreeUpdate& tree, bool is_root) {
+  if (tree.tree_data.tree_id == AXTreeIDUnknown()) {
+    LOG(WARNING) << "Skipping AXTreeID because its tree ID is unknown";
+    return;
+  }
+
   trees_.push_back(tree);
   if (is_root) {
     DCHECK_EQ(root_tree_id_, AXTreeIDUnknown());
diff --git a/ui/accessibility/platform/ax_platform_node.cc b/ui/accessibility/platform/ax_platform_node.cc
index 6bf1a7a..4f8d630 100644
--- a/ui/accessibility/platform/ax_platform_node.cc
+++ b/ui/accessibility/platform/ax_platform_node.cc
@@ -62,6 +62,14 @@
   return GetDelegate() ? GetDelegate()->GetUniqueId().Get() : -1;
 }
 
+void AXPlatformNode::SetIsPrimaryWebContentsForWindow(bool is_primary) {
+  is_primary_web_contents_for_window_ = is_primary;
+}
+
+bool AXPlatformNode::IsPrimaryWebContentsForWindow() const {
+  return is_primary_web_contents_for_window_;
+}
+
 std::string AXPlatformNode::ToString() {
   return GetDelegate() ? GetDelegate()->ToString() : "No delegate";
 }
diff --git a/ui/accessibility/platform/ax_platform_node.h b/ui/accessibility/platform/ax_platform_node.h
index 24b33ca8..e8ad7ed 100644
--- a/ui/accessibility/platform/ax_platform_node.h
+++ b/ui/accessibility/platform/ax_platform_node.h
@@ -92,6 +92,10 @@
   // Return true if this object is equal to or a descendant of |ancestor|.
   virtual bool IsDescendantOf(AXPlatformNode* ancestor) const = 0;
 
+  // Set |this| as the primary web contents for the window.
+  void SetIsPrimaryWebContentsForWindow(bool is_primary);
+  bool IsPrimaryWebContentsForWindow() const;
+
   // Return the unique ID.
   int32_t GetUniqueId() const;
 
@@ -125,6 +129,8 @@
   // underlying content.
   static gfx::NativeViewAccessible popup_focus_override_;
 
+  bool is_primary_web_contents_for_window_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(AXPlatformNode);
 };
 
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 2fe51ea5..af7f130 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2497,7 +2497,10 @@
   frame->SetDocumentParent(parent_atk_object);
 }
 
-AtkObject* AXPlatformNodeAuraLinux::FindFirstWebContentDocument() {
+AtkObject* AXPlatformNodeAuraLinux::FindPrimaryWebContentDocument() {
+  // It could get multiple web contents since additional web content is added,
+  // when the DevTools window is opened.
+  std::vector<AtkObject*> web_content_candidates;
   for (auto child_iterator_ptr = GetDelegate()->ChildrenBegin();
        *child_iterator_ptr != *GetDelegate()->ChildrenEnd();
        ++(*child_iterator_ptr)) {
@@ -2509,12 +2512,36 @@
       continue;
     if (child_node->GetAtkRole() != ATK_ROLE_DOCUMENT_WEB)
       continue;
-    return child;
+    web_content_candidates.push_back(child);
   }
 
+  if (web_content_candidates.empty())
+    return nullptr;
+
+  // If it finds just one web content, return it.
+  if (web_content_candidates.size() == 1)
+    return web_content_candidates[0];
+
+  for (auto* object : web_content_candidates) {
+    auto* child_node = AXPlatformNodeAuraLinux::FromAtkObject(object);
+    // If it is a primary web contents, return it.
+    if (child_node->IsPrimaryWebContentsForWindow())
+      return object;
+  }
   return nullptr;
 }
 
+bool AXPlatformNodeAuraLinux::IsWebDocumentForRelations() {
+  AtkObject* atk_object = GetOrCreateAtkObject();
+  if (!atk_object)
+    return false;
+  AXPlatformNodeAuraLinux* parent = FromAtkObject(GetParent());
+  if (!parent || !GetDelegate()->IsWebContent() ||
+      GetAtkRole() != ATK_ROLE_DOCUMENT_WEB)
+    return false;
+  return parent->FindPrimaryWebContentDocument() == atk_object;
+}
+
 AtkObject* AXPlatformNodeAuraLinux::CreateAtkObject() {
   if (GetData().role != ax::mojom::Role::kApplication &&
       !GetDelegate()->IsToplevelBrowserWindow() &&
@@ -3183,7 +3210,7 @@
 
   AtkRelationSet* relation_set = atk_relation_set_new();
 
-  if (GetDelegate()->IsWebContent() && GetAtkRole() == ATK_ROLE_DOCUMENT_WEB) {
+  if (IsWebDocumentForRelations()) {
     AtkObject* parent_frame = FindAtkObjectParentFrame(atk_object);
     if (parent_frame) {
       atk_relation_set_add_relation_by_type(
@@ -3192,7 +3219,7 @@
   }
 
   if (auto* document_parent = FromAtkObject(document_parent_)) {
-    AtkObject* document = document_parent->FindFirstWebContentDocument();
+    AtkObject* document = document_parent->FindPrimaryWebContentDocument();
     if (document) {
       atk_relation_set_add_relation_by_type(relation_set, ATK_RELATION_EMBEDS,
                                             document);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index f4cfa87..6c63a19 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -340,8 +340,11 @@
   // the toplevel frame which contains the node.
   void SetDocumentParentOnFrameIfNecessary();
 
-  // Find the first child which is a document containing web content.
-  AtkObject* FindFirstWebContentDocument();
+  // Find the child which is a document containing the primary web content.
+  AtkObject* FindPrimaryWebContentDocument();
+
+  // Returns true if it is a web content for the relations.
+  bool IsWebDocumentForRelations();
 
   // If a selection that intersects this node get the full selection
   // including start and end node ids.
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h
index 04986a89..886c819 100644
--- a/ui/android/delegated_frame_host_android.h
+++ b/ui/android/delegated_frame_host_android.h
@@ -56,8 +56,8 @@
     return base::TimeDelta::FromSeconds(5);
   }
   static int64_t FirstFrameTimeoutFrames() {
-    return base::ClampRound<int64_t>(
-        FirstFrameTimeout().FltDiv(viz::BeginFrameArgs::DefaultInterval()));
+    return base::ClampRound<int64_t>(FirstFrameTimeout() /
+                                     viz::BeginFrameArgs::DefaultInterval());
   }
 
   // Wait up to 1 second for a frame of the correct size to be produced. Android
@@ -67,8 +67,8 @@
     return base::TimeDelta::FromSeconds(1);
   }
   static int64_t ResizeTimeoutFrames() {
-    return base::ClampRound<int64_t>(
-        ResizeTimeout().FltDiv(viz::BeginFrameArgs::DefaultInterval()));
+    return base::ClampRound<int64_t>(ResizeTimeout() /
+                                     viz::BeginFrameArgs::DefaultInterval());
   }
 
   // Advances the fallback surface to the first surface after navigation. This
diff --git a/ui/base/l10n/time_format.cc b/ui/base/l10n/time_format.cc
index 41f1881..2e51714 100644
--- a/ui/base/l10n/time_format.cc
+++ b/ui/base/l10n/time_format.cc
@@ -130,13 +130,13 @@
     }
   } else if (delta < kYear) {
     DCHECK(with_month_and_year);
-    const int month = delta.IntDiv(kMonth);
+    const int month = base::ClampFloor(delta / kMonth);
     DCHECK_GE(month, 1);
     DCHECK_LE(month, 12);
     formatter->Format(Formatter::UNIT_MONTH, month, &time_string);
   } else {
     DCHECK(with_month_and_year);
-    const int year = delta.IntDiv(kYear);
+    const int year = base::ClampFloor(delta / kYear);
     formatter->Format(Formatter::UNIT_YEAR, year, &time_string);
   }
 
diff --git a/ui/events/gesture_detection/motion_event_buffer_unittest.cc b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
index 7dfe70a..d40656d5 100644
--- a/ui/events/gesture_detection/motion_event_buffer_unittest.cc
+++ b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <stddef.h>
 
+#include "base/numerics/safe_conversions.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/gesture_detection/motion_event_buffer.h"
@@ -170,9 +171,9 @@
         event_time + flush_time_delta - event_time_offset;
     base::TimeTicks max_event_time =
         event_time + base::TimeDelta::FromSecondsD(0.5f);
-    const size_t min_expected_events = static_cast<size_t>(
-        (max_event_time - flush_time)
-            .IntDiv(std::max(event_time_delta, flush_time_delta)));
+    const size_t min_expected_events =
+        base::ClampFloor<size_t>((max_event_time - flush_time) /
+                                 std::max(event_time_delta, flush_time_delta));
 
     MotionEventBuffer buffer(this, true);
 
diff --git a/ui/gfx/paint_throbber.cc b/ui/gfx/paint_throbber.cc
index c7bd67d..66f4336 100644
--- a/ui/gfx/paint_throbber.cc
+++ b/ui/gfx/paint_throbber.cc
@@ -73,7 +73,7 @@
   int64_t twelve_oclock = 90;
   int64_t finish_angle_cc =
       twelve_oclock +
-      base::ClampRound<int64_t>(elapsed_time.FltDiv(kRevolutionTime) * 360);
+      base::ClampRound<int64_t>(elapsed_time / kRevolutionTime * 360);
   int64_t start_angle_cc = std::max(finish_angle_cc - 180, twelve_oclock);
 
   // Negate the angles to convert to the clockwise numbers Skia expects.
@@ -100,7 +100,8 @@
   // This tween is equivalent to cubic-bezier(0.4, 0.0, 0.2, 1).
   double sweep = kMaxArcSize *
                  Tween::CalculateValue(Tween::FAST_OUT_SLOW_IN, arc_progress);
-  const int64_t sweep_frame = elapsed_time.IntDiv(kArcTime);
+  const int64_t sweep_frame =
+      base::ClampFloor<int64_t>(elapsed_time / kArcTime);
   if (sweep_frame % 2 == 0)
     sweep -= kMaxArcSize;
 
@@ -130,7 +131,7 @@
                            const base::TimeDelta& elapsed_time,
                            base::Optional<SkScalar> stroke_width) {
   const int64_t start_angle =
-      270 + base::ClampRound<int64_t>(elapsed_time.FltDiv(kRotationTime) * 360);
+      270 + base::ClampRound<int64_t>(elapsed_time / kRotationTime * 360);
   PaintThrobberSpinningWithStartAngle(canvas, bounds, color, elapsed_time,
                                       start_angle, stroke_width);
 }
@@ -183,7 +184,7 @@
 
   const int64_t start_angle =
       waiting_start_angle +
-      base::ClampRound<int64_t>(elapsed_time.FltDiv(kRotationTime) * 360);
+      base::ClampRound<int64_t>(elapsed_time / kRotationTime * 360);
   const base::TimeDelta effective_elapsed_time =
       elapsed_time + waiting_state->arc_time_offset;
 
diff --git a/ui/message_center/views/relative_time_formatter.cc b/ui/message_center/views/relative_time_formatter.cc
index 36b6c67..6053884 100644
--- a/ui/message_center/views/relative_time_formatter.cc
+++ b/ui/message_center/views/relative_time_formatter.cc
@@ -4,6 +4,7 @@
 
 #include "ui/message_center/views/relative_time_formatter.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "base/stl_util.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/strings/grit/ui_strings.h"
@@ -69,7 +70,7 @@
   }
 
   int string_id = past ? format.past : format.future;
-  int count = static_cast<int>(absolute.IntDiv(format.range));
+  int count = base::ClampFloor(absolute / format.range);
   TimeDelta delay = past
                         ? format.range * (count + 1)
                         : TimeDelta::FromMilliseconds(1) - format.range * count;
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc
index b3c8633f..639ba0b 100644
--- a/ui/views/controls/webview/webview.cc
+++ b/ui/views/controls/webview/webview.cc
@@ -272,8 +272,17 @@
   if (web_contents() && !web_contents()->IsCrashed()) {
     content::RenderWidgetHostView* host_view =
         web_contents()->GetRenderWidgetHostView();
-    if (host_view)
-      return host_view->GetNativeViewAccessible();
+    if (host_view) {
+      gfx::NativeViewAccessible accessible =
+          host_view->GetNativeViewAccessible();
+      // |accessible| needs to know whether this is the primary WebContents.
+      if (auto* ax_platform_node =
+              ui::AXPlatformNode::FromNativeViewAccessible(accessible)) {
+        ax_platform_node->SetIsPrimaryWebContentsForWindow(
+            is_primary_web_contents_for_window_);
+      }
+      return accessible;
+    }
   }
   return View::GetNativeViewAccessible();
 }
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h
index cfcf301..f18eea14 100644
--- a/ui/views/controls/webview/webview.h
+++ b/ui/views/controls/webview/webview.h
@@ -89,6 +89,11 @@
   // if the web contents is changed.
   void SetCrashedOverlayView(View* crashed_overlay_view);
 
+  // Sets whether this is the primary web contents for the window.
+  void set_is_primary_web_contents_for_window(bool is_primary) {
+    is_primary_web_contents_for_window_ = is_primary;
+  }
+
   // When used to host UI, we need to explicitly allow accelerators to be
   // processed. Default is false.
   void set_allow_accelerators(bool allow_accelerators) {
@@ -199,6 +204,7 @@
   content::BrowserContext* browser_context_;
   bool allow_accelerators_ = false;
   View* crashed_overlay_view_ = nullptr;
+  bool is_primary_web_contents_for_window_ = false;
 
   // Minimum and maximum sizes to determine WebView bounds for auto-resizing.
   // Empty if auto resize is not enabled.
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index ffb6b52a..c73a95e 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -372,22 +372,25 @@
 #if defined(OS_ANDROID)
     BrowserContextImpl* browser_context_impl =
         static_cast<BrowserContextImpl*>(browser_context);
-    bool is_real_time_lookup_enabled =
-        !GetSafeBrowsingService()->GetSafeBrowsingDisabled() &&
-        safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup(
-            browser_context_impl->pref_service(),
-            browser_context_impl->IsOffTheRecord(),
-            FeatureListCreator::GetInstance()->variations_service());
+    bool is_safe_browsing_enabled = safe_browsing::IsSafeBrowsingEnabled(
+        *browser_context_impl->pref_service());
 
-    // |url_lookup_service| is used when real time url check is enabled.
-    safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service =
-        is_real_time_lookup_enabled
-            ? RealTimeUrlLookupServiceFactory::GetForBrowserContext(
-                  browser_context)
-            : nullptr;
+    if (is_safe_browsing_enabled) {
+      bool is_real_time_lookup_enabled =
+          safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup(
+              browser_context_impl->pref_service(),
+              browser_context_impl->IsOffTheRecord(),
+              FeatureListCreator::GetInstance()->variations_service());
 
-    result.push_back(GetSafeBrowsingService()->CreateURLLoaderThrottle(
-        wc_getter, frame_tree_node_id, url_lookup_service));
+      // |url_lookup_service| is used when real time url check is enabled.
+      safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service =
+          is_real_time_lookup_enabled
+              ? RealTimeUrlLookupServiceFactory::GetForBrowserContext(
+                    browser_context)
+              : nullptr;
+      result.push_back(GetSafeBrowsingService()->CreateURLLoaderThrottle(
+          wc_getter, frame_tree_node_id, url_lookup_service));
+    }
 #endif
   }
 
diff --git a/weblayer/browser/profile_impl.cc b/weblayer/browser/profile_impl.cc
index 5d58d82c..7d77507b 100644
--- a/weblayer/browser/profile_impl.cc
+++ b/weblayer/browser/profile_impl.cc
@@ -507,11 +507,10 @@
   auto* pref_service = GetBrowserContext()->pref_service();
   switch (type) {
     case SettingType::BASIC_SAFE_BROWSING_ENABLED:
-      basic_safe_browsing_enabled_ = value;
 #if defined(OS_ANDROID)
-      BrowserProcess::GetInstance()
-          ->GetSafeBrowsingService(weblayer::GetUserAgent())
-          ->SetSafeBrowsingDisabled(!basic_safe_browsing_enabled_);
+      safe_browsing::SetSafeBrowsingState(
+          pref_service, value ? safe_browsing::STANDARD_PROTECTION
+                              : safe_browsing::NO_SAFE_BROWSING);
 #endif
       break;
     case SettingType::UKM_ENABLED: {
@@ -546,7 +545,10 @@
   auto* pref_service = GetBrowserContext()->pref_service();
   switch (type) {
     case SettingType::BASIC_SAFE_BROWSING_ENABLED:
-      return basic_safe_browsing_enabled_;
+#if defined(OS_ANDROID)
+      return safe_browsing::IsSafeBrowsingEnabled(*pref_service);
+#endif
+      return false;
     case SettingType::UKM_ENABLED:
       return pref_service->GetBoolean(prefs::kUkmEnabled);
     case SettingType::EXTENDED_REPORTING_SAFE_BROWSING_ENABLED:
diff --git a/weblayer/browser/profile_impl.h b/weblayer/browser/profile_impl.h
index c559488..884ec05 100644
--- a/weblayer/browser/profile_impl.h
+++ b/weblayer/browser/profile_impl.h
@@ -158,8 +158,6 @@
 
   std::unique_ptr<CookieManagerImpl> cookie_manager_;
 
-  bool basic_safe_browsing_enabled_ = true;
-
 #if defined(OS_ANDROID)
   base::android::ScopedJavaGlobalRef<jobject> java_profile_;
 #endif
diff --git a/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
index 1cd3bc1a..0af1ccd 100644
--- a/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
+++ b/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
@@ -4,16 +4,22 @@
 
 #include <map>
 
+#include "components/prefs/pref_service.h"
 #include "components/safe_browsing/android/safe_browsing_api_handler.h"
 #include "components/safe_browsing/content/base_blocking_page.h"
 #include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/content/security_interstitial_page.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
+#include "components/user_prefs/user_prefs.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "weblayer/browser/browser_context_impl.h"
+#include "weblayer/browser/browser_impl.h"
 #include "weblayer/browser/profile_impl.h"
 #include "weblayer/browser/safe_browsing/safe_browsing_blocking_page.h"
 #include "weblayer/browser/tab_impl.h"
@@ -80,14 +86,17 @@
   SafeBrowsingBrowserTest() : fake_handler_(new FakeSafeBrowsingApiHandler()) {}
   ~SafeBrowsingBrowserTest() override = default;
 
-  // WebLayerBrowserTest:
   void SetUpOnMainThread() override {
+    InitializeOnMainThread();
+    // Safe Browsing is enabled by default
+    ASSERT_TRUE(GetSafeBrowsingEnabled());
+  }
+
+  void InitializeOnMainThread() {
     NavigateAndWaitForCompletion(GURL("about:blank"), shell());
     safe_browsing::SafeBrowsingApiHandler::SetInstance(fake_handler_.get());
     ASSERT_TRUE(embedded_test_server()->Start());
     url_ = embedded_test_server()->GetURL("/simple_page.html");
-    // Safe Browsing is enabled by default
-    ASSERT_TRUE(GetSafeBrowsingEnabled());
   }
 
   void SetSafeBrowsingEnabled(bool value) {
@@ -149,6 +158,19 @@
 
   bool HasInterstitial() { return GetSecurityInterstitialPage() != nullptr; }
 
+  void KillRenderer() {
+    content::RenderProcessHost* child_process =
+        static_cast<TabImpl*>(shell()->tab())
+            ->web_contents()
+            ->GetMainFrame()
+            ->GetProcess();
+    content::RenderProcessHostWatcher crash_observer(
+        child_process,
+        content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+    child_process->Shutdown(0);
+    crash_observer.Wait();
+  }
+
   std::unique_ptr<FakeSafeBrowsingApiHandler> fake_handler_;
   GURL url_;
 
@@ -156,6 +178,21 @@
   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBrowserTest);
 };
 
+class SafeBrowsingDisabledBrowserTest : public SafeBrowsingBrowserTest {
+ public:
+  SafeBrowsingDisabledBrowserTest() {}
+  ~SafeBrowsingDisabledBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    SetSafeBrowsingEnabled(false);
+    SafeBrowsingBrowserTest::InitializeOnMainThread();
+    ASSERT_FALSE(GetSafeBrowsingEnabled());
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDisabledBrowserTest);
+};
+
 IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
                        DoesNotShowInterstitial_NoRestriction) {
   Navigate(url_, false);
@@ -188,46 +225,63 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_NoRestriction_disableSB) {
-  SetSafeBrowsingEnabled(false);
-  EXPECT_FALSE(GetSafeBrowsingEnabled());
-  Navigate(url_, false);
-}
-
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_Safe_disableSB) {
-  SetSafeBrowsingEnabled(false);
-  EXPECT_FALSE(GetSafeBrowsingEnabled());
-  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false);
-}
-
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_Malware_disableSB) {
-  SetSafeBrowsingEnabled(false);
-  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false);
-}
-
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
                        DoesNotShowInterstitial_Phishing_disableSB) {
+  // Test that the browser checks the safe browsing setting for new navigations.
   SetSafeBrowsingEnabled(false);
   NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, false);
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_Unwanted_disableSB) {
+                       DoesNotShowInterstitial_Malware_Subresource_disableSB) {
+  // Test that new renderer checks the safe browsing setting.
   SetSafeBrowsingEnabled(false);
+  KillRenderer();
+  NavigateWithSubResourceAndThreatType(
+      safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckSetsPrefs) {
+  // Check that changing safe browsing setting sets corresponding pref,
+  // which is persistent.
+  PrefService* prefs = GetProfile()->GetBrowserContext()->pref_service();
+  SetSafeBrowsingEnabled(true);
+  EXPECT_TRUE(prefs->GetBoolean(::prefs::kSafeBrowsingEnabled));
+  SetSafeBrowsingEnabled(false);
+  EXPECT_FALSE(prefs->GetBoolean(::prefs::kSafeBrowsingEnabled));
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_NoRestriction) {
+  Navigate(url_, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Safe) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Malware) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Phishing) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Unwanted) {
   NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, false);
 }
 
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_Billing_disableSB) {
-  SetSafeBrowsingEnabled(false);
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Billing) {
   NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, false);
 }
 
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
-                       DoesNotShowInterstitial_Malware_Subresource_disableSB) {
-  SetSafeBrowsingEnabled(false);
+IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest,
+                       DoesNotShowInterstitial_Malware_Subresource) {
   NavigateWithSubResourceAndThreatType(
       safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false);
 }
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.cc b/weblayer/browser/safe_browsing/safe_browsing_service.cc
index 328f00d..fca167f 100644
--- a/weblayer/browser/safe_browsing/safe_browsing_service.cc
+++ b/weblayer/browser/safe_browsing/safe_browsing_service.cc
@@ -6,11 +6,13 @@
 
 #include "base/bind.h"
 #include "base/path_service.h"
+#include "components/prefs/pref_service.h"
 #include "components/safe_browsing/android/remote_database_manager.h"
 #include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h"
 #include "components/safe_browsing/content/browser/browser_url_loader_throttle.h"
 #include "components/safe_browsing/content/browser/mojo_safe_browsing_impl.h"
 #include "components/safe_browsing/core/browser/safe_browsing_network_context.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/core/realtime/url_lookup_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -21,6 +23,7 @@
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "third_party/blink/public/common/loader/url_loader_throttle.h"
+#include "weblayer/browser/browser_context_impl.h"
 #include "weblayer/browser/safe_browsing/safe_browsing_navigation_throttle.h"
 #include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h"
 
@@ -38,8 +41,9 @@
   return network_context_params;
 }
 
-// Helper method that checks the RenderProcessHost is still alive before hopping
-// over to the IO thread.
+// Helper method that checks the RenderProcessHost is still alive and checks the
+// latest Safe Browsing pref value on the UI thread before hopping over to the
+// IO thread.
 void MaybeCreateSafeBrowsing(
     int rph_id,
     content::ResourceContext* resource_context,
@@ -53,6 +57,14 @@
   if (!render_process_host)
     return;
 
+  bool is_safe_browsing_enabled = safe_browsing::IsSafeBrowsingEnabled(
+      *static_cast<BrowserContextImpl*>(
+           render_process_host->GetBrowserContext())
+           ->pref_service());
+
+  if (!is_safe_browsing_enabled)
+    return;
+
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(&safe_browsing::MojoSafeBrowsingImpl::MaybeCreate, rph_id,
@@ -63,7 +75,7 @@
 }  // namespace
 
 SafeBrowsingService::SafeBrowsingService(const std::string& user_agent)
-    : user_agent_(user_agent), safe_browsing_disabled_(false) {}
+    : user_agent_(user_agent) {}
 
 SafeBrowsingService::~SafeBrowsingService() = default;
 
@@ -124,8 +136,7 @@
 
   if (!safe_browsing_url_checker_delegate_) {
     safe_browsing_url_checker_delegate_ = new UrlCheckerDelegateImpl(
-        GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager(),
-        safe_browsing_disabled_);
+        GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager());
   }
 
   return safe_browsing_url_checker_delegate_;
@@ -217,26 +228,6 @@
   }
 }
 
-void SafeBrowsingService::SetSafeBrowsingDisabled(bool disabled) {
-  content::GetIOThreadTaskRunner({})->PostTask(
-      FROM_HERE,
-      base::BindOnce(&SafeBrowsingService::SetSafeBrowsingDisabledOnIOThread,
-                     base::Unretained(this), disabled));
-}
-
-void SafeBrowsingService::SetSafeBrowsingDisabledOnIOThread(bool disabled) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-  if (safe_browsing_disabled_ != disabled) {
-    safe_browsing_disabled_ = disabled;
-    // If there is no safe_browsing_url_checker_delegate_ yet the opt_out
-    // setting will be set later during its creation.
-    if (safe_browsing_url_checker_delegate_) {
-      safe_browsing_url_checker_delegate_->SetSafeBrowsingDisabled(disabled);
-    }
-  }
-}
-
 scoped_refptr<network::SharedURLLoaderFactory>
 SafeBrowsingService::GetURLLoaderFactory() {
   if (!network_context_)
@@ -244,8 +235,4 @@
   return network_context_->GetURLLoaderFactory();
 }
 
-bool SafeBrowsingService::GetSafeBrowsingDisabled() {
-  return safe_browsing_disabled_;
-}
-
 }  // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.h b/weblayer/browser/safe_browsing/safe_browsing_service.h
index 668cb05..1de5c0f 100644
--- a/weblayer/browser/safe_browsing/safe_browsing_service.h
+++ b/weblayer/browser/safe_browsing/safe_browsing_service.h
@@ -57,8 +57,6 @@
   void AddInterface(service_manager::BinderRegistry* registry,
                     content::RenderProcessHost* render_process_host);
   void StopDBManager();
-  void SetSafeBrowsingDisabled(bool disabled);
-  bool GetSafeBrowsingDisabled();
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
 
  private:
@@ -76,7 +74,6 @@
   void CreateURLLoaderFactoryForIO(
       mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
   void StopDBManagerOnIOThread();
-  void SetSafeBrowsingDisabledOnIOThread(bool disabled);
 
   // The UI manager handles showing interstitials. Accessed on both UI and IO
   // thread.
@@ -102,8 +99,6 @@
 
   std::string user_agent_;
 
-  bool safe_browsing_disabled_;
-
   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService);
 };
 
diff --git a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc b/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
index dd7ad56..7ff46a31 100644
--- a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
+++ b/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -15,11 +15,9 @@
 
 UrlCheckerDelegateImpl::UrlCheckerDelegateImpl(
     scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
-    scoped_refptr<SafeBrowsingUIManager> ui_manager,
-    bool disabled)
+    scoped_refptr<SafeBrowsingUIManager> ui_manager)
     : database_manager_(std::move(database_manager)),
       ui_manager_(std::move(ui_manager)),
-      safe_browsing_disabled_(disabled),
       threat_types_(safe_browsing::CreateSBThreatTypeSet(
           {safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
            safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
@@ -70,17 +68,13 @@
   return false;
 }
 
-void UrlCheckerDelegateImpl::SetSafeBrowsingDisabled(bool disabled) {
-  safe_browsing_disabled_ = disabled;
-}
-
 bool UrlCheckerDelegateImpl::ShouldSkipRequestCheck(
     const GURL& original_url,
     int frame_tree_node_id,
     int render_process_id,
     int render_frame_id,
     bool originated_from_service_worker) {
-  return safe_browsing_disabled_ ? true : false;
+  return false;
 }
 
 void UrlCheckerDelegateImpl::NotifySuspiciousSiteDetected(
diff --git a/weblayer/browser/safe_browsing/url_checker_delegate_impl.h b/weblayer/browser/safe_browsing/url_checker_delegate_impl.h
index d59745b..c940d7f7 100644
--- a/weblayer/browser/safe_browsing/url_checker_delegate_impl.h
+++ b/weblayer/browser/safe_browsing/url_checker_delegate_impl.h
@@ -23,8 +23,7 @@
   UrlCheckerDelegateImpl(
       scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
           database_manager,
-      scoped_refptr<SafeBrowsingUIManager> ui_manager,
-      bool disabled);
+      scoped_refptr<SafeBrowsingUIManager> ui_manager);
 
   void SetSafeBrowsingDisabled(bool disabled);
 
@@ -61,7 +60,6 @@
 
   scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
   scoped_refptr<SafeBrowsingUIManager> ui_manager_;
-  bool safe_browsing_disabled_;
   safe_browsing::SBThreatTypeSet threat_types_;
 
   DISALLOW_COPY_AND_ASSIGN(UrlCheckerDelegateImpl);