diff --git a/BUILD.gn b/BUILD.gn
index 6e6e8a8..b309339 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -650,7 +650,11 @@
   }
 
   if (is_chromecast) {
-    deps += [ "//chromecast:cast_shell" ]
+    deps += [ "//chromecast:cast_test_lists" ]
+
+    if (!is_fuchsia) {
+      deps += [ "//chromecast:cast_shell" ]
+    }
     if (enable_extensions && use_aura) {
       deps += [ "//chrome/browser/resources/chromeos/accessibility/chromevox" ]
     }
diff --git a/DEPS b/DEPS
index 229fc62..f19fdeea 100644
--- a/DEPS
+++ b/DEPS
@@ -175,11 +175,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': 'fdb2b7d530383d85956b883779209a0627cc275b',
+  'skia_revision': '21df075cab00b771ffc495707bb59d14160df513',
   # 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': '29760046ff9e33dec7fa39cf2cf77577c836b525',
+  'v8_revision': '3e618bf6f5df3bdcb906db22d65671971c74038d',
   # 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.
@@ -187,15 +187,15 @@
   # 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': '7587588595901010a7b8d8683d06796ae420edb8',
+  'angle_revision': '65e2f03bd23e08c3dbb2e352cc494a7b4acb276c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': 'fbbfeb700295d1fe1ec6419a93594e5e1540ea32',
+  'swiftshader_revision': '21be09d8e6990e0ef61de062939a8ea08f2bb3d1',
   # 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': 'f3163cf2ed39849aecbcb10c38b241634e647039',
+  'pdfium_revision': '8cb6a652ad24ac7c4fc84170c976ce701ba8880e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -238,7 +238,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': 'ba22253ee917ef8b05185302ef7b0706363a6b17',
+  'catapult_revision': 'd04ef219ddbf4278e00baee7dc5c516ad9a44f21',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -246,7 +246,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': 'da2f64ae4a747fc868ca05a851f1d650ba7701a3',
+  'devtools_frontend_revision': '2abdc799d9741b743fc308a9f5ee42c3bd34b5bf',
   # 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.
@@ -306,11 +306,11 @@
   # 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': '1bbbe8f52da580bd245af733e068eaabacf72731',
+  'dawn_revision': '3d2d62813fc57ffc56cc4ee342e2e210b26664a8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'ab93f588da756a727562e5d3a62f52f7c89f8255',
+  'quiche_revision': 'ce445c76dfa2fba01e93e96df66f6707a7fb3d11',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -533,7 +533,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '2cfacf6ee93083a52abe6568b40d6b1da471ed8d',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '286cf2ae8c6f0509b15380b1992bac813c05e7e0',
       'condition': 'checkout_ios',
   },
 
@@ -864,7 +864,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '3c5c3d31fe5d54054b75b7e01b5f72cec9df4d76',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f5a3b2d93548c83fc090cdf7b61d723b22716d3b',
       'condition': 'checkout_linux',
   },
 
@@ -889,7 +889,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ba4699fef545e5b9dcd00d626b09f13bccce4c4f',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6037820448a9dbe4f53902edf438a9ad5a6cac5d',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1295,7 +1295,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bd963dc116517241b00a1115ca1123d914024852',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5b3d06c520dbb264e6bcd30629ebad010b889e7e',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1496,7 +1496,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'dd55f3ca8f2ea716ca917a4aaf36f0729fe902b1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '3a8df884d1691260c93da86ce864f8c890e9d155',
+    Var('webrtc_git') + '/src.git' + '@' + '768c5f438cad7b65a05f8a9fe79d4049329e5475',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1566,7 +1566,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a46b4a303829521950cdca5c2e7b87ef05c31850',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a8a2b9c8ebe80d192bec7d37fc103c3da833214c',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 50b5f081..faa4dc4 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -24,30 +24,14 @@
 }
 
 if (public_android_sdk) {
-  template("standalone_system_webview_apk_tmpl") {
-    system_webview_apk_tmpl(target_name) {
-      forward_variables_from(invoker, "*")
-      android_manifest = system_webview_android_manifest
-      android_manifest_dep =
-          "//android_webview/nonembedded:system_webview_manifest"
-      deps = upstream_only_webview_deps
-      min_sdk_version = 21
-    }
-  }
-
   # Standalone WebView APK.
-  standalone_system_webview_apk_tmpl("system_webview_apk") {
+  system_webview_apk_tmpl("system_webview_apk") {
+    android_manifest = system_webview_android_manifest
+    android_manifest_dep =
+        "//android_webview/nonembedded:system_webview_manifest"
+    deps = upstream_only_webview_deps
     apk_name = "SystemWebView"
-  }
-
-  if (android_64bit_target_cpu) {
-    # This target builds a 32-bit only Webview on a 64-bit config, analogous to
-    # what's built on a 32-bit config. This lets all Webviews build on a single
-    # configuration.
-    standalone_system_webview_apk_tmpl("system_webview_32_apk") {
-      apk_name = "SystemWebView32"
-      include_64_bit_webview = false
-    }
+    min_sdk_version = 21
   }
 
   android_resource_sizes_test("resource_sizes_system_webview_apk") {
@@ -635,15 +619,17 @@
   }
 }
 
-android_assets("webview_primary_abi_assets") {
+android_assets("standalone_webview_assets") {
+  deps = [
+    "//third_party/icu:icu_assets",
+  ]
   if (use_v8_context_snapshot) {
-    deps = [
-      "//tools/v8_context_snapshot:v8_context_snapshot_assets",
-    ]
+    deps += [ "//tools/v8_context_snapshot:v8_context_snapshot_assets" ]
   } else {
-    deps = [
-      "//v8:v8_external_startup_data_assets",
-    ]
+    deps += [ "//v8:v8_external_startup_data_assets" ]
+  }
+  if (android_64bit_target_cpu) {
+    deps += [ ":v8_snapshot_secondary_abi_assets" ]
   }
 }
 
@@ -659,12 +645,6 @@
 }
 
 if (android_64bit_target_cpu) {
-  android_assets("webview_secondary_abi_assets") {
-    deps = [
-      ":v8_snapshot_secondary_abi_assets",
-    ]
-  }
-
   android_assets("monochrome_webview_secondary_abi_assets") {
     deps = [
       "//third_party/icu:icu_assets",
@@ -673,16 +653,6 @@
   }
 }
 
-android_assets("weblayer_webview_assets") {
-  deps = [
-    ":webview_primary_abi_assets",
-    "//third_party/icu:icu_assets",
-  ]
-  if (android_64bit_target_cpu) {
-    deps += [ ":webview_secondary_abi_assets" ]
-  }
-}
-
 android_assets("stub_assets") {
   renaming_sources = [ "$root_gen_dir/components/resources/about_credits.html" ]
   renaming_destinations = [ "webview_licenses.notice" ]
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc
index 85920a8..0eba836 100644
--- a/android_webview/browser/aw_autofill_client.cc
+++ b/android_webview/browser/aw_autofill_client.cc
@@ -190,7 +190,7 @@
   return false;
 }
 
-void AwAutofillClient::ScanCreditCard(const CreditCardScanCallback& callback) {
+void AwAutofillClient::ScanCreditCard(CreditCardScanCallback callback) {
   NOTIMPLEMENTED();
 }
 
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h
index 03c117e..365b411 100644
--- a/android_webview/browser/aw_autofill_client.h
+++ b/android_webview/browser/aw_autofill_client.h
@@ -115,7 +115,7 @@
   void ConfirmCreditCardFillAssist(const autofill::CreditCard& card,
                                    base::OnceClosure callback) override;
   bool HasCreditCardScanFeature() override;
-  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ScanCreditCard(CreditCardScanCallback callback) override;
   void ShowAutofillPopup(
       const gfx::RectF& element_bounds,
       base::i18n::TextDirection text_direction,
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
index 71df22d92..9f6c044e 100644
--- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
+++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
@@ -109,7 +109,7 @@
   // For other requests, follow user consent.
   JNIEnv* env = base::android::AttachCurrentThread();
   bool safe_browsing_user_consent =
-      Java_AwSafeBrowsingConfigHelper_getSafeBrowsingUserOptIn2(env);
+      Java_AwSafeBrowsingConfigHelper_getSafeBrowsingUserOptIn(env);
   return !safe_browsing_user_consent;
 }
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java
index 0522eb2..979027e8 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java
@@ -70,7 +70,9 @@
 
     // Overriding implementations may call "callback" asynchronously, on any thread.
     public void querySafeBrowsingUserConsent(@NonNull final Callback<Boolean> callback) {
-        // User opt-in preference depends on a SafetyNet API.
+        // User opt-in preference depends on a SafetyNet API. In purely upstream builds (which don't
+        // communicate with GMS), assume the user has not opted in.
+        callback.onResult(false);
     }
 
     // Overriding implementations may call "callback" asynchronously. For simplicity (and not
diff --git a/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java b/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java
index 197f6c3..72439c8 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java
@@ -88,7 +88,7 @@
     }
 
     // Silently returns null in case of a missing or truncated seed, which is expected in case
-    // of an incomplete downoad or copy. Other IO problems are actual errors, and are logged.
+    // of an incomplete download or copy. Other IO problems are actual errors, and are logged.
     @Nullable
     public static SeedInfo readSeedFile(File inFile) {
         if (!inFile.exists()) return null;
@@ -103,22 +103,24 @@
                 return null;
             }
 
-            if (!proto.hasSignature() || !proto.hasCountry() || !proto.hasDate()
-                    || !proto.hasIsGzipCompressed() || !proto.hasSeedData()) {
+            if (!proto.hasSignature() || !proto.hasCountry()
+                    || (!proto.hasDate() && !proto.hasDateHeader()) || !proto.hasIsGzipCompressed()
+                    || !proto.hasSeedData()) {
                 return null;
             }
 
             SeedInfo info = new SeedInfo();
             info.signature = proto.getSignature();
             info.country = proto.getCountry();
-            info.date = proto.getDate();
             info.isGzipCompressed = proto.getIsGzipCompressed();
             info.seedData = proto.getSeedData().toByteArray();
 
-            // |dateHeader| is deprecated in favor of |date|, but parse |dateHeader| in case this
-            // seed predates the deprecation.
-            // TODO(crbug.com/1013390): Remove this fallback logic.
-            if (proto.hasDateHeader()) {
+            if (proto.hasDate()) {
+                info.date = proto.getDate();
+            } else {
+                // |dateHeader| is deprecated in favor of |date|, but parse |dateHeader| in case
+                // this seed predates the deprecation.
+                // TODO(crbug.com/1013390): Remove this fallback logic.
                 info.date = SeedInfo.parseDateHeader(proto.getDateHeader());
             }
 
diff --git a/android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java b/android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java
index 967ffb0c..87ae3bb 100644
--- a/android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java
+++ b/android_webview/java/src/org/chromium/android_webview/safe_browsing/AwSafeBrowsingConfigHelper.java
@@ -146,18 +146,10 @@
     // Can be called from any thread. This returns true or false, depending on user opt-in
     // preference. This returns false if we don't know yet what the user's preference is.
     @CalledByNative
-    private static boolean getSafeBrowsingUserOptIn2() {
+    private static boolean getSafeBrowsingUserOptIn() {
         return sSafeBrowsingUserOptIn;
     }
 
-    // Can be called from any thread. This returns true or false, depending on user opt-in
-    // preference. This returns false if we don't know yet what the user's preference is.
-    // Deprecated: use getSafeBrowsingUserOptIn2() instead, this will be removed when downstream no
-    // longer depends on it.
-    public static Boolean getSafeBrowsingUserOptIn() {
-        return getSafeBrowsingUserOptIn2();
-    }
-
     public static void setSafeBrowsingUserOptIn(boolean optin) {
         sSafeBrowsingUserOptIn = optin;
     }
diff --git a/android_webview/renderer/aw_print_render_frame_helper_delegate.cc b/android_webview/renderer/aw_print_render_frame_helper_delegate.cc
index c3e1c40..8de21c4b 100644
--- a/android_webview/renderer/aw_print_render_frame_helper_delegate.cc
+++ b/android_webview/renderer/aw_print_render_frame_helper_delegate.cc
@@ -12,11 +12,6 @@
 
 AwPrintRenderFrameHelperDelegate::~AwPrintRenderFrameHelperDelegate() = default;
 
-bool AwPrintRenderFrameHelperDelegate::CancelPrerender(
-    content::RenderFrame* render_frame) {
-  return false;
-}
-
 blink::WebElement AwPrintRenderFrameHelperDelegate::GetPdfElement(
     blink::WebLocalFrame* frame) {
   return blink::WebElement();
diff --git a/android_webview/renderer/aw_print_render_frame_helper_delegate.h b/android_webview/renderer/aw_print_render_frame_helper_delegate.h
index 5448f8aae..e5541b6 100644
--- a/android_webview/renderer/aw_print_render_frame_helper_delegate.h
+++ b/android_webview/renderer/aw_print_render_frame_helper_delegate.h
@@ -18,7 +18,6 @@
 
  private:
   // printing::PrintRenderFrameHelper::Delegate:
-  bool CancelPrerender(content::RenderFrame* render_frame) override;
   blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override;
   bool IsPrintPreviewEnabled() override;
   bool IsScriptedPrintEnabled() override;
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni
index 36dd1b38..5f729ce3 100644
--- a/android_webview/system_webview_apk_tmpl.gni
+++ b/android_webview/system_webview_apk_tmpl.gni
@@ -55,27 +55,22 @@
     _use_trichrome_library =
         defined(use_trichrome_library) && use_trichrome_library
 
-    # Pure 32-bit implies a 32-bit only Webview built on a 64-bit configuration.
-    _pure_32_bit =
-        android_64bit_target_cpu && defined(invoker.include_64_bit_webview) &&
-        !invoker.include_64_bit_webview
-    not_needed([ "_pure_32_bit" ])
+    if (!_use_trichrome_library) {
+      deps += [ "//android_webview:standalone_webview_assets" ]
+    }
 
     # Flag whether additional deps and libs should be included for each ABI.
     _include_primary_support = false
     _include_secondary_support = false
 
     if (!_use_trichrome_library) {
-      if (!android_64bit_target_cpu || !_pure_32_bit) {
-        shared_libraries = [ "//android_webview:libwebviewchromium" ]
-        _include_primary_support = true
-      }
+      shared_libraries = [ "//android_webview:libwebviewchromium" ]
+      _include_primary_support = true
+      shared_resources = true
       if (android_64bit_target_cpu) {
         secondary_abi_shared_libraries = [ "//android_webview:libwebviewchromium($android_secondary_abi_toolchain)" ]
         _include_secondary_support = true
       }
-      deps += [ "//third_party/icu:icu_assets" ]
-      shared_resources = true
     } else {
       uncompress_shared_libraries = true
       app_as_shared_lib = true
@@ -87,12 +82,19 @@
           native_lib_placeholders = [ "libdummy.so" ]
           if (invoker.include_32_bit_webview) {
             secondary_abi_shared_libraries = [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ]
+            deps += [ "//android_webview:v8_snapshot_secondary_abi_assets" ]
             _include_secondary_support = true
           }
         } else {
           if (invoker.include_64_bit_webview) {
             shared_libraries = [ "//android_webview:monochrome" ]
             _include_primary_support = true
+            if (use_v8_context_snapshot) {
+              deps +=
+                  [ "//tools/v8_context_snapshot:v8_context_snapshot_assets" ]
+            } else {
+              deps += [ "//v8:v8_external_startup_data_assets" ]
+            }
           }
           secondary_native_lib_placeholders = [ "libdummy.so" ]
         }
@@ -103,17 +105,13 @@
 
     if (_include_primary_support) {
       deps += [
-        "//android_webview:webview_primary_abi_assets",
         "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
       ]
       loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
     }
     if (_include_secondary_support) {
       _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
-      deps += [
-        "//android_webview:webview_secondary_abi_assets",
-        _trampoline,
-      ]
+      deps += [ _trampoline ]
       _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
       secondary_abi_loadable_modules =
           [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
@@ -182,26 +180,12 @@
         } else {
           version_code = trichrome_version_code
         }
+      } else if (android_channel == "dev") {
+        version_code = webview_dev_version_code
+      } else if (android_channel == "beta") {
+        version_code = webview_beta_version_code
       } else {
-        if (android_channel == "dev") {
-          if (_pure_32_bit) {
-            version_code = webview_32_dev_version_code
-          } else {
-            version_code = webview_dev_version_code
-          }
-        } else if (android_channel == "beta") {
-          if (_pure_32_bit) {
-            version_code = webview_32_beta_version_code
-          } else {
-            version_code = webview_beta_version_code
-          }
-        } else {
-          if (_pure_32_bit) {
-            version_code = webview_32_stable_version_code
-          } else {
-            version_code = webview_stable_version_code
-          }
-        }
+        version_code = webview_stable_version_code
       }
     }
     if (!defined(version_name)) {
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index e200d72c..390be2c7 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1342,8 +1342,6 @@
     "wm/workspace/multi_window_resize_controller.h",
     "wm/workspace/phantom_window_controller.cc",
     "wm/workspace/phantom_window_controller.h",
-    "wm/workspace/two_step_edge_cycler.cc",
-    "wm/workspace/two_step_edge_cycler.h",
     "wm/workspace/workspace_event_handler.cc",
     "wm/workspace/workspace_event_handler.h",
     "wm/workspace/workspace_layout_manager.cc",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 5449dd3..e365616 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -13,6 +13,7 @@
 #include "ash/app_list/model/app_list_item.h"
 #include "ash/app_list/views/app_list_main_view.h"
 #include "ash/app_list/views/app_list_view.h"
+#include "ash/app_list/views/apps_container_view.h"
 #include "ash/app_list/views/contents_view.h"
 #include "ash/app_list/views/search_box_view.h"
 #include "ash/assistant/assistant_controller.h"
@@ -816,9 +817,24 @@
   }
 }
 
+base::ScopedClosureRunner
+AppListControllerImpl::DisableHomeScreenBackgroundBlur() {
+  AppListView* const app_list_view = presenter_.GetView();
+  if (!app_list_view)
+    return base::ScopedClosureRunner(base::DoNothing());
+  return app_list_view->app_list_main_view()
+      ->contents_view()
+      ->GetAppsContainerView()
+      ->DisableSuggestionChipsBlur();
+}
+
 void AppListControllerImpl::OnHomeLauncherAnimationComplete(
     bool shown,
     int64_t display_id) {
+  // Stop disabling background blur in home screen when the home screen
+  // transition ends.
+  home_screen_blur_disabler_.reset();
+
   home_launcher_transition_state_ = HomeLauncherTransitionState::kFinished;
   CloseAssistantUi(shown ? AssistantExitPoint::kLauncherOpen
                          : AssistantExitPoint::kLauncherClose);
@@ -832,6 +848,12 @@
 
 void AppListControllerImpl::OnHomeLauncherPositionChanged(int percent_shown,
                                                           int64_t display_id) {
+  // Disable home screen background blur if the home launcher transition is
+  // staring - the blur disabler will be reset when the transition ends (in
+  // OnHomeLauncherAnimationComplete()).
+  if (home_launcher_transition_state_ == HomeLauncherTransitionState::kFinished)
+    home_screen_blur_disabler_ = DisableHomeScreenBackgroundBlur();
+
   const bool mostly_shown = percent_shown >= 50;
   home_launcher_transition_state_ =
       mostly_shown ? HomeLauncherTransitionState::kMostlyShown
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index 7e84873d..462ff3d 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -280,6 +280,7 @@
       base::Optional<AnimationInfo> animation_info,
       UpdateAnimationSettingsCallback callback) override;
   base::Optional<base::TimeDelta> GetOptionalAnimationDuration() override;
+  base::ScopedClosureRunner DisableHomeScreenBackgroundBlur() override;
   void OnHomeLauncherAnimationComplete(bool shown, int64_t display_id) override;
   void OnHomeLauncherPositionChanged(int percent_shown,
                                      int64_t display_id) override;
@@ -429,6 +430,11 @@
   // visibility animation to finish. Should only be used in tablet mode.
   HomeLauncherAnimationCallback home_launcher_animation_callback_;
 
+  // ScopedClosureRunner which while in scope keeps background blur in home
+  // screen (in particular, apps container suggestion chips background)
+  // disabled. Set while home screen transitions are in progress.
+  base::Optional<base::ScopedClosureRunner> home_screen_blur_disabler_;
+
   base::ObserverList<AppListControllerObserver> observers_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListControllerImpl);
diff --git a/ash/home_screen/home_screen_delegate.h b/ash/home_screen/home_screen_delegate.h
index 9d3192e4..0fa0947 100644
--- a/ash/home_screen/home_screen_delegate.h
+++ b/ash/home_screen/home_screen_delegate.h
@@ -6,6 +6,7 @@
 #define ASH_HOME_SCREEN_HOME_SCREEN_DELEGATE_H_
 
 #include "base/callback.h"
+#include "base/callback_helpers.h"
 #include "base/optional.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 
@@ -97,6 +98,10 @@
   // True if home screen is visible.
   virtual bool IsHomeScreenVisible() = 0;
 
+  // Disables background blur in home screen UI while the returned
+  // ScopedClosureRunner is in scope.
+  virtual base::ScopedClosureRunner DisableHomeScreenBackgroundBlur() = 0;
+
   // Returns bounds rect in screen coordinates for the app list item associated
   // with the provided window in the apps grid shown in the home screen,
   // assuming the initial app list grid page is selected.
diff --git a/ash/home_screen/swipe_home_to_overview_controller.cc b/ash/home_screen/swipe_home_to_overview_controller.cc
index 9bcc629..0be0130 100644
--- a/ash/home_screen/swipe_home_to_overview_controller.cc
+++ b/ash/home_screen/swipe_home_to_overview_controller.cc
@@ -94,6 +94,10 @@
         display.bounds().y() +
         display.bounds().height() * kHomeScalingThresholdDisplayHeightRatio;
     state_ = State::kTrackingDrag;
+    home_screen_blur_disabler_ = Shell::Get()
+                                     ->home_screen_controller()
+                                     ->delegate()
+                                     ->DisableHomeScreenBackgroundBlur();
   } else {
     if (location_in_screen.y() <= overview_transition_threshold_y_ &&
         std::abs(scroll_x) + std::abs(scroll_y) <= kMovementVelocityThreshold) {
@@ -154,6 +158,10 @@
       ->UpdateScaleAndOpacityForHomeLauncher(
           1.0f /*scale*/, 1.0f /*opacity*/, base::nullopt /*animation_info*/,
           base::BindRepeating(&UpdateHomeAnimationForGestureCancel));
+
+  // No need to keep blur disabled for the drag - note that blur might remain
+  // disabled at this point due to the started home screen scale animation.
+  home_screen_blur_disabler_.reset();
 }
 
 void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() {
@@ -174,6 +182,11 @@
   UMA_HISTOGRAM_ENUMERATION(kEnterOverviewHistogramName,
                             EnterOverviewFromHomeLauncher::kSuccess);
   Shell::Get()->overview_controller()->StartOverview();
+
+  // No need to keep blur disabled for the drag - note that blur might remain
+  // disabled at this point due to the started overview transition (which
+  // triggers home screen scale animation).
+  home_screen_blur_disabler_.reset();
 }
 
 }  // namespace ash
diff --git a/ash/home_screen/swipe_home_to_overview_controller.h b/ash/home_screen/swipe_home_to_overview_controller.h
index 96485032..0d26426 100644
--- a/ash/home_screen/swipe_home_to_overview_controller.h
+++ b/ash/home_screen/swipe_home_to_overview_controller.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "ash/ash_export.h"
+#include "base/callback_helpers.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/timer/timer.h"
@@ -81,6 +82,11 @@
   // The timer to run FinalizeDragAndShowOverview().
   base::OneShotTimer overview_transition_timer_;
 
+  // ScopedClosureRunner that while in scope disables background blur in home
+  // screen. It will be set during home screen drag with a goal of improving
+  // overall drag performance.
+  base::Optional<base::ScopedClosureRunner> home_screen_blur_disabler_;
+
   DISALLOW_COPY_AND_ASSIGN(SwipeHomeToOverviewController);
 };
 
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc
index 665c4cb7..73502531 100644
--- a/ash/public/cpp/app_list/app_list_features.cc
+++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -33,6 +33,8 @@
     "EnableZeroStateMixedTypesRanker", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kEnableAppReinstallZeroState{
     "EnableAppReinstallZeroState", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kEnableSuggestedFiles{"EnableSuggestedFiles",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
 // "EnableEmbeddedAssistantUI" is used in finch experiment therefore we cannot
 // change it until fully launched. It is used to redirect Launcher search to
@@ -105,6 +107,10 @@
   return base::FeatureList::IsEnabled(kEnableAppReinstallZeroState);
 }
 
+bool IsSuggestedFilesEnabled() {
+  return base::FeatureList::IsEnabled(kEnableSuggestedFiles);
+}
+
 bool IsAssistantSearchEnabled() {
   return base::FeatureList::IsEnabled(kEnableAssistantSearch);
 }
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h
index 28be74f7..fa0290d 100644
--- a/ash/public/cpp/app_list/app_list_features.h
+++ b/ash/public/cpp/app_list/app_list_features.h
@@ -39,13 +39,13 @@
 // Enable app ranking models.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableAppRanker;
 
-// Enable an model that ranks zero-state apps search result.
+// Enable a model that ranks zero-state apps search result.
 // TODO(crbug.com/989350): This flag can be removed once the
 // AppSearchResultRanker is removed. Same with the
 // AppSearchResultRankerPredictorName.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableZeroStateAppsRanker;
 
-// Enable an model that ranks query based non-apps result.
+// Enable a model that ranks query based non-apps result.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableQueryBasedMixedTypesRanker;
 
 // Enable a model that ranks zero-state files and recent queries.
@@ -55,6 +55,9 @@
 // zero-state.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableAppReinstallZeroState;
 
+// Enables file suggestions in the suggestion chips.
+ASH_PUBLIC_EXPORT extern const base::Feature kEnableSuggestedFiles;
+
 // Enables the Assistant search redirection in the app list.
 ASH_PUBLIC_EXPORT extern const base::Feature kEnableAssistantSearch;
 
@@ -95,6 +98,7 @@
 bool ASH_PUBLIC_EXPORT IsQueryBasedMixedTypesRankerEnabled();
 bool ASH_PUBLIC_EXPORT IsZeroStateMixedTypesRankerEnabled();
 bool ASH_PUBLIC_EXPORT IsAppReinstallZeroStateEnabled();
+bool ASH_PUBLIC_EXPORT IsSuggestedFilesEnabled();
 bool ASH_PUBLIC_EXPORT IsAssistantSearchEnabled();
 bool ASH_PUBLIC_EXPORT IsAssistantLauncherUIEnabled();
 bool ASH_PUBLIC_EXPORT IsAppGridGhostEnabled();
diff --git a/ash/public/cpp/app_list/internal_app_id_constants.h b/ash/public/cpp/app_list/internal_app_id_constants.h
index 84ac9c09..86b11b63 100644
--- a/ash/public/cpp/app_list/internal_app_id_constants.h
+++ b/ash/public/cpp/app_list/internal_app_id_constants.h
@@ -22,9 +22,6 @@
 constexpr char kInternalAppIdContinueReading[] =
     "fbokpncipdhffndmljhhidahghagaonp";
 
-// Generated as crx_file::id_util::GenerateId("org.chromium.camera").
-constexpr char kInternalAppIdCamera[] = "iniodglblcgmngkgdipeiclkdjjpnlbn";
-
 // Generated as crx_file::id_util::GenerateId("org.chromium.discover").
 constexpr char kInternalAppIdDiscover[] = "pjdncmlmjhcebmcacdddfacepcjmfaoo";
 
diff --git a/ash/public/cpp/resources/ash_public_unscaled_resources.grd b/ash/public/cpp/resources/ash_public_unscaled_resources.grd
index 0c5c3cb..391f3e0 100644
--- a/ash/public/cpp/resources/ash_public_unscaled_resources.grd
+++ b/ash/public/cpp/resources/ash_public_unscaled_resources.grd
@@ -17,9 +17,8 @@
       <!-- CrOS internal apps images -->
       <include name="IDR_SHORTCUT_VIEWER_LOGO_192" file="unscaled_resources/shortcut_viewer_logo_192.png" type="BINDATA" />
       <include name="IDR_SETTINGS_LOGO_192" file="unscaled_resources/settings_logo_192.png" type="BINDATA" />
-      <include name="IDR_CAMERA_LOGO_192" file="unscaled_resources/camera_logo_192.png" type="BINDATA" />
       <include name="IDR_DISCOVER_APP_192" file="unscaled_resources/discover_app_logo_192.png" type="BINDATA" />
-       <include name="IDR_RELEASE_NOTES_APP_192" file="unscaled_resources/release_notes_logo_192.png" type="BINDATA" />
+      <include name="IDR_RELEASE_NOTES_APP_192" file="unscaled_resources/release_notes_logo_192.png" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/ash/public/cpp/resources/unscaled_resources/camera_logo_192.png b/ash/public/cpp/resources/unscaled_resources/camera_logo_192.png
deleted file mode 100644
index c5603807..0000000
--- a/ash/public/cpp/resources/unscaled_resources/camera_logo_192.png
+++ /dev/null
Binary files differ
diff --git a/ash/shelf/back_button_unittest.cc b/ash/shelf/back_button_unittest.cc
index 2649447..ef8f886 100644
--- a/ash/shelf/back_button_unittest.cc
+++ b/ash/shelf/back_button_unittest.cc
@@ -118,13 +118,6 @@
   if (GetParam())
     std::unique_ptr<views::Widget> widget = CreateTestWidget();
 
-  // Wait for the navigation widget's animation.
-  test_api()->RunMessageLoopUntilAnimationsDone(
-      GetPrimaryShelf()
-          ->shelf_widget()
-          ->navigation_widget()
-          ->get_bounds_animator_for_testing());
-
   AcceleratorControllerImpl* controller =
       Shell::Get()->accelerator_controller();
 
@@ -174,13 +167,6 @@
   if (GetParam())
     std::unique_ptr<views::Widget> widget = CreateTestWidget();
 
-  // We need to wait for the navigation widget's animation to be done.
-  test_api_->RunMessageLoopUntilAnimationsDone(
-      GetPrimaryShelf()
-          ->shelf_widget()
-          ->navigation_widget()
-          ->get_bounds_animator_for_testing());
-
   generator->MoveMouseTo(back_button()->GetBoundsInScreen().CenterPoint());
   generator->PressRightButton();
 
diff --git a/ash/shelf/home_button_unittest.cc b/ash/shelf/home_button_unittest.cc
index 4440300..db51bae3 100644
--- a/ash/shelf/home_button_unittest.cc
+++ b/ash/shelf/home_button_unittest.cc
@@ -172,40 +172,22 @@
   // When hotseat is enabled, home button position changes between in-app shelf
   // and home shelf, so test in-app when hotseat is enabled.
   if (GetParam()) {
-    // Wait for the navigation widget's animation.
-    test_api.RunMessageLoopUntilAnimationsDone(
-        GetPrimaryShelf()
-            ->shelf_widget()
-            ->navigation_widget()
-            ->get_bounds_animator_for_testing());
-
     EXPECT_EQ(home_button()->bounds().x(), 0);
 
     // Switch to in-app shelf.
     std::unique_ptr<views::Widget> widget = CreateTestWidget();
   }
 
-  // Wait for the navigation widget's animation.
-  test_api.RunMessageLoopUntilAnimationsDone(
-      GetPrimaryShelf()
-          ->shelf_widget()
-          ->navigation_widget()
-          ->get_bounds_animator_for_testing());
   EXPECT_GT(home_button()->bounds().x(), 0);
 
   Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
-  test_api.RunMessageLoopUntilAnimationsDone(
-      GetPrimaryShelf()
-          ->shelf_widget()
-          ->navigation_widget()
-          ->get_bounds_animator_for_testing());
 
   // Visual space around the home button is set at the widget level.
   EXPECT_EQ(0, home_button()->bounds().x());
 }
 
 TEST_P(HomeButtonTest, LongPressGesture) {
-  // Simulate two user with primary user as active.
+  // Simulate two users with primary user as active.
   CreateUserSessions(2);
 
   // Enable the Assistant in system settings.
diff --git a/ash/shelf/hotseat_widget.cc b/ash/shelf/hotseat_widget.cc
index e822451..60ee806 100644
--- a/ash/shelf/hotseat_widget.cc
+++ b/ash/shelf/hotseat_widget.cc
@@ -335,11 +335,12 @@
   delegate_view_->UpdateOpaqueBackground();
 }
 
-void HotseatWidget::UpdateLayout() {
+void HotseatWidget::UpdateLayout(bool animate) {
   ui::Layer* layer = GetNativeView()->layer();
   ui::ScopedLayerAnimationSettings animation_setter(layer->GetAnimator());
   animation_setter.SetTransitionDuration(
-      ShelfConfig::Get()->shelf_animation_duration());
+      animate ? ShelfConfig::Get()->shelf_animation_duration()
+              : base::TimeDelta::FromMilliseconds(0));
   animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
   animation_setter.SetPreemptionStrategy(
       ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
diff --git a/ash/shelf/hotseat_widget.h b/ash/shelf/hotseat_widget.h
index 8154832..66416fa 100644
--- a/ash/shelf/hotseat_widget.h
+++ b/ash/shelf/hotseat_widget.h
@@ -61,7 +61,7 @@
   void UpdateOpaqueBackground();
 
   // Updates this widget's layout according to current conditions.
-  void UpdateLayout();
+  void UpdateLayout(bool animate);
 
   gfx::Size GetOpaqueBackgroundSize() const;
 
diff --git a/ash/shelf/shelf_config_unittest.cc b/ash/shelf/shelf_config_unittest.cc
index 2a9f3e3..8361e26 100644
--- a/ash/shelf/shelf_config_unittest.cc
+++ b/ash/shelf/shelf_config_unittest.cc
@@ -12,7 +12,8 @@
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "chromeos/constants/chromeos_switches.h"
+#include "base/test/scoped_feature_list.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -23,9 +24,8 @@
   ~ShelfConfigTest() override = default;
 
   void SetUp() override {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        chromeos::switches::kShelfHotseat);
-
+    scoped_feature_list_.InitAndEnableFeature(
+        chromeos::features::kShelfHotseat);
     AshTestBase::SetUp();
   }
 
@@ -41,7 +41,7 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(ShelfConfigTest);
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Make sure ShelfConfig is dense when screen becomes small in tablet mode.
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 603a18e..8158901 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -1482,7 +1482,7 @@
     gfx::Rect shelf_bounds = target_bounds_.shelf_bounds;
     shelf_widget_->SetBounds(shelf_bounds);
 
-    hotseat_widget->UpdateLayout();
+    hotseat_widget->UpdateLayout(animate);
 
     // Having a window which is visible but does not have an opacity is an
     // illegal state. We therefore hide the shelf here if required.
@@ -1499,7 +1499,7 @@
                    gfx::Tween::EASE_OUT);
 
     // Let the navigation widget handle its own layout changes.
-    nav_widget->UpdateLayout();
+    nav_widget->UpdateLayout(animate);
 
     // Do not update the work area during overview animation.
     if (!suspend_work_area_update_) {
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index b48339b..db24c36f 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -72,6 +72,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/window_parenting_client.h"
@@ -1027,15 +1028,16 @@
   // testing::Test:
   void SetUp() override {
     if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) {
-      if (GetParam())
-        base::CommandLine::ForCurrentProcess()->AppendSwitch(
-            chromeos::switches::kShelfHotseat);
+      if (GetParam()) {
+        scoped_feature_list_.InitAndEnableFeature(
+            chromeos::features::kShelfHotseat);
+      }
     }
     AshTestBase::SetUp();
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerTest);
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Used to test the Hotseat, ScrollabeShelf, and DenseShelf features.
@@ -3310,13 +3312,13 @@
 
   // testing::Test:
   void SetUp() override {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        chromeos::switches::kShelfHotseat);
+    scoped_feature_list_.InitAndEnableFeature(
+        chromeos::features::kShelfHotseat);
     AshTestBase::SetUp();
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(HotseatShelfLayoutManagerTest);
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Tests that the always shown shelf forwards the appropriate events to the home
@@ -4920,10 +4922,10 @@
 
   // AshTestBase:
   void SetUp() override {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        chromeos::switches::kShelfHotseat);
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kDragFromShelfToHomeOrOverview);
+    scoped_feature_list_.InitWithFeatures(
+        {chromeos::features::kShelfHotseat,
+         features::kDragFromShelfToHomeOrOverview},
+        {});
     AshTestBase::SetUp();
 
     TabletModeControllerTestApi().EnterTabletMode();
@@ -4936,7 +4938,6 @@
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
-  DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerWindowDraggingTest);
 };
 
 // Test that when swiping up on the shelf, we may or may not drag up the MRU
@@ -5724,7 +5725,7 @@
   }
 }
 
-// Paramaterized tests for shelf with and without shelf dimming enabled.
+// Parameterized tests for shelf with and without shelf dimming enabled.
 class DimShelfLayoutManagerTest : public ShelfLayoutManagerTestBase,
                                   public testing::WithParamInterface<bool> {
  public:
@@ -5852,7 +5853,7 @@
                         : kExpectedDefaultShelfOpacity);
 }
 
-// Paramaterized tests for shelf dimming with hotseat enabled or disabled.
+// Parameterized tests for shelf dimming with hotseat enabled or disabled.
 class HotseatDimShelfLayoutManagerTest : public DimShelfLayoutManagerTest {
  public:
   HotseatDimShelfLayoutManagerTest() = default;
@@ -5860,14 +5861,20 @@
   // testing::Test:
   void SetUp() override {
     if (GetParam()) {
-      base::CommandLine::ForCurrentProcess()->AppendSwitch(
-          chromeos::switches::kShelfHotseat);
+      scoped_feature_list_.InitAndEnableFeature(
+          chromeos::features::kShelfHotseat);
+    } else {
+      scoped_feature_list_.InitAndDisableFeature(
+          chromeos::features::kShelfHotseat);
     }
 
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         ash::switches::kEnableDimShelf);
     AshTestBase::SetUp();
   }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Used to test shelf dimming in conjunction with hotseat.
diff --git a/ash/shelf/shelf_navigation_widget.cc b/ash/shelf/shelf_navigation_widget.cc
index 597dfc1..70813da 100644
--- a/ash/shelf/shelf_navigation_widget.cc
+++ b/ash/shelf/shelf_navigation_widget.cc
@@ -233,7 +233,7 @@
   SetContentsView(delegate_);
   GetBackButton()->SetBoundsRect(GetFirstButtonBounds());
   SetSize(GetIdealSize());
-  UpdateLayout();
+  UpdateLayout(/*animate=*/false);
 }
 
 gfx::Size ShelfNavigationWidget::GetIdealSize() const {
@@ -294,15 +294,15 @@
 }
 
 void ShelfNavigationWidget::OnTabletModeStarted() {
-  UpdateLayout();
+  UpdateLayout(/*animate=*/true);
 }
 
 void ShelfNavigationWidget::OnTabletModeEnded() {
-  UpdateLayout();
+  UpdateLayout(/*animate=*/true);
 }
 
 void ShelfNavigationWidget::OnShelfAlignmentChanged(aura::Window* root_window) {
-  UpdateLayout();
+  UpdateLayout(/*animate=*/false);
 }
 
 void ShelfNavigationWidget::OnImplicitAnimationsCompleted() {
@@ -312,14 +312,15 @@
 }
 
 void ShelfNavigationWidget::OnShelfConfigUpdated() {
-  UpdateLayout();
+  UpdateLayout(/*animate=*/true);
 }
 
-void ShelfNavigationWidget::UpdateLayout() {
+void ShelfNavigationWidget::UpdateLayout(bool animate) {
   bool is_back_button_shown = IsBackButtonShown();
   // Use the same duration for all parts of the upcoming animation.
   const auto animation_duration =
-      ShelfConfig::Get()->shelf_animation_duration();
+      animate ? ShelfConfig::Get()->shelf_animation_duration()
+              : base::TimeDelta::FromMilliseconds(0);
   bounds_animator_->SetAnimationDuration(animation_duration);
 
   ui::ScopedLayerAnimationSettings nav_animation_setter(
diff --git a/ash/shelf/shelf_navigation_widget.h b/ash/shelf/shelf_navigation_widget.h
index 869379c..1e260178 100644
--- a/ash/shelf/shelf_navigation_widget.h
+++ b/ash/shelf/shelf_navigation_widget.h
@@ -78,7 +78,7 @@
 
   // Updates this widget's layout according to current constraints: tablet
   // mode and shelf orientation.
-  void UpdateLayout();
+  void UpdateLayout(bool animate);
 
   views::BoundsAnimator* get_bounds_animator_for_testing() {
     return bounds_animator_.get();
diff --git a/ash/strings/ash_strings_eu.xtb b/ash/strings/ash_strings_eu.xtb
index b758b1a..f86fb3b1 100644
--- a/ash/strings/ash_strings_eu.xtb
+++ b/ash/strings/ash_strings_eu.xtb
@@ -131,6 +131,7 @@
 <translation id="2653659639078652383">Bidali</translation>
 <translation id="2658778018866295321">Sakatu eta arrastatu</translation>
 <translation id="2700493154570097719">Zehaztu teklatua</translation>
+<translation id="2704781753052663061">Konektatu beste wifi-sare batzuetara</translation>
 <translation id="2718395828230677721">Gaueko argia</translation>
 <translation id="2727977024730340865">Energia gutxiko kargagailu bat entxufatu duzu. Agian bateria kargatzeko prozesua ez da fidagarria izango.</translation>
 <translation id="2761704814324807722">Egoera, ordua: <ph name="TIME" />, <ph name="BATTERY" /></translation>
diff --git a/ash/strings/ash_strings_km.xtb b/ash/strings/ash_strings_km.xtb
index 3298ffd..b288d8e 100644
--- a/ash/strings/ash_strings_km.xtb
+++ b/ash/strings/ash_strings_km.xtb
@@ -131,6 +131,7 @@
 <translation id="2653659639078652383">ដាក់ស្នើ</translation>
 <translation id="2658778018866295321">ចុចហើយអូស</translation>
 <translation id="2700493154570097719">កំណត់​ក្ដារចុច​របស់អ្នក</translation>
+<translation id="2704781753052663061">ភ្ជាប់​បណ្ដាញ Wi-Fi ផ្សេងទៀត</translation>
 <translation id="2718395828230677721">ពន្លឺពេលយប់</translation>
 <translation id="2727977024730340865">បានដោតទៅឆ្នាំងសាកថាមពលខ្សោយ។ ការសាកថ្មប្រហែលជាមិនអាចជឿជាក់បានទេ។</translation>
 <translation id="2761704814324807722">ទម្រស្ថានភាព ម៉ោង <ph name="TIME" />, <ph name="BATTERY" /></translation>
diff --git a/ash/system/message_center/arc/arc_notification_manager_unittest.cc b/ash/system/message_center/arc/arc_notification_manager_unittest.cc
index d900529..b467602c 100644
--- a/ash/system/message_center/arc/arc_notification_manager_unittest.cc
+++ b/ash/system/message_center/arc/arc_notification_manager_unittest.cc
@@ -16,8 +16,8 @@
 #include "components/arc/session/connection_holder.h"
 #include "components/arc/test/connection_holder_util.h"
 #include "components/arc/test/fake_notifications_instance.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/message_center/fake_message_center.h"
 #include "ui/message_center/message_center_observer.h"
@@ -134,14 +134,14 @@
     return key;
   }
 
-  void FlushInstanceCall() { binding_->FlushForTesting(); }
+  void FlushInstanceCall() { receiver_->FlushForTesting(); }
 
   void ConnectMojoChannel() {
-    binding_ =
-        std::make_unique<mojo::Binding<arc::mojom::NotificationsInstance>>(
+    receiver_ =
+        std::make_unique<mojo::Receiver<arc::mojom::NotificationsInstance>>(
             arc_notifications_instance_.get());
     arc::mojom::NotificationsInstancePtr instance_ptr;
-    binding_->Bind(mojo::MakeRequest(&instance_ptr));
+    receiver_->Bind(mojo::MakeRequest(&instance_ptr));
 
     arc_notification_manager_->SetInstance(std::move(instance_ptr));
     WaitForInstanceReady(
@@ -162,7 +162,7 @@
   void TearDown() override {
     arc_notification_manager_.reset();
     message_center_.reset();
-    binding_.reset();
+    receiver_.reset();
     arc_notifications_instance_.reset();
     base::RunLoop().RunUntilIdle();
   }
@@ -170,7 +170,7 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   TestArcAppIdProvider app_id_provider_;
   std::unique_ptr<arc::FakeNotificationsInstance> arc_notifications_instance_;
-  std::unique_ptr<mojo::Binding<arc::mojom::NotificationsInstance>> binding_;
+  std::unique_ptr<mojo::Receiver<arc::mojom::NotificationsInstance>> receiver_;
   std::unique_ptr<ArcNotificationManager> arc_notification_manager_;
   std::unique_ptr<MockMessageCenter> message_center_;
 
diff --git a/ash/system/status_area_widget_delegate.cc b/ash/system/status_area_widget_delegate.cc
index 1fc7dc4..7213216 100644
--- a/ash/system/status_area_widget_delegate.cc
+++ b/ash/system/status_area_widget_delegate.cc
@@ -138,7 +138,17 @@
 
 void StatusAreaWidgetDelegate::OnHotseatStateChanged(HotseatState old_state,
                                                      HotseatState new_state) {
-  UpdateLayout();
+  // Update the border of the last visible child so it has the right
+  // padding depending of the state of the shelf (See
+  // https://crbug.com/1025270). Don't layout as it will cause the whole
+  // transition to snap instead of animate (See https://crbug.com/1032770).
+  auto it = std::find_if(children().crbegin(), children().crend(),
+                         [](const View* v) { return v->GetVisible(); });
+  if (it == children().crend())
+    return;
+
+  View* last_visible_child = *it;
+  SetBorderOnChild(last_visible_child, /*is_child_on_edge=*/true);
 }
 
 void StatusAreaWidgetDelegate::UpdateLayout() {
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h
index 6fb58401..a1e9d40 100644
--- a/ash/system/tray/tray_constants.h
+++ b/ash/system/tray/tray_constants.h
@@ -92,7 +92,7 @@
 constexpr float kUnifiedMenuBackgroundBlur = 30.f;
 
 constexpr gfx::Insets kUnifiedMenuItemPadding(0, 16, 16, 16);
-constexpr gfx::Insets kUnifiedSystemInfoViewPadding(4, 16, 16, 16);
+constexpr gfx::Insets kUnifiedSystemInfoViewPadding(0, 16, 16, 16);
 constexpr gfx::Insets kUnifiedManagedDeviceViewPadding(4, 19, 4, 16);
 constexpr gfx::Insets kUnifiedSliderRowPadding(0, 12, 8, 16);
 constexpr gfx::Insets kUnifiedSliderBubblePadding(12, 0, 4, 0);
@@ -145,22 +145,27 @@
 constexpr double kNotificationCenterDragExpandThreshold = 0.8;
 
 // Constants used in FeaturePodsView of UnifiedSystemTray.
-constexpr gfx::Size kUnifiedFeaturePodIconSize(48, 48);
-constexpr gfx::Size kUnifiedFeaturePodSize(112, 88);
-constexpr gfx::Size kUnifiedFeaturePodCollapsedSize(48, 48);
+constexpr gfx::Size kUnifiedFeaturePodIconSize(46, 46);
+constexpr gfx::Size kUnifiedFeaturePodSize(112, 94);
+constexpr gfx::Size kUnifiedFeaturePodCollapsedSize(46, 46);
 constexpr gfx::Insets kUnifiedFeaturePodIconPadding(4);
 constexpr gfx::Insets kUnifiedFeaturePodHoverPadding(2);
-constexpr int kUnifiedFeaturePodVectorIconSize = 24;
+constexpr int kUnifiedFeaturePodVectorIconSize = 20;
 constexpr int kUnifiedFeaturePodLabelWidth = 80;
 constexpr int kUnifiedFeaturePodSpacing = 6;
 constexpr int kUnifiedFeaturePodHoverRadius = 4;
-constexpr int kUnifiedFeaturePodVerticalPadding = 28;
-constexpr int kUnifiedFeaturePodTopPadding = 24;
-constexpr int kUnifiedFeaturePodBottomPadding = 5;
+constexpr int kUnifiedFeaturePodVerticalPadding = 24;
+constexpr int kUnifiedFeaturePodTopPadding = 20;
+constexpr int kUnifiedFeaturePodBottomPadding = 0;
 constexpr int kUnifiedFeaturePodHorizontalSidePadding = 12;
 constexpr int kUnifiedFeaturePodHorizontalMiddlePadding = 0;
 constexpr int kUnifiedFeaturePodCollapsedVerticalPadding = 12;
 constexpr int kUnifiedFeaturePodCollapsedHorizontalPadding = 24;
+constexpr int kUnifiedFeaturePodLabelLineHeight = 16;
+constexpr int kUnifiedFeaturePodSubLabelLineHeight = 15;
+constexpr int kUnifiedFeaturePodLabelFontSize = 13;
+constexpr int kUnifiedFeaturePodSubLabelFontSize = 12;
+constexpr int kUnifiedFeaturePodInterLabelPadding = 2;
 constexpr int kUnifiedFeaturePodArrowSpacing = 4;
 constexpr int kUnifiedFeaturePodItemsInRow = 3;
 constexpr int kUnifiedFeaturePodMaxRows = 3;
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc
index e039d5e..60fca9c4 100644
--- a/ash/system/unified/feature_pod_button.cc
+++ b/ash/system/unified/feature_pod_button.cc
@@ -35,10 +35,20 @@
 
 namespace {
 
-void ConfigureFeaturePodLabel(views::Label* label) {
+void ConfigureFeaturePodLabel(views::Label* label,
+                              int line_height,
+                              int font_size) {
   label->SetAutoColorReadabilityEnabled(false);
   label->SetSubpixelRenderingEnabled(false);
   label->set_can_process_events_within_subtree(false);
+  label->SetLineHeight(line_height);
+
+  gfx::Font default_font;
+  gfx::Font label_font =
+      default_font.Derive(font_size - default_font.GetFontSize(),
+                          gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
+  gfx::FontList font_list(label_font);
+  label->SetFontList(font_list);
 }
 
 }  // namespace
@@ -58,7 +68,7 @@
 FeaturePodIconButton::~FeaturePodIconButton() = default;
 
 void FeaturePodIconButton::SetToggled(bool toggled) {
-  if (!is_togglable_)
+  if (!is_togglable_ || toggled_ == toggled)
     return;
 
   toggled_ = toggled;
@@ -141,8 +151,11 @@
   SetBorder(views::CreateEmptyBorder(kUnifiedFeaturePodHoverPadding));
   GetViewAccessibility().OverrideIsLeaf(true);
 
-  ConfigureFeaturePodLabel(label_);
-  ConfigureFeaturePodLabel(sub_label_);
+  label_->SetLineHeight(kUnifiedFeaturePodLabelLineHeight);
+  ConfigureFeaturePodLabel(label_, kUnifiedFeaturePodLabelLineHeight,
+                           kUnifiedFeaturePodLabelFontSize);
+  ConfigureFeaturePodLabel(sub_label_, kUnifiedFeaturePodSubLabelLineHeight,
+                           kUnifiedFeaturePodSubLabelFontSize);
   sub_label_->SetVisible(false);
 
   detailed_view_arrow_->set_can_process_events_within_subtree(false);
@@ -166,7 +179,8 @@
   DCHECK(focus_ring());
   focus_ring()->Layout();
   LayoutInCenter(label_, GetContentsBounds().y());
-  LayoutInCenter(sub_label_, GetContentsBounds().CenterPoint().y());
+  LayoutInCenter(sub_label_, GetContentsBounds().CenterPoint().y() +
+                                 kUnifiedFeaturePodInterLabelPadding);
 
   if (!detailed_view_arrow_->GetVisible())
     return;
@@ -196,8 +210,10 @@
   }
 
   int height = label_->GetPreferredSize().height() + GetInsets().height();
-  if (sub_label_->GetVisible())
-    height += sub_label_->GetPreferredSize().height();
+  if (sub_label_->GetVisible()) {
+    height += kUnifiedFeaturePodInterLabelPadding +
+              sub_label_->GetPreferredSize().height();
+  }
 
   return gfx::Size(width, height);
 }
@@ -309,11 +325,13 @@
 void FeaturePodButton::SetVectorIcon(const gfx::VectorIcon& icon) {
   const SkColor icon_color = AshColorProvider::Get()->GetContentLayerColor(
       ContentLayerType::kIconPrimary, AshColorMode::kDark);
-  icon_button_->SetImage(views::Button::STATE_NORMAL,
-                         gfx::CreateVectorIcon(icon, icon_color));
+  icon_button_->SetImage(
+      views::Button::STATE_NORMAL,
+      gfx::CreateVectorIcon(icon, kUnifiedFeaturePodVectorIconSize,
+                            icon_color));
   icon_button_->SetImage(
       views::Button::STATE_DISABLED,
-      gfx::CreateVectorIcon(icon,
+      gfx::CreateVectorIcon(icon, kUnifiedFeaturePodVectorIconSize,
                             AshColorProvider::GetDisabledColor(icon_color)));
 }
 
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc
index c8b12c21..f58d68ce 100644
--- a/ash/system/unified/feature_pods_container_view.cc
+++ b/ash/system/unified/feature_pods_container_view.cc
@@ -79,7 +79,8 @@
 
   return kUnifiedFeaturePodBottomPadding +
          (kUnifiedFeaturePodVerticalPadding + kUnifiedFeaturePodSize.height()) *
-             number_of_lines;
+             std::max(0, number_of_lines - 1) +
+         kUnifiedFeaturePodSize.height() + kUnifiedFeaturePodTopPadding;
 }
 
 int FeaturePodsContainerView::GetCollapsedHeight() const {
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index 1cffe53..954b3777 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -19,6 +19,8 @@
 #include "ash/root_window_settings.h"
 #include "ash/rotator/screen_rotation_animator.h"
 #include "ash/screen_util.h"
+#include "ash/shelf/shelf.h"
+#include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shell.h"
 #include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/desks/desk_mini_view.h"
@@ -222,12 +224,24 @@
 // clamp the bounds to a minimum size and shift the bounds offscreen.
 gfx::Rect GetGridBoundsInScreen(aura::Window* root_window,
                                 bool divider_changed) {
-  const gfx::Rect work_area =
+  gfx::Rect grid_bounds =
       WorkAreaInsets::ForWindow(root_window)->ComputeStableWorkArea();
+
+  // If the hotseat is extended, exclude its bounds when calculating overview
+  // bounds otherwise there may be overlap between it and overview items.
+  Shelf* shelf = Shelf::ForWindow(root_window);
+  if (shelf->shelf_layout_manager()->hotseat_state() ==
+      HotseatState::kExtended) {
+    const int hotseat_bottom_inset =
+        ShelfConfig::Get()->hotseat_size() +
+        ShelfConfig::Get()->hotseat_bottom_padding();
+    grid_bounds.Inset(0, 0, 0, hotseat_bottom_inset);
+  }
+
   SplitViewController* split_view_controller =
       SplitViewController::Get(root_window);
   if (!split_view_controller->InSplitViewMode())
-    return work_area;
+    return grid_bounds;
 
   SplitViewController::SnapPosition opposite_position =
       (split_view_controller->default_snap_position() ==
@@ -241,7 +255,7 @@
 
   const bool horizontal = SplitViewController::IsLayoutHorizontal();
   const int min_length =
-      (horizontal ? work_area.width() : work_area.height()) / 3;
+      (horizontal ? grid_bounds.width() : grid_bounds.height()) / 3;
   const int current_length = horizontal ? bounds.width() : bounds.height();
 
   if (current_length > min_length)
@@ -498,10 +512,7 @@
     // might need animation even if the grid needs animation.
     if (animate && transition == OverviewSession::OverviewTransition::kEnter)
       should_animate_item = window_item->should_animate_when_entering();
-    // Do not do the bounds animation for the drop target. We'll do the opacity
-    // animation by ourselves.
-    if (IsDropTargetWindow(window_item->GetWindow()))
-      should_animate_item = false;
+
     if (animate && transition == OverviewSession::OverviewTransition::kEnter) {
       if (window_item->should_animate_when_entering() &&
           !has_non_cover_animating) {
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc
index 91ea92e..3f48a39 100644
--- a/ash/wm/overview/overview_item.cc
+++ b/ash/wm/overview/overview_item.cc
@@ -1189,10 +1189,11 @@
   DCHECK(root_window_ == window->GetRootWindow());
   // Do not set transform for drop target, set bounds instead.
   if (overview_grid_->IsDropTargetWindow(window)) {
-    window->SetBoundsInScreen(
-        ToStableSizeRoundedRect(GetWindowTargetBoundsWithInsets()),
-        WindowState::Get(window)->GetDisplay());
-    window->SetTransform(gfx::Transform());
+    const gfx::Rect drop_target_bounds =
+        ToStableSizeRoundedRect(GetWindowTargetBoundsWithInsets());
+    SetWidgetBoundsAndMaybeAnimateTransform(
+        overview_grid_->drop_target_widget(), drop_target_bounds,
+        animation_type, /*observer=*/nullptr);
     return;
   }
 
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index d699aeb..6860b31 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -1700,28 +1700,44 @@
   overview_session()->CompleteDrag(overview_item, drag_point);
 }
 
-class HotseatDisabledOverviewSessionTest : public OverviewSessionTest {
+class HotseatOverviewSessionTest : public OverviewSessionTest {
  public:
-  HotseatDisabledOverviewSessionTest() = default;
-  ~HotseatDisabledOverviewSessionTest() override = default;
+  HotseatOverviewSessionTest() = default;
+  ~HotseatOverviewSessionTest() override = default;
 
   // AshTestBase:
   void SetUp() override {
-    feature_list_.InitAndDisableFeature(chromeos::features::kShelfHotseat);
+    if (GetParam())
+      feature_list_.InitAndEnableFeature(chromeos::features::kShelfHotseat);
+    else
+      feature_list_.InitAndDisableFeature(chromeos::features::kShelfHotseat);
     OverviewSessionTest::SetUp();
   }
 
  private:
   base::test::ScopedFeatureList feature_list_;
-  DISALLOW_COPY_AND_ASSIGN(HotseatDisabledOverviewSessionTest);
+  DISALLOW_COPY_AND_ASSIGN(HotseatOverviewSessionTest);
 };
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         HotseatDisabledOverviewSessionTest,
-                         testing::Bool());
+INSTANTIATE_TEST_SUITE_P(All, HotseatOverviewSessionTest, testing::Bool());
 
-TEST_P(HotseatDisabledOverviewSessionTest,
-       NoWindowsIndicatorPositionSplitview) {
+// Tests that the bounds of the grid do not intersect the shelf or its hotseat.
+TEST_P(HotseatOverviewSessionTest, OverviewGridBounds) {
+  EnterTabletMode();
+  std::unique_ptr<aura::Window> window(CreateTestWindow());
+
+  ToggleOverview();
+  ASSERT_TRUE(overview_session());
+
+  Shelf* shelf = Shelf::ForWindow(Shell::GetPrimaryRootWindow());
+  const gfx::Rect shelf_bounds = shelf->GetIdealBounds();
+  const gfx::Rect hotseat_bounds =
+      shelf->shelf_widget()->hotseat_widget()->GetWindowBoundsInScreen();
+  EXPECT_FALSE(GetGridBounds().Intersects(shelf_bounds));
+  EXPECT_FALSE(GetGridBounds().Intersects(hotseat_bounds));
+}
+
+TEST_P(HotseatOverviewSessionTest, NoWindowsIndicatorPositionSplitview) {
   UpdateDisplay("400x300");
   EnterTabletMode();
   std::unique_ptr<aura::Window> window(CreateTestWindow());
@@ -1757,44 +1773,6 @@
             no_windows_widget->GetWindowBoundsInScreen().CenterPoint());
 }
 
-TEST_P(OverviewSessionTest, NoWindowsIndicatorPositionSplitview) {
-  // TODO(https://crbug.com/1009550): Make the shelf in-app for split view and
-  // overview.
-  if (chromeos::switches::ShouldShowShelfHotseat())
-    return;
-
-  UpdateDisplay("400x300");
-  EnterTabletMode();
-  std::unique_ptr<aura::Window> window(CreateTestWindow());
-
-  ToggleOverview();
-  ASSERT_TRUE(overview_session());
-  RoundedLabelWidget* no_windows_widget =
-      overview_session()->no_windows_widget_for_testing();
-  EXPECT_FALSE(no_windows_widget);
-
-  // Tests that when snapping a window to the left in splitview, the no windows
-  // indicator shows up in the middle of the right side of the screen.
-  split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT);
-  no_windows_widget = overview_session()->no_windows_widget_for_testing();
-  ASSERT_TRUE(no_windows_widget);
-
-  // There is a 8dp divider in splitview, the indicator should take that into
-  // account.
-  const int bounds_left = 200 + 4;
-  int expected_x = bounds_left + (400 - (bounds_left)) / 2;
-  const int expected_y = (300 - ShelfConfig::Get()->shelf_size()) / 2;
-  EXPECT_EQ(gfx::Point(expected_x, expected_y),
-            no_windows_widget->GetWindowBoundsInScreen().CenterPoint());
-
-  // Tests that when snapping a window to the right in splitview, the no windows
-  // indicator shows up in the middle of the left side of the screen.
-  split_view_controller()->SnapWindow(window.get(), SplitViewController::RIGHT);
-  expected_x = /*bounds_right=*/(200 - 4) / 2;
-  EXPECT_EQ(gfx::Point(expected_x, expected_y),
-            no_windows_widget->GetWindowBoundsInScreen().CenterPoint());
-}
-
 // Tests that the no windows indicator shows properly after adding an item.
 TEST_P(OverviewSessionTest, NoWindowsIndicatorAddItem) {
   EnterTabletMode();
diff --git a/ash/wm/workspace/two_step_edge_cycler.cc b/ash/wm/workspace/two_step_edge_cycler.cc
deleted file mode 100644
index f31b8407..0000000
--- a/ash/wm/workspace/two_step_edge_cycler.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/workspace/two_step_edge_cycler.h"
-
-#include <cstdlib>
-
-namespace ash {
-namespace {
-
-// We cycle to the second mode if any of the following happens while the mouse
-// is on the edge of the workspace:
-// . The user stops moving the mouse for |kMaxDelay| and then moves the mouse
-//   again in the preferred direction from the last paused location for at least
-//   |kMaxPixelsAfterPause| horizontal pixels.
-// . The mouse moves |kMaxPixels| horizontal pixels in the preferred direction.
-// . The mouse is moved |kMaxMoves| times since the last pause.
-const int kMaxDelay = 400;
-const int kMaxPixels = 100;
-const int kMaxPixelsAfterPause = 10;
-const int kMaxMoves = 25;
-
-}  // namespace
-
-TwoStepEdgeCycler::TwoStepEdgeCycler(const gfx::Point& start,
-                                     TwoStepEdgeCycler::Direction direction)
-    : second_mode_(false),
-      time_last_move_(base::TimeTicks::Now()),
-      num_moves_(0),
-      start_x_(start.x()),
-      paused_x_(start.x()),
-      paused_(false),
-      direction_(direction) {}
-
-TwoStepEdgeCycler::~TwoStepEdgeCycler() = default;
-
-void TwoStepEdgeCycler::OnMove(const gfx::Point& location) {
-  if (second_mode_)
-    return;
-
-  if ((base::TimeTicks::Now() - time_last_move_).InMilliseconds() > kMaxDelay) {
-    paused_ = true;
-    paused_x_ = location.x();
-    num_moves_ = 0;
-  }
-  time_last_move_ = base::TimeTicks::Now();
-
-  int compare_x = paused_ ? paused_x_ : start_x_;
-  if (location.x() != compare_x &&
-      (location.x() < compare_x) != (direction_ == DIRECTION_LEFT)) {
-    return;
-  }
-
-  ++num_moves_;
-  bool moved_in_the_same_direction_after_pause =
-      paused_ && std::abs(location.x() - paused_x_) >= kMaxPixelsAfterPause;
-  second_mode_ = moved_in_the_same_direction_after_pause ||
-                 std::abs(location.x() - start_x_) >= kMaxPixels ||
-                 num_moves_ >= kMaxMoves;
-}
-
-}  // namespace ash
diff --git a/ash/wm/workspace/two_step_edge_cycler.h b/ash/wm/workspace/two_step_edge_cycler.h
deleted file mode 100644
index d6aca87ee..0000000
--- a/ash/wm/workspace/two_step_edge_cycler.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_WORKSPACE_TWO_STEP_EDGE_CYCLER_H_
-#define ASH_WM_WORKSPACE_TWO_STEP_EDGE_CYCLER_H_
-
-#include "ash/ash_export.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "ui/gfx/geometry/point.h"
-
-namespace ash {
-
-// TwoStepEdgeCycler is responsible for cycling between two modes when the mouse
-// is at the edge of the workspace. The cycler does not loop so it is impossible
-// to get back to the first mode once the second mode is reached.
-// TwoStepEdgeCycler should be destroyed once the mouse moves off the edge of
-// the workspace.
-class ASH_EXPORT TwoStepEdgeCycler {
- public:
-  // The direction in which a mouse should travel to switch mode.
-  enum Direction { DIRECTION_LEFT, DIRECTION_RIGHT };
-
-  explicit TwoStepEdgeCycler(const gfx::Point& start, Direction direction);
-  ~TwoStepEdgeCycler();
-
-  // Update which mode should be used as a result of a mouse / touch move.
-  // |location| is the location of the event.
-  void OnMove(const gfx::Point& location);
-
-  bool use_second_mode() const { return second_mode_; }
-
- private:
-  // Whether the second mode should be used.
-  bool second_mode_;
-
-  // Time OnMove() was last invoked.
-  base::TimeTicks time_last_move_;
-
-  // The number of moves since the cycler was constructed.
-  int num_moves_;
-
-  // Initial x-coordinate.
-  int start_x_;
-
-  // x-coordinate when paused.
-  int paused_x_;
-
-  // Whether the movement was paused.
-  bool paused_;
-
-  // Determines a preferred movement direction that we are watching.
-  Direction direction_;
-
-  DISALLOW_COPY_AND_ASSIGN(TwoStepEdgeCycler);
-};
-
-}  // namespace ash
-
-#endif  // ASH_WM_WORKSPACE_TWO_STEP_EDGE_CYCLER_H_
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 6aa5451f..98410db 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -30,7 +30,6 @@
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
 #include "ash/wm/workspace/phantom_window_controller.h"
-#include "ash/wm/workspace/two_step_edge_cycler.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/user_metrics.h"
 #include "ui/aura/client/aura_constants.h"
@@ -471,7 +470,6 @@
   } else {
     snap_type_ = SNAP_NONE;
     snap_phantom_window_controller_.reset();
-    edge_cycler_.reset();
   }
 }
 
@@ -1046,7 +1044,6 @@
   snap_type_ = GetSnapType(location);
   if (snap_type_ == SNAP_NONE || snap_type_ != last_type) {
     snap_phantom_window_controller_.reset();
-    edge_cycler_.reset();
     if (snap_type_ == SNAP_NONE)
       return;
   }
@@ -1056,17 +1053,8 @@
   if (!can_snap) {
     snap_type_ = SNAP_NONE;
     snap_phantom_window_controller_.reset();
-    edge_cycler_.reset();
     return;
   }
-  if (!edge_cycler_) {
-    edge_cycler_.reset(new TwoStepEdgeCycler(
-        location, snap_type_ == SNAP_LEFT
-                      ? TwoStepEdgeCycler::DIRECTION_LEFT
-                      : TwoStepEdgeCycler::DIRECTION_RIGHT));
-  } else {
-    edge_cycler_->OnMove(location);
-  }
 
   // Update phantom window with snapped guide bounds.
   const gfx::Rect phantom_bounds =
diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h
index f2c5fd8..ea338b68f 100644
--- a/ash/wm/workspace/workspace_window_resizer.h
+++ b/ash/wm/workspace/workspace_window_resizer.h
@@ -19,7 +19,6 @@
 
 namespace ash {
 class PhantomWindowController;
-class TwoStepEdgeCycler;
 class WindowSize;
 class WindowState;
 
@@ -196,10 +195,6 @@
   // is a grid and the caption is being dragged.
   std::unique_ptr<PhantomWindowController> snap_phantom_window_controller_;
 
-  // Used to determine whether the window should be snapped when the user drags
-  // a window to the edge of the screen.
-  std::unique_ptr<TwoStepEdgeCycler> edge_cycler_;
-
   // The edge to which the window should be snapped to at the end of the drag.
   SnapType snap_type_;
 
diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc
index 6b0bae08..15d1bdec 100644
--- a/ash/wm/workspace/workspace_window_resizer_unittest.cc
+++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc
@@ -633,8 +633,6 @@
     int bottom =
         screen_util::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
     resizer->CompleteDrag();
-    // With the resolution of 500x600 we will hit in this case the 50% screen
-    // size setting.
     // TODO(varkha): Insets are updated because of http://crbug.com/292238
     EXPECT_EQ("250,0 250x" + base::NumberToString(bottom),
               window_->bounds().ToString());
diff --git a/base/android/java/src/org/chromium/base/ContextUtils.java b/base/android/java/src/org/chromium/base/ContextUtils.java
index 5c24041c4..14ef407 100644
--- a/base/android/java/src/org/chromium/base/ContextUtils.java
+++ b/base/android/java/src/org/chromium/base/ContextUtils.java
@@ -73,6 +73,7 @@
      *
      * @return The application-wide shared preferences.
      */
+    @SuppressWarnings("DefaultSharedPreferencesCheck")
     private static SharedPreferences fetchAppSharedPreferences() {
         return PreferenceManager.getDefaultSharedPreferences(sApplicationContext);
     }
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index 8b25509..85be687 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -25,7 +25,7 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "base/timer/elapsed_timer.h"
+#include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 
 namespace base {
@@ -104,10 +104,10 @@
     std::unique_ptr<ProfileBuilder> profile_builder;
 
     // The absolute time for the next sample.
-    Time next_sample_time;
+    TimeTicks next_sample_time;
 
     // The time that a profile was started, for calculating the total duration.
-    Time profile_start_time;
+    TimeTicks profile_start_time;
 
     // Counter that indicates the current sample position along the acquisition.
     int sample_count = 0;
@@ -441,7 +441,8 @@
   DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
   DCHECK_EQ(0u, active_collections_.count(collection->collection_id));
 
-  TimeDelta profile_duration = Time::Now() - collection->profile_start_time +
+  TimeDelta profile_duration = TimeTicks::Now() -
+                               collection->profile_start_time +
                                collection->params.sampling_interval;
 
   collection->profile_builder->OnProfileCompleted(
@@ -543,8 +544,8 @@
 
   // If this is the first sample, the collection params need to be filled.
   if (collection->sample_count == 0) {
-    collection->profile_start_time = Time::Now();
-    collection->next_sample_time = Time::Now();
+    collection->profile_start_time = TimeTicks::Now();
+    collection->next_sample_time = TimeTicks::Now();
   }
 
   // Record a single sample.
@@ -554,13 +555,13 @@
   // Schedule the next sample recording if there is one.
   if (++collection->sample_count < collection->params.samples_per_profile) {
     if (!collection->params.keep_consistent_sampling_interval)
-      collection->next_sample_time = Time::Now();
+      collection->next_sample_time = TimeTicks::Now();
     collection->next_sample_time += collection->params.sampling_interval;
     bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask(
         FROM_HERE,
         BindOnce(&SamplingThread::RecordSampleTask, Unretained(this),
                  collection_id),
-        std::max(collection->next_sample_time - Time::Now(), TimeDelta()));
+        std::max(collection->next_sample_time - TimeTicks::Now(), TimeDelta()));
     DCHECK(success);
     return;
   }
diff --git a/base/win/.clang-tidy b/base/win/.clang-tidy
new file mode 100644
index 0000000..a83692df
--- /dev/null
+++ b/base/win/.clang-tidy
@@ -0,0 +1,5 @@
+---
+Checks: '-*,
+         modernize-use-nullptr'
+HeaderFilterRegex: 'base/win/*'
+...
diff --git a/base/win/com_init_check_hook.cc b/base/win/com_init_check_hook.cc
index 9ec32fbe..034c6ec 100644
--- a/base/win/com_init_check_hook.cc
+++ b/base/win/com_init_check_hook.cc
@@ -5,6 +5,7 @@
 #include "base/win/com_init_check_hook.h"
 
 #include <windows.h>
+
 #include <objbase.h>
 #include <stdint.h>
 #include <string.h>
@@ -145,7 +146,8 @@
     // See banner comment above why this subtracts 5 bytes.
     co_create_instance_padded_address_ =
         reinterpret_cast<uint32_t>(
-            GetProcAddress(ole32_library_, "CoCreateInstance")) - 5;
+            GetProcAddress(ole32_library_, "CoCreateInstance")) -
+        5;
 
     // See banner comment above why this adds 7 bytes.
     original_co_create_instance_body_function_ =
diff --git a/base/win/com_init_check_hook_unittest.cc b/base/win/com_init_check_hook_unittest.cc
index d144b83..567f9ba 100644
--- a/base/win/com_init_check_hook_unittest.cc
+++ b/base/win/com_init_check_hook_unittest.cc
@@ -72,7 +72,8 @@
 
   uint32_t co_create_instance_padded_address =
       reinterpret_cast<uint32_t>(
-          GetProcAddress(ole32_library, "CoCreateInstance")) - 5;
+          GetProcAddress(ole32_library, "CoCreateInstance")) -
+      5;
   const unsigned char* co_create_instance_bytes =
       reinterpret_cast<const unsigned char*>(co_create_instance_padded_address);
   const unsigned char original_byte = co_create_instance_bytes[0];
diff --git a/base/win/com_init_util.cc b/base/win/com_init_util.cc
index d81f4201..57c3c6f 100644
--- a/base/win/com_init_util.cc
+++ b/base/win/com_init_util.cc
@@ -5,6 +5,7 @@
 #include "base/win/com_init_util.h"
 
 #include <windows.h>
+
 #include <winternl.h>
 
 namespace base {
diff --git a/base/win/dllmain.cc b/base/win/dllmain.cc
index 907c7f40..cb221815 100644
--- a/base/win/dllmain.cc
+++ b/base/win/dllmain.cc
@@ -86,7 +86,7 @@
 
 // Custom crash code to get a unique entry in crash reports.
 NOINLINE static void CrashOnProcessDetach() {
-  *static_cast<volatile int*>(0) = 0x356;
+  *static_cast<volatile int*>(nullptr) = 0x356;
 }
 
 // Make DllMain call the listed callbacks.  This way any third parties that are
@@ -102,7 +102,7 @@
     return true;  // Some other service is doing this work.
 
   for (PIMAGE_TLS_CALLBACK* it = &__xl_a; it < &__xl_z; ++it) {
-    if (*it == NULL || *it == on_callback)
+    if (*it == nullptr || *it == on_callback)
       continue;  // Don't bother to call our own callback.
     (*it)(h, reason, reserved);
   }
diff --git a/base/win/enum_variant_unittest.cc b/base/win/enum_variant_unittest.cc
index 3165b5e..cd10a52 100644
--- a/base/win/enum_variant_unittest.cc
+++ b/base/win/enum_variant_unittest.cc
@@ -110,7 +110,7 @@
   // Clone it.
   Microsoft::WRL::ComPtr<IEnumVARIANT> ev2;
   EXPECT_EQ(S_OK, ev->Clone(&ev2));
-  EXPECT_TRUE(ev2 != NULL);
+  EXPECT_TRUE(ev2 != nullptr);
 
   VARIANT out_elements[3];
   for (int i = 0; i < 3; ++i)
diff --git a/base/win/event_trace_consumer.h b/base/win/event_trace_consumer.h
index 3b3e9f5..c75e7a36 100644
--- a/base/win/event_trace_consumer.h
+++ b/base/win/event_trace_consumer.h
@@ -7,9 +7,11 @@
 #define BASE_WIN_EVENT_TRACE_CONSUMER_H_
 
 #include <windows.h>
-#include <wmistr.h>
+
 #include <evntrace.h>
 #include <stddef.h>
+#include <wmistr.h>
+
 #include <vector>
 
 #include "base/macros.h"
@@ -35,12 +37,9 @@
 class EtwTraceConsumerBase {
  public:
   // Constructs a closed consumer.
-  EtwTraceConsumerBase() {
-  }
+  EtwTraceConsumerBase() {}
 
-  ~EtwTraceConsumerBase() {
-    Close();
-  }
+  ~EtwTraceConsumerBase() { Close(); }
 
   // Opens the named realtime session, which must be existent.
   // Note: You can use OpenRealtimeSession or OpenFileSession
@@ -63,8 +62,7 @@
 
  protected:
   // Override in subclasses to handle events.
-  static void ProcessEvent(EVENT_TRACE* event) {
-  }
+  static void ProcessEvent(EVENT_TRACE* event) {}
   // Override in subclasses to handle buffers.
   static bool ProcessBuffer(EVENT_TRACE_LOGFILE* buffer) {
     return true;  // keep going
@@ -86,8 +84,8 @@
   DISALLOW_COPY_AND_ASSIGN(EtwTraceConsumerBase);
 };
 
-template <class ImplClass> inline
-HRESULT EtwTraceConsumerBase<ImplClass>::OpenRealtimeSession(
+template <class ImplClass>
+inline HRESULT EtwTraceConsumerBase<ImplClass>::OpenRealtimeSession(
     const wchar_t* session_name) {
   EVENT_TRACE_LOGFILE logfile = {};
   logfile.LoggerName = const_cast<wchar_t*>(session_name);
@@ -103,8 +101,8 @@
   return S_OK;
 }
 
-template <class ImplClass> inline
-HRESULT EtwTraceConsumerBase<ImplClass>::OpenFileSession(
+template <class ImplClass>
+inline HRESULT EtwTraceConsumerBase<ImplClass>::OpenFileSession(
     const wchar_t* file_name) {
   EVENT_TRACE_LOGFILE logfile = {};
   logfile.LogFileName = const_cast<wchar_t*>(file_name);
@@ -119,19 +117,18 @@
   return S_OK;
 }
 
-template <class ImplClass> inline
-HRESULT EtwTraceConsumerBase<ImplClass>::Consume() {
+template <class ImplClass>
+inline HRESULT EtwTraceConsumerBase<ImplClass>::Consume() {
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::MAY_BLOCK);
   ULONG err = ::ProcessTrace(&trace_handles_[0],
-                             static_cast<ULONG>(trace_handles_.size()),
-                             NULL,
-                             NULL);
+                             static_cast<ULONG>(trace_handles_.size()), nullptr,
+                             nullptr);
   return HRESULT_FROM_WIN32(err);
 }
 
-template <class ImplClass> inline
-HRESULT EtwTraceConsumerBase<ImplClass>::Close() {
+template <class ImplClass>
+inline HRESULT EtwTraceConsumerBase<ImplClass>::Close() {
   HRESULT hr = S_OK;
   for (size_t i = 0; i < trace_handles_.size(); ++i) {
     if (NULL != trace_handles_[i]) {
diff --git a/base/win/event_trace_consumer_unittest.cc b/base/win/event_trace_consumer_unittest.cc
index 9c950fd..2b580196 100644
--- a/base/win/event_trace_consumer_unittest.cc
+++ b/base/win/event_trace_consumer_unittest.cc
@@ -31,10 +31,10 @@
 
 typedef std::list<EVENT_TRACE> EventQueue;
 
-class TestConsumer: public EtwTraceConsumerBase<TestConsumer> {
+class TestConsumer : public EtwTraceConsumerBase<TestConsumer> {
  public:
   TestConsumer() {
-    sank_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL));
+    sank_event_.Set(::CreateEvent(nullptr, TRUE, FALSE, nullptr));
     ClearQueue();
   }
 
@@ -56,7 +56,7 @@
     events_.push_back(*event);
     EVENT_TRACE& back = events_.back();
 
-    if (event->MofData != NULL && event->MofLength != 0) {
+    if (event->MofData != nullptr && event->MofLength != 0) {
       back.MofData = new char[event->MofLength];
       memcpy(back.MofData, event->MofData, event->MofLength);
     }
@@ -77,11 +77,10 @@
 ScopedHandle TestConsumer::sank_event_;
 EventQueue TestConsumer::events_;
 
-class EtwTraceConsumerBaseTest: public testing::Test {
+class EtwTraceConsumerBaseTest : public testing::Test {
  public:
   EtwTraceConsumerBaseTest()
-      : session_name_(StringPrintf(L"TestSession-%d", GetCurrentProcId())) {
-  }
+      : session_name_(StringPrintf(L"TestSession-%d", GetCurrentProcId())) {}
 
   void SetUp() override {
     // Cleanup any potentially dangling sessions.
@@ -124,7 +123,7 @@
 
 namespace {
 
-class EtwTraceConsumerRealtimeTest: public EtwTraceConsumerBaseTest {
+class EtwTraceConsumerRealtimeTest : public EtwTraceConsumerBaseTest {
  public:
   void SetUp() override {
     EtwTraceConsumerBaseTest::SetUp();
@@ -143,19 +142,19 @@
   }
 
   static DWORD WINAPI ConsumerThreadMainProc(void* arg) {
-    return reinterpret_cast<EtwTraceConsumerRealtimeTest*>(arg)->
-        ConsumerThread();
+    return reinterpret_cast<EtwTraceConsumerRealtimeTest*>(arg)
+        ->ConsumerThread();
   }
 
   HRESULT StartConsumerThread() {
-    consumer_ready_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL));
+    consumer_ready_.Set(::CreateEvent(nullptr, TRUE, FALSE, nullptr));
     EXPECT_TRUE(consumer_ready_.IsValid());
-    consumer_thread_.Set(::CreateThread(NULL, 0, ConsumerThreadMainProc, this,
-                                        0, NULL));
-    if (consumer_thread_.Get() == NULL)
+    consumer_thread_.Set(
+        ::CreateThread(nullptr, 0, ConsumerThreadMainProc, this, 0, nullptr));
+    if (consumer_thread_.Get() == nullptr)
       return HRESULT_FROM_WIN32(::GetLastError());
 
-    HANDLE events[] = { consumer_ready_.Get(), consumer_thread_.Get() };
+    HANDLE events[] = {consumer_ready_.Get(), consumer_thread_.Get()};
     DWORD result =
         ::WaitForMultipleObjects(size(events), events, FALSE, INFINITE);
     switch (result) {
@@ -163,15 +162,15 @@
         // The event was set, the consumer_ is ready.
         return S_OK;
       case WAIT_OBJECT_0 + 1: {
-          // The thread finished. This may race with the event, so check
-          // explicitly for the event here, before concluding there's trouble.
-          if (::WaitForSingleObject(consumer_ready_.Get(), 0) == WAIT_OBJECT_0)
-            return S_OK;
-          DWORD exit_code = 0;
-          if (::GetExitCodeThread(consumer_thread_.Get(), &exit_code))
-            return exit_code;
-          return HRESULT_FROM_WIN32(::GetLastError());
-        }
+        // The thread finished. This may race with the event, so check
+        // explicitly for the event here, before concluding there's trouble.
+        if (::WaitForSingleObject(consumer_ready_.Get(), 0) == WAIT_OBJECT_0)
+          return S_OK;
+        DWORD exit_code = 0;
+        if (::GetExitCodeThread(consumer_thread_.Get(), &exit_code))
+          return exit_code;
+        return HRESULT_FROM_WIN32(::GetLastError());
+      }
       default:
         return E_UNEXPECTED;
     }
@@ -212,7 +211,7 @@
   // Wait around for the consumer_ thread a bit.
   ASSERT_EQ(static_cast<DWORD>(WAIT_TIMEOUT),
             ::WaitForSingleObject(consumer_thread_.Get(), 50));
-  ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+  ASSERT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
 
   // The consumer_ returns success on session stop.
   ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread());
@@ -220,10 +219,12 @@
 
 namespace {
 
+// clang-format off
 // {57E47923-A549-476f-86CA-503D57F59E62}
 DEFINE_GUID(
     kTestEventType,
     0x57e47923, 0xa549, 0x476f, 0x86, 0xca, 0x50, 0x3d, 0x57, 0xf5, 0x9e, 0x62);
+// clang-format on
 
 }  // namespace
 
@@ -249,7 +250,7 @@
   EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Log(&event.header));
   EXPECT_EQ(WAIT_OBJECT_0,
             ::WaitForSingleObject(TestConsumer::sank_event_.Get(), INFINITE));
-  ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+  ASSERT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
   ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread());
   ASSERT_NE(0u, TestConsumer::events_.size());
 }
@@ -258,10 +259,9 @@
 
 // We run events through a file session to assert that
 // the content comes through.
-class EtwTraceConsumerDataTest: public EtwTraceConsumerBaseTest {
+class EtwTraceConsumerDataTest : public EtwTraceConsumerBaseTest {
  public:
-  EtwTraceConsumerDataTest() {
-  }
+  EtwTraceConsumerDataTest() {}
 
   void SetUp() override {
     EtwTraceConsumerBaseTest::SetUp();
@@ -301,8 +301,8 @@
     EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Log(header));
     EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(test_provider_));
     EXPECT_HRESULT_SUCCEEDED(provider.Unregister());
-    EXPECT_HRESULT_SUCCEEDED(controller.Flush(NULL));
-    EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+    EXPECT_HRESULT_SUCCEEDED(controller.Flush(nullptr));
+    EXPECT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
 
     return S_OK;
   }
@@ -344,7 +344,6 @@
 
 }  // namespace
 
-
 TEST_F(EtwTraceConsumerDataTest, RoundTrip) {
   EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR);
 
@@ -352,14 +351,14 @@
   event.fields[0].DataPtr = reinterpret_cast<ULONG64>(kData);
   event.fields[0].Length = sizeof(kData);
 
-  PEVENT_TRACE trace = NULL;
+  PEVENT_TRACE trace = nullptr;
   HRESULT hr = RoundTripEvent(&event.header, &trace);
   if (hr == E_ACCESSDENIED) {
     VLOG(1) << "You must be an administrator to run this test on Vista";
     return;
   }
   ASSERT_HRESULT_SUCCEEDED(hr) << "RoundTripEvent failed";
-  ASSERT_TRUE(trace != NULL);
+  ASSERT_TRUE(trace != nullptr);
   ASSERT_EQ(sizeof(kData), trace->MofLength);
   ASSERT_STREQ(kData, reinterpret_cast<const char*>(trace->MofData));
 }
diff --git a/base/win/event_trace_controller.cc b/base/win/event_trace_controller.cc
index 115db20..d2fbac4 100644
--- a/base/win/event_trace_controller.cc
+++ b/base/win/event_trace_controller.cc
@@ -16,8 +16,8 @@
   prop->Wnode.BufferSize = sizeof(buffer_);
   prop->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
   prop->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
-  prop->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
-                            sizeof(wchar_t) * kMaxStringLen;
+  prop->LogFileNameOffset =
+      sizeof(EVENT_TRACE_PROPERTIES) + sizeof(wchar_t) * kMaxStringLen;
 }
 
 HRESULT EtwTraceProperties::SetLoggerName(const wchar_t* logger_name) {
@@ -25,9 +25,7 @@
   if (kMaxStringLen < len)
     return E_INVALIDARG;
 
-  memcpy(buffer_ + get()->LoggerNameOffset,
-         logger_name,
-         sizeof(wchar_t) * len);
+  memcpy(buffer_ + get()->LoggerNameOffset, logger_name, sizeof(wchar_t) * len);
   return S_OK;
 }
 
@@ -36,25 +34,23 @@
   if (kMaxStringLen < len)
     return E_INVALIDARG;
 
-  memcpy(buffer_ + get()->LogFileNameOffset,
-         logger_file_name,
+  memcpy(buffer_ + get()->LogFileNameOffset, logger_file_name,
          sizeof(wchar_t) * len);
   return S_OK;
 }
 
-EtwTraceController::EtwTraceController() : session_(NULL) {
-}
+EtwTraceController::EtwTraceController() : session_(NULL) {}
 
 EtwTraceController::~EtwTraceController() {
   if (session_)
-    Stop(NULL);
+    Stop(nullptr);
 }
 
 HRESULT EtwTraceController::Start(const wchar_t* session_name,
-    EtwTraceProperties* prop) {
+                                  EtwTraceProperties* prop) {
   DCHECK(NULL == session_ && session_name_.empty());
   EtwTraceProperties ignore;
-  if (prop == NULL)
+  if (prop == nullptr)
     prop = &ignore;
 
   HRESULT hr = Start(session_name, prop, &session_);
@@ -65,36 +61,38 @@
 }
 
 HRESULT EtwTraceController::StartFileSession(const wchar_t* session_name,
-    const wchar_t* logfile_path, bool realtime) {
+                                             const wchar_t* logfile_path,
+                                             bool realtime) {
   DCHECK(NULL == session_ && session_name_.empty());
 
   EtwTraceProperties prop;
   prop.SetLoggerFileName(logfile_path);
   EVENT_TRACE_PROPERTIES& p = *prop.get();
-  p.Wnode.ClientContext = 1;  // QPC timer accuracy.
+  p.Wnode.ClientContext = 1;                         // QPC timer accuracy.
   p.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;  // Sequential log.
   if (realtime)
     p.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
 
   p.MaximumFileSize = 100;  // 100M file size.
-  p.FlushTimer = 30;  // 30 seconds flush lag.
+  p.FlushTimer = 30;        // 30 seconds flush lag.
   return Start(session_name, &prop);
 }
 
 HRESULT EtwTraceController::StartRealtimeSession(const wchar_t* session_name,
-    size_t buffer_size) {
+                                                 size_t buffer_size) {
   DCHECK(NULL == session_ && session_name_.empty());
   EtwTraceProperties prop;
   EVENT_TRACE_PROPERTIES& p = *prop.get();
   p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY;
-  p.FlushTimer = 1;  // flush every second.
+  p.FlushTimer = 1;   // flush every second.
   p.BufferSize = 16;  // 16 K buffers.
   p.LogFileNameOffset = 0;
   return Start(session_name, &prop);
 }
 
-HRESULT EtwTraceController::EnableProvider(REFGUID provider, UCHAR level,
-    ULONG flags) {
+HRESULT EtwTraceController::EnableProvider(REFGUID provider,
+                                           UCHAR level,
+                                           ULONG flags) {
   ULONG error = ::EnableTrace(TRUE, flags, level, &provider, session_);
   return HRESULT_FROM_WIN32(error);
 }
@@ -106,11 +104,11 @@
 
 HRESULT EtwTraceController::Stop(EtwTraceProperties* properties) {
   EtwTraceProperties ignore;
-  if (properties == NULL)
+  if (properties == nullptr)
     properties = &ignore;
 
-  ULONG error = ::ControlTrace(session_, NULL, properties->get(),
-    EVENT_TRACE_CONTROL_STOP);
+  ULONG error = ::ControlTrace(session_, nullptr, properties->get(),
+                               EVENT_TRACE_CONTROL_STOP);
   if (ERROR_SUCCESS != error)
     return HRESULT_FROM_WIN32(error);
 
@@ -121,10 +119,10 @@
 
 HRESULT EtwTraceController::Flush(EtwTraceProperties* properties) {
   EtwTraceProperties ignore;
-  if (properties == NULL)
+  if (properties == nullptr)
     properties = &ignore;
 
-  ULONG error = ::ControlTrace(session_, NULL, properties->get(),
+  ULONG error = ::ControlTrace(session_, nullptr, properties->get(),
                                EVENT_TRACE_CONTROL_FLUSH);
   if (ERROR_SUCCESS != error)
     return HRESULT_FROM_WIN32(error);
@@ -133,38 +131,39 @@
 }
 
 HRESULT EtwTraceController::Start(const wchar_t* session_name,
-    EtwTraceProperties* properties, TRACEHANDLE* session_handle) {
-  DCHECK(properties != NULL);
+                                  EtwTraceProperties* properties,
+                                  TRACEHANDLE* session_handle) {
+  DCHECK(properties != nullptr);
   ULONG err = ::StartTrace(session_handle, session_name, properties->get());
   return HRESULT_FROM_WIN32(err);
 }
 
 HRESULT EtwTraceController::Query(const wchar_t* session_name,
-    EtwTraceProperties* properties) {
+                                  EtwTraceProperties* properties) {
   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                              EVENT_TRACE_CONTROL_QUERY);
   return HRESULT_FROM_WIN32(err);
 }
 
 HRESULT EtwTraceController::Update(const wchar_t* session_name,
-    EtwTraceProperties* properties) {
-  DCHECK(properties != NULL);
+                                   EtwTraceProperties* properties) {
+  DCHECK(properties != nullptr);
   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                              EVENT_TRACE_CONTROL_UPDATE);
   return HRESULT_FROM_WIN32(err);
 }
 
 HRESULT EtwTraceController::Stop(const wchar_t* session_name,
-    EtwTraceProperties* properties) {
-  DCHECK(properties != NULL);
+                                 EtwTraceProperties* properties) {
+  DCHECK(properties != nullptr);
   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                              EVENT_TRACE_CONTROL_STOP);
   return HRESULT_FROM_WIN32(err);
 }
 
 HRESULT EtwTraceController::Flush(const wchar_t* session_name,
-    EtwTraceProperties* properties) {
-  DCHECK(properties != NULL);
+                                  EtwTraceProperties* properties) {
+  DCHECK(properties != nullptr);
   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                              EVENT_TRACE_CONTROL_FLUSH);
   return HRESULT_FROM_WIN32(err);
diff --git a/base/win/event_trace_controller.h b/base/win/event_trace_controller.h
index 2e32b4c..8d506a51 100644
--- a/base/win/event_trace_controller.h
+++ b/base/win/event_trace_controller.h
@@ -21,9 +21,11 @@
 #define BASE_WIN_EVENT_TRACE_CONTROLLER_H_
 
 #include <windows.h>
-#include <wmistr.h>
+
 #include <evntrace.h>
 #include <stddef.h>
+#include <wmistr.h>
+
 #include <string>
 
 #include "base/base_export.h"
@@ -39,16 +41,14 @@
  public:
   EtwTraceProperties();
 
-  EVENT_TRACE_PROPERTIES* get() {
-    return &properties_;
-  }
+  EVENT_TRACE_PROPERTIES* get() { return &properties_; }
 
   const EVENT_TRACE_PROPERTIES* get() const {
     return reinterpret_cast<const EVENT_TRACE_PROPERTIES*>(&properties_);
   }
 
   const wchar_t* GetLoggerName() const {
-    return reinterpret_cast<const wchar_t *>(buffer_ + get()->LoggerNameOffset);
+    return reinterpret_cast<const wchar_t*>(buffer_ + get()->LoggerNameOffset);
   }
 
   // Copies logger_name to the properties structure.
@@ -64,8 +64,8 @@
   static const size_t kMaxStringLen = 1024;
   // Properties buffer allocates space for header and for
   // max length for name and session name.
-  static const size_t kBufSize = sizeof(EVENT_TRACE_PROPERTIES)
-      + 2 * sizeof(wchar_t) * (kMaxStringLen);
+  static const size_t kBufSize =
+      sizeof(EVENT_TRACE_PROPERTIES) + 2 * sizeof(wchar_t) * (kMaxStringLen);
 
  private:
   // The EVENT_TRACE_PROPERTIES structure needs to be overlaid on a
@@ -99,13 +99,13 @@
                            bool realtime = false);
 
   // Starts a realtime session with some default properties.
-  HRESULT StartRealtimeSession(const wchar_t* session_name,
-                               size_t buffer_size);
+  HRESULT StartRealtimeSession(const wchar_t* session_name, size_t buffer_size);
 
   // Enables "provider" at "level" for this session.
   // This will cause all providers registered with the GUID
   // "provider" to start tracing at the new level, systemwide.
-  HRESULT EnableProvider(const GUID& provider, UCHAR level,
+  HRESULT EnableProvider(const GUID& provider,
+                         UCHAR level,
                          ULONG flags = 0xFFFFFFFF);
   // Disables "provider".
   HRESULT DisableProvider(const GUID& provider);
diff --git a/base/win/event_trace_controller_unittest.cc b/base/win/event_trace_controller_unittest.cc
index 9958535..b1cfffe 100644
--- a/base/win/event_trace_controller_unittest.cc
+++ b/base/win/event_trace_controller_unittest.cc
@@ -5,7 +5,8 @@
 // Unit tests for event trace controller.
 
 #include <objbase.h>
-#include <initguid.h>
+
+#include <initguid.h>  // NOLINT - has to be last
 
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -27,16 +28,13 @@
 
 namespace {
 
-DEFINE_GUID(kGuidNull,
-    0x0000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0);
-
 const ULONG kTestProviderFlags = 0xCAFEBABE;
 
-class TestingProvider: public EtwTraceProvider {
+class TestingProvider : public EtwTraceProvider {
  public:
   explicit TestingProvider(const GUID& provider_name)
       : EtwTraceProvider(provider_name) {
-    callback_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL));
+    callback_event_.Set(::CreateEvent(nullptr, TRUE, FALSE, nullptr));
   }
 
   void WaitForCallback() {
@@ -63,7 +61,7 @@
   EXPECT_EQ(0u, p->Wnode.ProviderId);
   EXPECT_EQ(0u, p->Wnode.HistoricalContext);
 
-  EXPECT_TRUE(kGuidNull == p->Wnode.Guid);
+  EXPECT_TRUE(GUID_NULL == p->Wnode.Guid);
   EXPECT_EQ(0u, p->Wnode.ClientContext);
   EXPECT_EQ(static_cast<ULONG>(WNODE_FLAG_TRACED_GUID), p->Wnode.Flags);
 
@@ -82,7 +80,7 @@
   EXPECT_EQ(0u, p->BuffersWritten);
   EXPECT_EQ(0u, p->LogBuffersLost);
   EXPECT_EQ(0u, p->RealTimeBuffersLost);
-  EXPECT_EQ(0u, p->LoggerThreadId);
+  EXPECT_EQ(nullptr, p->LoggerThreadId);
   EXPECT_NE(0u, p->LogFileNameOffset);
   EXPECT_NE(0u, p->LoggerNameOffset);
 }
@@ -109,8 +107,7 @@
 class EtwTraceControllerTest : public testing::Test {
  public:
   EtwTraceControllerTest()
-      : session_name_(StringPrintf(L"TestSession-%d", GetCurrentProcId())) {
-  }
+      : session_name_(StringPrintf(L"TestSession-%d", GetCurrentProcId())) {}
 
   void SetUp() override {
     EtwTraceProperties ignore;
@@ -139,12 +136,11 @@
   EXPECT_STREQ(L"", controller.session_name());
 }
 
-
 TEST_F(EtwTraceControllerTest, StartRealTimeSession) {
   EtwTraceController controller;
 
-  HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(),
-                                               100 * 1024);
+  HRESULT hr =
+      controller.StartRealtimeSession(session_name_.c_str(), 100 * 1024);
   if (hr == E_ACCESSDENIED) {
     VLOG(1) << "You must be an administrator to run this test on Vista";
     return;
@@ -153,7 +149,7 @@
   EXPECT_NE(0u, controller.session());
   EXPECT_STREQ(session_name_.c_str(), controller.session_name());
 
-  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+  EXPECT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
   EXPECT_EQ(0u, controller.session());
   EXPECT_STREQ(L"", controller.session_name());
 }
@@ -176,7 +172,7 @@
   EXPECT_NE(0u, controller.session());
   EXPECT_STREQ(session_name_.c_str(), controller.session_name());
 
-  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+  EXPECT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
   EXPECT_EQ(0u, controller.session());
   EXPECT_STREQ(L"", controller.session_name());
   DeleteFile(temp, false);
@@ -190,15 +186,15 @@
   EXPECT_EQ(0u, provider.session_handle());
 
   EtwTraceController controller;
-  HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(),
-                                               100 * 1024);
+  HRESULT hr =
+      controller.StartRealtimeSession(session_name_.c_str(), 100 * 1024);
   if (hr == E_ACCESSDENIED) {
     VLOG(1) << "You must be an administrator to run this test on Vista";
     return;
   }
 
-  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_,
-                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));
+  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(
+      test_provider_, TRACE_LEVEL_VERBOSE, kTestProviderFlags));
 
   provider.WaitForCallback();
 
@@ -215,8 +211,8 @@
   EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Unregister());
 
   // Enable the provider again, before registering.
-  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_,
-                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));
+  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(
+      test_provider_, TRACE_LEVEL_VERBOSE, kTestProviderFlags));
 
   // Register the provider again, the settings above
   // should take immediate effect.
@@ -228,7 +224,7 @@
   // Consume the callback event of the previous controller.EnableProvider().
   provider.WaitForCallback();
 
-  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
+  EXPECT_HRESULT_SUCCEEDED(controller.Stop(nullptr));
 
   // Windows 7 does not call the callback when Stop() is called so we
   // can't wait, and enable_level and enable_flags are not zeroed.
diff --git a/base/win/event_trace_provider.cc b/base/win/event_trace_provider.cc
index 8fcf67d..4bbf86f 100644
--- a/base/win/event_trace_provider.cc
+++ b/base/win/event_trace_provider.cc
@@ -3,26 +3,30 @@
 // found in the LICENSE file.
 //
 #include "base/win/event_trace_provider.h"
+
 #include <windows.h>
+
 #include <cguid.h>
 
 namespace base {
 namespace win {
 
 TRACE_GUID_REGISTRATION EtwTraceProvider::obligatory_guid_registration_ = {
-  &GUID_NULL,
-  NULL
-};
+    &GUID_NULL, nullptr};
 
 EtwTraceProvider::EtwTraceProvider(const GUID& provider_name)
-    : provider_name_(provider_name), registration_handle_(NULL),
-      session_handle_(NULL), enable_flags_(0), enable_level_(0) {
-}
+    : provider_name_(provider_name),
+      registration_handle_(NULL),
+      session_handle_(NULL),
+      enable_flags_(0),
+      enable_level_(0) {}
 
 EtwTraceProvider::EtwTraceProvider()
-    : provider_name_(GUID_NULL), registration_handle_(NULL),
-      session_handle_(NULL), enable_flags_(0), enable_level_(0) {
-}
+    : provider_name_(GUID_NULL),
+      registration_handle_(NULL),
+      session_handle_(NULL),
+      enable_flags_(0),
+      enable_level_(0) {}
 
 EtwTraceProvider::~EtwTraceProvider() {
   Unregister();
@@ -69,8 +73,10 @@
 }
 
 ULONG WINAPI EtwTraceProvider::ControlCallback(WMIDPREQUESTCODE request,
-    void* context, ULONG *reserved, void* buffer) {
-  EtwTraceProvider *provider = reinterpret_cast<EtwTraceProvider*>(context);
+                                               void* context,
+                                               ULONG* reserved,
+                                               void* buffer) {
+  EtwTraceProvider* provider = reinterpret_cast<EtwTraceProvider*>(context);
 
   return provider->Callback(request, buffer);
 }
@@ -79,8 +85,9 @@
   if (provider_name_ == GUID_NULL)
     return ERROR_INVALID_NAME;
 
-  return ::RegisterTraceGuids(ControlCallback, this, &provider_name_,
-      1, &obligatory_guid_registration_, NULL, NULL, &registration_handle_);
+  return ::RegisterTraceGuids(ControlCallback, this, &provider_name_, 1,
+                              &obligatory_guid_registration_, nullptr, nullptr,
+                              &registration_handle_);
 }
 
 ULONG EtwTraceProvider::Unregister() {
@@ -96,29 +103,35 @@
 }
 
 ULONG EtwTraceProvider::Log(const EtwEventClass& event_class,
-    EtwEventType type, EtwEventLevel level, const char *message) {
+                            EtwEventType type,
+                            EtwEventLevel level,
+                            const char* message) {
   if (NULL == session_handle_ || enable_level_ < level)
     return ERROR_SUCCESS;  // No one listening.
 
   EtwMofEvent<1> event(event_class, type, level);
 
   event.fields[0].DataPtr = reinterpret_cast<ULONG64>(message);
-  event.fields[0].Length = message ?
-      static_cast<ULONG>(sizeof(message[0]) * (1 + strlen(message))) : 0;
+  event.fields[0].Length =
+      message ? static_cast<ULONG>(sizeof(message[0]) * (1 + strlen(message)))
+              : 0;
 
   return ::TraceEvent(session_handle_, &event.header);
 }
 
 ULONG EtwTraceProvider::Log(const EtwEventClass& event_class,
-    EtwEventType type, EtwEventLevel level, const wchar_t *message) {
+                            EtwEventType type,
+                            EtwEventLevel level,
+                            const wchar_t* message) {
   if (NULL == session_handle_ || enable_level_ < level)
     return ERROR_SUCCESS;  // No one listening.
 
   EtwMofEvent<1> event(event_class, type, level);
 
   event.fields[0].DataPtr = reinterpret_cast<ULONG64>(message);
-  event.fields[0].Length = message ?
-      static_cast<ULONG>(sizeof(message[0]) * (1 + wcslen(message))) : 0;
+  event.fields[0].Length =
+      message ? static_cast<ULONG>(sizeof(message[0]) * (1 + wcslen(message)))
+              : 0;
 
   return ::TraceEvent(session_handle_, &event.header);
 }
diff --git a/base/win/event_trace_provider.h b/base/win/event_trace_provider.h
index d550dd68..875c62ea 100644
--- a/base/win/event_trace_provider.h
+++ b/base/win/event_trace_provider.h
@@ -8,10 +8,11 @@
 #define BASE_WIN_EVENT_TRACE_PROVIDER_H_
 
 #include <windows.h>
-#include <wmistr.h>
+
 #include <evntrace.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <wmistr.h>
 
 #include <limits>
 
@@ -28,13 +29,15 @@
 typedef ULONG EtwEventFlags;
 
 // Base class is a POD for correctness.
-template <size_t N> struct EtwMofEventBase {
+template <size_t N>
+struct EtwMofEventBase {
   EVENT_TRACE_HEADER header;
   MOF_FIELD fields[N];
 };
 
 // Utility class to auto-initialize event trace header structures.
-template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> {
+template <size_t N>
+class EtwMofEvent : public EtwMofEventBase<N> {
  public:
   typedef EtwMofEventBase<N> Super;
 
@@ -43,11 +46,10 @@
   using EtwMofEventBase<N>::header;
   using EtwMofEventBase<N>::fields;
 
-  EtwMofEvent() {
-    memset(static_cast<Super*>(this), 0, sizeof(Super));
-  }
+  EtwMofEvent() { memset(static_cast<Super*>(this), 0, sizeof(Super)); }
 
-  EtwMofEvent(const EtwEventClass& event_class, EtwEventType type,
+  EtwMofEvent(const EtwEventClass& event_class,
+              EtwEventType type,
               EtwEventLevel level) {
     memset(static_cast<Super*>(this), 0, sizeof(Super));
     header.Size = sizeof(Super);
@@ -57,8 +59,10 @@
     header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR;
   }
 
-  EtwMofEvent(const EtwEventClass& event_class, EtwEventType type,
-              EtwEventVersion version, EtwEventLevel level) {
+  EtwMofEvent(const EtwEventClass& event_class,
+              EtwEventType type,
+              EtwEventVersion version,
+              EtwEventLevel level) {
     memset(static_cast<Super*>(this), 0, sizeof(Super));
     header.Size = sizeof(Super);
     header.Guid = event_class;
@@ -76,7 +80,7 @@
     }
   }
 
-  EVENT_TRACE_HEADER* get() { return& header; }
+  EVENT_TRACE_HEADER* get() { return &header; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(EtwMofEvent);
@@ -125,15 +129,19 @@
   //      bit set, to test whether to log for a particular sub "facility".
   bool ShouldLog(EtwEventLevel level, EtwEventFlags flags) {
     return NULL != session_handle_ && level >= enable_level_ &&
-        (0 != (flags & enable_flags_));
+           (0 != (flags & enable_flags_));
   }
 
   // Simple wrappers to log Unicode and ANSI strings.
   // Do nothing if !ShouldLog(level, 0xFFFFFFFF).
-  ULONG Log(const EtwEventClass& event_class, EtwEventType type,
-            EtwEventLevel level, const char *message);
-  ULONG Log(const EtwEventClass& event_class, EtwEventType type,
-            EtwEventLevel level, const wchar_t *message);
+  ULONG Log(const EtwEventClass& event_class,
+            EtwEventType type,
+            EtwEventLevel level,
+            const char* message);
+  ULONG Log(const EtwEventClass& event_class,
+            EtwEventType type,
+            EtwEventLevel level,
+            const wchar_t* message);
 
   // Log the provided event.
   ULONG Log(EVENT_TRACE_HEADER* event);
@@ -162,8 +170,10 @@
   ULONG EnableEvents(PVOID buffer);
   ULONG DisableEvents();
   ULONG Callback(WMIDPREQUESTCODE request, PVOID buffer);
-  static ULONG WINAPI ControlCallback(WMIDPREQUESTCODE request, PVOID context,
-                                      ULONG *reserved, PVOID buffer);
+  static ULONG WINAPI ControlCallback(WMIDPREQUESTCODE request,
+                                      PVOID context,
+                                      ULONG* reserved,
+                                      PVOID buffer);
 
   GUID provider_name_;
   TRACEHANDLE registration_handle_;
diff --git a/base/win/event_trace_provider_unittest.cc b/base/win/event_trace_provider_unittest.cc
index 7d57773..82e76aa 100644
--- a/base/win/event_trace_provider_unittest.cc
+++ b/base/win/event_trace_provider_unittest.cc
@@ -6,20 +6,25 @@
 #include "base/win/event_trace_provider.h"
 #include <new>
 #include "testing/gtest/include/gtest/gtest.h"
+
 #include <initguid.h>  // NOLINT - has to be last
 
 namespace {
 
-using base::win::EtwTraceProvider;
 using base::win::EtwMofEvent;
+using base::win::EtwTraceProvider;
 
+// clang-format off
 // {7F0FD37F-FA3C-4cd6-9242-DF60967A2CB2}
 DEFINE_GUID(kTestProvider,
   0x7f0fd37f, 0xfa3c, 0x4cd6, 0x92, 0x42, 0xdf, 0x60, 0x96, 0x7a, 0x2c, 0xb2);
+// clang-format on
 
+// clang-format off
 // {7F0FD37F-FA3C-4cd6-9242-DF60967A2CB2}
 DEFINE_GUID(kTestEventClass,
   0x7f0fd37f, 0xfa3c, 0x4cd6, 0x92, 0x42, 0xdf, 0x60, 0x96, 0x7a, 0x2c, 0xb2);
+// clang-format on
 
 }  // namespace
 
diff --git a/base/win/iat_patch_function.cc b/base/win/iat_patch_function.cc
index f1f28c27..07d32c5 100644
--- a/base/win/iat_patch_function.cc
+++ b/base/win/iat_patch_function.cc
@@ -42,11 +42,15 @@
   return iat_function.pointer;
 }
 
-bool InterceptEnumCallback(const base::win::PEImage& image, const char* module,
-                           DWORD ordinal, const char* name, DWORD hint,
-                           IMAGE_THUNK_DATA* iat, void* cookie) {
+bool InterceptEnumCallback(const base::win::PEImage& image,
+                           const char* module,
+                           DWORD ordinal,
+                           const char* name,
+                           DWORD hint,
+                           IMAGE_THUNK_DATA* iat,
+                           void* cookie) {
   InterceptFunctionInformation* intercept_information =
-    reinterpret_cast<InterceptFunctionInformation*>(cookie);
+      reinterpret_cast<InterceptFunctionInformation*>(cookie);
 
   if (!intercept_information) {
     NOTREACHED();
@@ -99,7 +103,8 @@
 //          as defined in winerror.h
 DWORD InterceptImportedFunction(HMODULE module_handle,
                                 const char* imported_from_module,
-                                const char* function_name, void* new_function,
+                                const char* function_name,
+                                void* new_function,
                                 void** old_function,
                                 IMAGE_THUNK_DATA** iat_thunk) {
   if (!module_handle || !imported_from_module || !function_name ||
@@ -114,14 +119,13 @@
     return ERROR_INVALID_PARAMETER;
   }
 
-  InterceptFunctionInformation intercept_information = {
-    false,
-    imported_from_module,
-    function_name,
-    new_function,
-    old_function,
-    iat_thunk,
-    ERROR_GEN_FAILURE};
+  InterceptFunctionInformation intercept_information = {false,
+                                                        imported_from_module,
+                                                        function_name,
+                                                        new_function,
+                                                        old_function,
+                                                        iat_thunk,
+                                                        ERROR_GEN_FAILURE};
 
   // First go through the IAT. If we don't find the import we are looking
   // for in IAT, search delay import table.
@@ -203,12 +207,9 @@
   DCHECK_EQ(nullptr, intercept_function_);
   DCHECK(module);
 
-  DWORD error = InterceptImportedFunction(module,
-                                          imported_from_module,
-                                          function_name,
-                                          new_function,
-                                          &original_function_,
-                                          &iat_thunk_);
+  DWORD error =
+      InterceptImportedFunction(module, imported_from_module, function_name,
+                                new_function, &original_function_, &iat_thunk_);
 
   if (NO_ERROR == error) {
     DCHECK_NE(original_function_, intercept_function_);
@@ -219,8 +220,7 @@
 }
 
 DWORD IATPatchFunction::Unpatch() {
-  DWORD error = RestoreImportedFunction(intercept_function_,
-                                        original_function_,
+  DWORD error = RestoreImportedFunction(intercept_function_, original_function_,
                                         iat_thunk_);
   DCHECK_EQ(static_cast<DWORD>(NO_ERROR), error);
 
diff --git a/base/win/iat_patch_function.h b/base/win/iat_patch_function.h
index 22655a0..c6229cb2 100644
--- a/base/win/iat_patch_function.h
+++ b/base/win/iat_patch_function.h
@@ -59,13 +59,10 @@
   // Returns: Windows error code (winerror.h). NO_ERROR if successful
   DWORD Unpatch();
 
-  bool is_patched() const {
-    return (NULL != intercept_function_);
-  }
+  bool is_patched() const { return (nullptr != intercept_function_); }
 
   void* original_function() const;
 
-
  private:
   HMODULE module_handle_ = nullptr;
   void* intercept_function_ = nullptr;
diff --git a/base/win/map.h b/base/win/map.h
index fff0cc1..d7148952 100644
--- a/base/win/map.h
+++ b/base/win/map.h
@@ -363,7 +363,8 @@
   IFACEMETHODIMP Clear() override {
     map_.clear();
     NotifyMapChanged(
-        ABI::Windows::Foundation::Collections::CollectionChange_Reset, 0);
+        ABI::Windows::Foundation::Collections::CollectionChange_Reset,
+        0);  // NOLINT(modernize-use-nullptr): AbiK may not be a pointer.
     return S_OK;
   }
 
diff --git a/base/win/message_window.cc b/base/win/message_window.cc
index 7fb5039..7f26993 100644
--- a/base/win/message_window.cc
+++ b/base/win/message_window.cc
@@ -45,12 +45,12 @@
   window_class.cbClsExtra = 0;
   window_class.cbWndExtra = 0;
   window_class.hInstance = instance_;
-  window_class.hIcon = NULL;
-  window_class.hCursor = NULL;
-  window_class.hbrBackground = NULL;
-  window_class.lpszMenuName = NULL;
+  window_class.hIcon = nullptr;
+  window_class.hCursor = nullptr;
+  window_class.hbrBackground = nullptr;
+  window_class.lpszMenuName = nullptr;
   window_class.lpszClassName = kMessageWindowClassName;
-  window_class.hIconSm = NULL;
+  window_class.hIconSm = nullptr;
   atom_ = RegisterClassEx(&window_class);
   if (atom_ == 0) {
     PLOG(ERROR)
@@ -69,21 +69,19 @@
   }
 }
 
-MessageWindow::MessageWindow()
-    : window_(NULL) {
-}
+MessageWindow::MessageWindow() : window_(nullptr) {}
 
 MessageWindow::~MessageWindow() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
-  if (window_ != NULL) {
+  if (window_ != nullptr) {
     BOOL result = DestroyWindow(window_);
     DCHECK(result);
   }
 }
 
 bool MessageWindow::Create(MessageCallback message_callback) {
-  return DoCreate(std::move(message_callback), NULL);
+  return DoCreate(std::move(message_callback), nullptr);
 }
 
 bool MessageWindow::CreateNamed(MessageCallback message_callback,
@@ -93,7 +91,7 @@
 
 // static
 HWND MessageWindow::FindWindow(const string16& window_name) {
-  return FindWindowEx(HWND_MESSAGE, NULL, kMessageWindowClassName,
+  return FindWindowEx(HWND_MESSAGE, nullptr, kMessageWindowClassName,
                       as_wcstr(window_name));
 }
 
@@ -106,8 +104,9 @@
   message_callback_ = std::move(message_callback);
 
   WindowClass& window_class = g_window_class.Get();
-  window_ = CreateWindow(MAKEINTATOM(window_class.atom()), window_name, 0, 0, 0,
-                         0, 0, HWND_MESSAGE, 0, window_class.instance(), this);
+  window_ =
+      CreateWindow(MAKEINTATOM(window_class.atom()), window_name, 0, 0, 0, 0, 0,
+                   HWND_MESSAGE, nullptr, window_class.instance(), this);
   if (!window_) {
     PLOG(ERROR) << "Failed to create a message-only window";
     return false;
@@ -121,8 +120,8 @@
                                            UINT message,
                                            WPARAM wparam,
                                            LPARAM lparam) {
-  MessageWindow* self = reinterpret_cast<MessageWindow*>(
-      GetWindowLongPtr(hwnd, GWLP_USERDATA));
+  MessageWindow* self =
+      reinterpret_cast<MessageWindow*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
 
   switch (message) {
     // Set up the self before handling WM_CREATE.
@@ -136,8 +135,8 @@
 
       // Store pointer to the self to the window's user data.
       SetLastError(ERROR_SUCCESS);
-      LONG_PTR result = SetWindowLongPtr(
-          hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
+      LONG_PTR result = SetWindowLongPtr(hwnd, GWLP_USERDATA,
+                                         reinterpret_cast<LONG_PTR>(self));
       CHECK(result != 0 || GetLastError() == ERROR_SUCCESS);
       break;
     }
diff --git a/base/win/message_window.h b/base/win/message_window.h
index 2fef480..eac7f57 100644
--- a/base/win/message_window.h
+++ b/base/win/message_window.h
@@ -54,7 +54,9 @@
   bool DoCreate(MessageCallback message_callback, const wchar_t* window_name);
 
   // Invoked by the OS to process incoming window messages.
-  static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam,
+  static LRESULT CALLBACK WindowProc(HWND hwnd,
+                                     UINT message,
+                                     WPARAM wparam,
                                      LPARAM lparam);
 
   // Invoked to handle messages received by the window.
diff --git a/base/win/message_window_unittest.cc b/base/win/message_window_unittest.cc
index f11b56b4..9a10407 100644
--- a/base/win/message_window_unittest.cc
+++ b/base/win/message_window_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/win/message_window.h"
 #include "base/bind.h"
 #include "base/guid.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/win/message_window.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -13,8 +13,10 @@
 
 namespace {
 
-bool HandleMessage(
-    UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
+bool HandleMessage(UINT message,
+                   WPARAM wparam,
+                   LPARAM lparam,
+                   LRESULT* result) {
   // Return |wparam| as the result of WM_USER message.
   if (message == WM_USER) {
     *result = wparam;
@@ -54,7 +56,7 @@
   EXPECT_TRUE(window.CreateNamed(base::BindRepeating(&HandleMessage), name));
 
   HWND hwnd = win::MessageWindow::FindWindow(name);
-  EXPECT_TRUE(hwnd != NULL);
+  EXPECT_TRUE(hwnd != nullptr);
   EXPECT_EQ(SendMessage(hwnd, WM_USER, 200, 0), 200);
 }
 
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc
index bc4fd1a..ddd90ffd 100644
--- a/base/win/object_watcher.cc
+++ b/base/win/object_watcher.cc
@@ -4,12 +4,12 @@
 
 #include "base/win/object_watcher.h"
 
+#include <windows.h>
+
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 
-#include <windows.h>
-
 namespace base {
 namespace win {
 
@@ -96,8 +96,8 @@
                             delegate);
   object_ = object;
 
-  if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
-                                   this, INFINITE, wait_flags)) {
+  if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting, this,
+                                   INFINITE, wait_flags)) {
     DPLOG(FATAL) << "RegisterWaitForSingleObject failed";
     Reset();
     return false;
diff --git a/base/win/object_watcher_unittest.cc b/base/win/object_watcher_unittest.cc
index e5a2ad07..178cbe28 100644
--- a/base/win/object_watcher_unittest.cc
+++ b/base/win/object_watcher_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/win/object_watcher.h"
 
 #include <windows.h>
+
 #include <process.h>
 
 #include "base/run_loop.h"
@@ -25,8 +26,7 @@
 
 class DecrementCountDelegate : public ObjectWatcher::Delegate {
  public:
-  explicit DecrementCountDelegate(int* counter) : counter_(counter) {
-  }
+  explicit DecrementCountDelegate(int* counter) : counter_(counter) {}
   void OnObjectSignaled(HANDLE object) override { --(*counter_); }
 
  private:
@@ -41,7 +41,7 @@
   EXPECT_FALSE(watcher.IsWatching());
 
   // A manual-reset event that is not yet signaled.
-  HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
+  HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
 
   QuitDelegate delegate;
   bool ok = watcher.StartWatchingOnce(event, &delegate);
@@ -64,7 +64,7 @@
   ObjectWatcher watcher;
 
   // A manual-reset event that is not yet signaled.
-  HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
+  HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
 
   QuitDelegate delegate;
   bool ok = watcher.StartWatchingOnce(event, &delegate);
@@ -85,7 +85,7 @@
   DecrementCountDelegate delegate(&counter);
 
   // A manual-reset event that is not yet signaled.
-  HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
+  HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
 
   bool ok = watcher.StartWatchingOnce(event, &delegate);
   EXPECT_TRUE(ok);
@@ -112,7 +112,7 @@
   ObjectWatcher watcher;
 
   // A manual-reset event that is signaled before we begin watching.
-  HANDLE event = CreateEvent(NULL, TRUE, TRUE, NULL);
+  HANDLE event = CreateEvent(nullptr, TRUE, TRUE, nullptr);
 
   QuitDelegate delegate;
   bool ok = watcher.StartWatchingOnce(event, &delegate);
@@ -129,7 +129,7 @@
   // Simulate a task environment that dies before an ObjectWatcher.  This
   // ordinarily doesn't happen when people use the Thread class, but it can
   // happen when people use the Singleton pattern or atexit.
-  HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);  // not signaled
+  HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);  // not signaled
   {
     ObjectWatcher watcher;
     {
@@ -167,7 +167,7 @@
   EXPECT_FALSE(watcher.IsWatching());
 
   // An auto-reset event that is not yet signaled.
-  HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
+  HANDLE event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
 
   QuitAfterMultipleDelegate delegate(event, 2);
   bool ok = watcher.StartWatchingMultipleTimes(event, &delegate);
diff --git a/base/win/patch_util.cc b/base/win/patch_util.cc
index eb3bd653..0026ed4b 100644
--- a/base/win/patch_util.cc
+++ b/base/win/patch_util.cc
@@ -11,7 +11,7 @@
 namespace internal {
 
 DWORD ModifyCode(void* destination, const void* source, int length) {
-  if ((NULL == destination) || (NULL == source) || (0 == length)) {
+  if ((nullptr == destination) || (nullptr == source) || (0 == length)) {
     NOTREACHED();
     return ERROR_INVALID_PARAMETER;
   }
@@ -49,4 +49,4 @@
 
 }  // namespace internal
 }  // namespace win
-}  // namespace bsae
+}  // namespace base
diff --git a/base/win/patch_util.h b/base/win/patch_util.h
index 035fb83..9da88c9 100644
--- a/base/win/patch_util.h
+++ b/base/win/patch_util.h
@@ -20,6 +20,6 @@
 
 }  // namespace internal
 }  // namespace win
-}  // namespace bsae
+}  // namespace base
 
 #endif  // BASE_WIN_PATCH_UTIL_H_
diff --git a/base/win/pe_image.cc b/base/win/pe_image.cc
index 490d3ec..817e5c57 100644
--- a/base/win/pe_image.cc
+++ b/base/win/pe_image.cc
@@ -59,9 +59,11 @@
 }  // namespace
 
 // Callback used to enumerate imports. See EnumImportChunksFunction.
-bool ProcessImportChunk(const PEImage &image, LPCSTR module,
+bool ProcessImportChunk(const PEImage& image,
+                        LPCSTR module,
                         PIMAGE_THUNK_DATA name_table,
-                        PIMAGE_THUNK_DATA iat, PVOID cookie) {
+                        PIMAGE_THUNK_DATA iat,
+                        PVOID cookie) {
   EnumAllImportsStorage& storage =
       *reinterpret_cast<EnumAllImportsStorage*>(cookie);
 
@@ -105,7 +107,7 @@
   if (section < nt_headers->FileHeader.NumberOfSections)
     return first_section + section;
   else
-    return NULL;
+    return nullptr;
 }
 
 WORD PEImage::GetNumSections() const {
@@ -126,10 +128,10 @@
   PBYTE target = reinterpret_cast<PBYTE>(address);
   PIMAGE_SECTION_HEADER section;
 
-  for (UINT i = 0; NULL != (section = GetSectionHeader(i)); i++) {
+  for (UINT i = 0; nullptr != (section = GetSectionHeader(i)); i++) {
     // Don't use the virtual RVAToAddr.
-    PBYTE start = reinterpret_cast<PBYTE>(
-                      PEImage::RVAToAddr(section->VirtualAddress));
+    PBYTE start =
+        reinterpret_cast<PBYTE>(PEImage::RVAToAddr(section->VirtualAddress));
 
     DWORD size = section->Misc.VirtualSize;
 
@@ -137,15 +139,15 @@
       return section;
   }
 
-  return NULL;
+  return nullptr;
 }
 
 PIMAGE_SECTION_HEADER PEImage::GetImageSectionHeaderByName(
     LPCSTR section_name) const {
-  if (NULL == section_name)
-    return NULL;
+  if (nullptr == section_name)
+    return nullptr;
 
-  PIMAGE_SECTION_HEADER ret = NULL;
+  PIMAGE_SECTION_HEADER ret = nullptr;
   int num_sections = GetNumSections();
 
   for (int i = 0; i < num_sections; i++) {
@@ -168,7 +170,7 @@
       GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DEBUG);
   PIMAGE_DEBUG_DIRECTORY debug_directory =
       reinterpret_cast<PIMAGE_DEBUG_DIRECTORY>(
-      GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_DEBUG));
+          GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_DEBUG));
   if (!debug_directory)
     return false;
 
@@ -208,23 +210,23 @@
 PDWORD PEImage::GetExportEntry(LPCSTR name) const {
   PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory();
 
-  if (NULL == exports)
-    return NULL;
+  if (nullptr == exports)
+    return nullptr;
 
   WORD ordinal = 0;
   if (!GetProcOrdinal(name, &ordinal))
-    return NULL;
+    return nullptr;
 
-  PDWORD functions = reinterpret_cast<PDWORD>(
-                         RVAToAddr(exports->AddressOfFunctions));
+  PDWORD functions =
+      reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfFunctions));
 
   return functions + ordinal - exports->Base;
 }
 
 FARPROC PEImage::GetProcAddress(LPCSTR function_name) const {
   PDWORD export_entry = GetExportEntry(function_name);
-  if (NULL == export_entry)
-    return NULL;
+  if (nullptr == export_entry)
+    return nullptr;
 
   PBYTE function = reinterpret_cast<PBYTE>(RVAToAddr(*export_entry));
 
@@ -232,7 +234,7 @@
       GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT));
   DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_EXPORT);
   if (!exports || !size)
-    return NULL;
+    return nullptr;
 
   // Check for forwarded exports as a special case.
   if (exports <= function && exports + size > function)
@@ -241,13 +243,13 @@
   return reinterpret_cast<FARPROC>(function);
 }
 
-bool PEImage::GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const {
-  if (NULL == ordinal)
+bool PEImage::GetProcOrdinal(LPCSTR function_name, WORD* ordinal) const {
+  if (nullptr == ordinal)
     return false;
 
   PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory();
 
-  if (NULL == exports)
+  if (nullptr == exports)
     return false;
 
   if (IsOrdinal(function_name)) {
@@ -281,9 +283,8 @@
     if (cmp != 0)
       return false;
 
-
-    PWORD ordinals = reinterpret_cast<PWORD>(
-                         RVAToAddr(exports->AddressOfNameOrdinals));
+    PWORD ordinals =
+        reinterpret_cast<PWORD>(RVAToAddr(exports->AddressOfNameOrdinals));
 
     *ordinal = ordinals[lower - names] + static_cast<WORD>(exports->Base);
   }
@@ -315,24 +316,24 @@
   if (!directory || !size)
     return true;
 
-  PIMAGE_EXPORT_DIRECTORY exports = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
-                                        directory);
+  PIMAGE_EXPORT_DIRECTORY exports =
+      reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(directory);
   UINT ordinal_base = exports->Base;
   UINT num_funcs = exports->NumberOfFunctions;
   UINT num_names = exports->NumberOfNames;
-  PDWORD functions  = reinterpret_cast<PDWORD>(RVAToAddr(
-                          exports->AddressOfFunctions));
+  PDWORD functions =
+      reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfFunctions));
   PDWORD names = reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfNames));
-  PWORD ordinals = reinterpret_cast<PWORD>(RVAToAddr(
-                       exports->AddressOfNameOrdinals));
+  PWORD ordinals =
+      reinterpret_cast<PWORD>(RVAToAddr(exports->AddressOfNameOrdinals));
 
   for (UINT count = 0; count < num_funcs; count++) {
     PVOID func = RVAToAddr(functions[count]);
-    if (NULL == func)
+    if (nullptr == func)
       continue;
 
     // Check for a name.
-    LPCSTR name = NULL;
+    LPCSTR name = nullptr;
     UINT hint;
     for (hint = 0; hint < num_names; hint++) {
       if (ordinals[hint] == count) {
@@ -341,16 +342,16 @@
       }
     }
 
-    if (name == NULL)
+    if (name == nullptr)
       hint = 0;
 
     // Check for forwarded exports.
-    LPCSTR forward = NULL;
+    LPCSTR forward = nullptr;
     if (reinterpret_cast<char*>(func) >= reinterpret_cast<char*>(directory) &&
-        reinterpret_cast<char*>(func) <= reinterpret_cast<char*>(directory) +
-            size) {
+        reinterpret_cast<char*>(func) <=
+            reinterpret_cast<char*>(directory) + size) {
       forward = reinterpret_cast<LPCSTR>(func);
-      func = 0;
+      func = nullptr;
     }
 
     if (!callback(*this, ordinal_base + count, hint, name, func, forward,
@@ -373,8 +374,8 @@
   while (size >= sizeof(IMAGE_BASE_RELOCATION) && base->SizeOfBlock &&
          size >= base->SizeOfBlock) {
     PWORD reloc = reinterpret_cast<PWORD>(base + 1);
-    UINT num_relocs = (base->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
-        sizeof(WORD);
+    UINT num_relocs =
+        (base->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
 
     for (UINT i = 0; i < num_relocs; i++, reloc++) {
       WORD type = *reloc >> 12;
@@ -386,7 +387,7 @@
 
     size -= base->SizeOfBlock;
     base = reinterpret_cast<PIMAGE_BASE_RELOCATION>(
-               reinterpret_cast<char*>(base) + base->SizeOfBlock);
+        reinterpret_cast<char*>(base) + base->SizeOfBlock);
   }
 
   return true;
@@ -398,15 +399,15 @@
   DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_IMPORT);
   PIMAGE_IMPORT_DESCRIPTOR import = GetFirstImportChunk();
 
-  if (import == NULL || size < sizeof(IMAGE_IMPORT_DESCRIPTOR))
+  if (import == nullptr || size < sizeof(IMAGE_IMPORT_DESCRIPTOR))
     return true;
 
   for (; import->FirstThunk; import++) {
     LPCSTR module_name = reinterpret_cast<LPCSTR>(RVAToAddr(import->Name));
     PIMAGE_THUNK_DATA name_table = reinterpret_cast<PIMAGE_THUNK_DATA>(
-                                       RVAToAddr(import->OriginalFirstThunk));
-    PIMAGE_THUNK_DATA iat = reinterpret_cast<PIMAGE_THUNK_DATA>(
-                                RVAToAddr(import->FirstThunk));
+        RVAToAddr(import->OriginalFirstThunk));
+    PIMAGE_THUNK_DATA iat =
+        reinterpret_cast<PIMAGE_THUNK_DATA>(RVAToAddr(import->FirstThunk));
 
     if (target_module_name == nullptr ||
         (lstrcmpiA(module_name, target_module_name) == 0)) {
@@ -421,12 +422,13 @@
 bool PEImage::EnumOneImportChunk(EnumImportsFunction callback,
                                  LPCSTR module_name,
                                  PIMAGE_THUNK_DATA name_table,
-                                 PIMAGE_THUNK_DATA iat, PVOID cookie) const {
-  if (NULL == name_table)
+                                 PIMAGE_THUNK_DATA iat,
+                                 PVOID cookie) const {
+  if (nullptr == name_table)
     return false;
 
   for (; name_table && name_table->u1.Ordinal; name_table++, iat++) {
-    LPCSTR name = NULL;
+    LPCSTR name = nullptr;
     WORD ordinal = 0;
     WORD hint = 0;
 
@@ -450,15 +452,15 @@
 bool PEImage::EnumAllImports(EnumImportsFunction callback,
                              PVOID cookie,
                              LPCSTR target_module_name) const {
-  EnumAllImportsStorage temp = { callback, cookie };
+  EnumAllImportsStorage temp = {callback, cookie};
   return EnumImportChunks(ProcessImportChunk, &temp, target_module_name);
 }
 
 bool PEImage::EnumDelayImportChunks(EnumDelayImportChunksFunction callback,
                                     PVOID cookie,
                                     LPCSTR target_module_name) const {
-  PVOID directory = GetImageDirectoryEntryAddr(
-                        IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
+  PVOID directory =
+      GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
   DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
 
   if (!directory || !size)
@@ -526,7 +528,7 @@
                                       PIMAGE_THUNK_DATA iat,
                                       PVOID cookie) const {
   for (; name_table->u1.Ordinal; name_table++, iat++) {
-    LPCSTR name = NULL;
+    LPCSTR name = nullptr;
     WORD ordinal = 0;
     WORD hint = 0;
 
@@ -538,10 +540,10 @@
 
       if (rvas) {
         import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(
-                     RVAToAddr(name_table->u1.ForwarderString));
+            RVAToAddr(name_table->u1.ForwarderString));
       } else {
         import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(
-                     name_table->u1.ForwarderString);
+            name_table->u1.ForwarderString);
       }
 
       hint = import->Hint;
@@ -558,7 +560,7 @@
 bool PEImage::EnumAllDelayImports(EnumImportsFunction callback,
                                   PVOID cookie,
                                   LPCSTR target_module_name) const {
-  EnumAllImportsStorage temp = { callback, cookie };
+  EnumAllImportsStorage temp = {callback, cookie};
   return EnumDelayImportChunks(ProcessDelayImportChunk, &temp,
                                target_module_name);
 }
@@ -592,12 +594,12 @@
 
 bool PEImage::ImageAddrToOnDiskOffset(LPVOID address,
                                       DWORD* on_disk_offset) const {
-  if (NULL == address)
+  if (nullptr == address)
     return false;
 
   // Get the section that this address belongs to.
   PIMAGE_SECTION_HEADER section_header = GetImageSectionFromAddr(address);
-  if (NULL == section_header)
+  if (nullptr == section_header)
     return false;
 
   // Don't follow the virtual RVAToAddr, use the one on the base.
@@ -612,7 +614,7 @@
 
 PVOID PEImage::RVAToAddr(uintptr_t rva) const {
   if (rva == 0)
-    return NULL;
+    return nullptr;
 
   return reinterpret_cast<char*>(module_) + rva;
 }
@@ -636,13 +638,13 @@
 
 PVOID PEImageAsData::RVAToAddr(uintptr_t rva) const {
   if (rva == 0)
-    return NULL;
+    return nullptr;
 
   PVOID in_memory = PEImage::RVAToAddr(rva);
   DWORD disk_offset;
 
   if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset))
-    return NULL;
+    return nullptr;
 
   return PEImage::RVAToAddr(disk_offset);
 }
diff --git a/base/win/pe_image.h b/base/win/pe_image.h
index 8905b68..cc13805 100644
--- a/base/win/pe_image.h
+++ b/base/win/pe_image.h
@@ -11,10 +11,10 @@
 #ifndef BASE_WIN_PE_IMAGE_H_
 #define BASE_WIN_PE_IMAGE_H_
 
-#include <stdint.h>
-
 #include <windows.h>
 
+#include <stdint.h>
+
 #if defined(_WIN32_WINNT_WIN8)
 // The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h.
 #undef FACILITY_VISUALCPP
@@ -32,9 +32,10 @@
   // Callback to enumerate sections.
   // cookie is the value passed to the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumSectionsFunction)(const PEImage &image,
+  typedef bool (*EnumSectionsFunction)(const PEImage& image,
                                        PIMAGE_SECTION_HEADER header,
-                                       PVOID section_start, DWORD section_size,
+                                       PVOID section_start,
+                                       DWORD section_size,
                                        PVOID cookie);
 
   // Callback to enumerate exports.
@@ -42,31 +43,41 @@
   // contains the dll and symbol to forward this export to. cookie is the value
   // passed to the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumExportsFunction)(const PEImage &image, DWORD ordinal,
-                                      DWORD hint, LPCSTR name, PVOID function,
-                                      LPCSTR forward, PVOID cookie);
+  typedef bool (*EnumExportsFunction)(const PEImage& image,
+                                      DWORD ordinal,
+                                      DWORD hint,
+                                      LPCSTR name,
+                                      PVOID function,
+                                      LPCSTR forward,
+                                      PVOID cookie);
 
   // Callback to enumerate import blocks.
   // name_table and iat point to the imports name table and address table for
   // this block. cookie is the value passed to the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumImportChunksFunction)(const PEImage &image, LPCSTR module,
+  typedef bool (*EnumImportChunksFunction)(const PEImage& image,
+                                           LPCSTR module,
                                            PIMAGE_THUNK_DATA name_table,
-                                           PIMAGE_THUNK_DATA iat, PVOID cookie);
+                                           PIMAGE_THUNK_DATA iat,
+                                           PVOID cookie);
 
   // Callback to enumerate imports.
   // module is the dll that exports this symbol. cookie is the value passed to
   // the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumImportsFunction)(const PEImage &image, LPCSTR module,
-                                      DWORD ordinal, LPCSTR name, DWORD hint,
-                                      PIMAGE_THUNK_DATA iat, PVOID cookie);
+  typedef bool (*EnumImportsFunction)(const PEImage& image,
+                                      LPCSTR module,
+                                      DWORD ordinal,
+                                      LPCSTR name,
+                                      DWORD hint,
+                                      PIMAGE_THUNK_DATA iat,
+                                      PVOID cookie);
 
   // Callback to enumerate delayed import blocks.
   // module is the dll that exports this block of symbols. cookie is the value
   // passed to the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumDelayImportChunksFunction)(const PEImage &image,
+  typedef bool (*EnumDelayImportChunksFunction)(const PEImage& image,
                                                 PImgDelayDescr delay_descriptor,
                                                 LPCSTR module,
                                                 PIMAGE_THUNK_DATA name_table,
@@ -76,8 +87,10 @@
   // Callback to enumerate relocations.
   // cookie is the value passed to the enumerate method.
   // Returns true to continue the enumeration.
-  typedef bool (*EnumRelocsFunction)(const PEImage &image, WORD type,
-                                     PVOID address, PVOID cookie);
+  typedef bool (*EnumRelocsFunction)(const PEImage& image,
+                                     WORD type,
+                                     PVOID address,
+                                     PVOID cookie);
 
   explicit PEImage(HMODULE module) : module_(module) {}
   explicit PEImage(const void* module) {
@@ -172,7 +185,7 @@
 
   // Retrieves the ordinal for a given exported symbol.
   // Returns true if the symbol was found.
-  bool GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const;
+  bool GetProcOrdinal(LPCSTR function_name, WORD* ordinal) const;
 
   // Enumerates PE sections.
   // cookie is a generic cookie to pass to the callback.
@@ -205,8 +218,10 @@
   // Enumerates the imports from a single PE import block.
   // cookie is a generic cookie to pass to the callback.
   // Returns true on success.
-  bool EnumOneImportChunk(EnumImportsFunction callback, LPCSTR module_name,
-                          PIMAGE_THUNK_DATA name_table, PIMAGE_THUNK_DATA iat,
+  bool EnumOneImportChunk(EnumImportsFunction callback,
+                          LPCSTR module_name,
+                          PIMAGE_THUNK_DATA name_table,
+                          PIMAGE_THUNK_DATA iat,
                           PVOID cookie) const;
 
   // Enumerates PE delay imports.
@@ -257,7 +272,7 @@
 
   // Converts an address to an offset on disk.
   // Returns true on success.
-  bool ImageAddrToOnDiskOffset(LPVOID address, DWORD *on_disk_offset) const;
+  bool ImageAddrToOnDiskOffset(LPVOID address, DWORD* on_disk_offset) const;
 
  private:
   // Returns a pointer to a data directory, or NULL if |directory| is out of
@@ -290,12 +305,12 @@
 
 inline PIMAGE_IMPORT_DESCRIPTOR PEImage::GetFirstImportChunk() const {
   return reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
-             GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_IMPORT));
+      GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_IMPORT));
 }
 
 inline PIMAGE_EXPORT_DIRECTORY PEImage::GetExportDirectory() const {
   return reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
-             GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT));
+      GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT));
 }
 
 }  // namespace win
diff --git a/base/win/pe_image_test.cc b/base/win/pe_image_test.cc
index 3ce402f..a0b9ed16 100644
--- a/base/win/pe_image_test.cc
+++ b/base/win/pe_image_test.cc
@@ -27,7 +27,7 @@
     CoTaskMemFree(path);
 
   // Call into kernel32.dll.
-  HANDLE h = CreateEvent(NULL, FALSE, FALSE, NULL);
+  HANDLE h = CreateEvent(nullptr, FALSE, FALSE, nullptr);
   CloseHandle(h);
 }
 
diff --git a/base/win/pe_image_unittest.cc b/base/win/pe_image_unittest.cc
index 45279c3..408263a 100644
--- a/base/win/pe_image_unittest.cc
+++ b/base/win/pe_image_unittest.cc
@@ -246,8 +246,8 @@
 
   FARPROC address1 = pe.GetProcAddress("RegEnumKeyExW");
   FARPROC address2 = pe.GetProcAddress(reinterpret_cast<char*>(ordinal));
-  EXPECT_TRUE(address1 != NULL);
-  EXPECT_TRUE(address2 != NULL);
+  EXPECT_TRUE(address1 != nullptr);
+  EXPECT_TRUE(address2 != nullptr);
   EXPECT_TRUE(address1 == address2);
 }
 
diff --git a/base/win/process_startup_helper.cc b/base/win/process_startup_helper.cc
index 6861b38b..9f51adfa 100644
--- a/base/win/process_startup_helper.cc
+++ b/base/win/process_startup_helper.cc
@@ -18,8 +18,10 @@
 // call stacks from /OPT:ICF function folding. Printing a unique message or
 // returning a unique value will do this. Note that for best results they need
 // to be unique from *all* functions in Chrome.
-void InvalidParameter(const wchar_t* expression, const wchar_t* function,
-                      const wchar_t* file, unsigned int line,
+void InvalidParameter(const wchar_t* expression,
+                      const wchar_t* function,
+                      const wchar_t* file,
+                      unsigned int line,
                       uintptr_t reserved) {
   __debugbreak();
   // Use a different exit code from PureCall to avoid COMDAT folding.
diff --git a/base/win/registry.cc b/base/win/registry.cc
index 2c4a497..93ef2dd 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -66,19 +66,17 @@
   DCHECK(callback_.is_null());
 
   if (!watch_event_.IsValid())
-    watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
+    watch_event_.Set(CreateEvent(nullptr, TRUE, FALSE, nullptr));
 
   if (!watch_event_.IsValid())
     return false;
 
-  DWORD filter = REG_NOTIFY_CHANGE_NAME |
-                 REG_NOTIFY_CHANGE_ATTRIBUTES |
-                 REG_NOTIFY_CHANGE_LAST_SET |
-                 REG_NOTIFY_CHANGE_SECURITY;
+  DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES |
+                 REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY;
 
   // Watch the registry key for a change of value.
-  LONG result = RegNotifyChangeKeyValue(key, TRUE, filter, watch_event_.Get(),
-                                        TRUE);
+  LONG result =
+      RegNotifyChangeKeyValue(key, TRUE, filter, watch_event_.Get(), TRUE);
   if (result != ERROR_SUCCESS) {
     watch_event_.Close();
     return false;
@@ -90,14 +88,12 @@
 
 // RegKey ----------------------------------------------------------------------
 
-RegKey::RegKey() : key_(NULL), wow64access_(0) {
-}
+RegKey::RegKey() : key_(nullptr), wow64access_(0) {}
 
-RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
-}
+RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {}
 
 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
-    : key_(NULL), wow64access_(0) {
+    : key_(nullptr), wow64access_(0) {
   if (rootkey) {
     if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
       Create(rootkey, subkey, access);
@@ -123,10 +119,10 @@
                                    DWORD* disposition,
                                    REGSAM access) {
   DCHECK(rootkey && subkey && access && disposition);
-  HKEY subhkey = NULL;
+  HKEY subhkey = nullptr;
   LONG result =
-      RegCreateKeyEx(rootkey, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, access,
-                     NULL, &subhkey, disposition);
+      RegCreateKeyEx(rootkey, subkey, 0, nullptr, REG_OPTION_NON_VOLATILE,
+                     access, nullptr, &subhkey, disposition);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subhkey;
@@ -147,9 +143,9 @@
     NOTREACHED();
     return ERROR_INVALID_PARAMETER;
   }
-  HKEY subkey = NULL;
-  LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
-                               access, NULL, &subkey, NULL);
+  HKEY subkey = nullptr;
+  LONG result = RegCreateKeyEx(key_, name, 0, nullptr, REG_OPTION_NON_VOLATILE,
+                               access, nullptr, &subkey, nullptr);
   if (result == ERROR_SUCCESS) {
     Close();
     key_ = subkey;
@@ -161,7 +157,7 @@
 
 LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
   DCHECK(rootkey && subkey && access);
-  HKEY subhkey = NULL;
+  HKEY subhkey = nullptr;
 
   LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &subhkey);
   if (result == ERROR_SUCCESS) {
@@ -184,7 +180,7 @@
     NOTREACHED();
     return ERROR_INVALID_PARAMETER;
   }
-  HKEY subkey = NULL;
+  HKEY subkey = nullptr;
   LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey);
 
   // We have to close the current opened key before replacing it with the new
@@ -200,7 +196,7 @@
 void RegKey::Close() {
   if (key_) {
     ::RegCloseKey(key_);
-    key_ = NULL;
+    key_ = nullptr;
     wow64access_ = 0;
   }
 }
@@ -216,25 +212,28 @@
 HKEY RegKey::Take() {
   DCHECK_EQ(wow64access_, 0u);
   HKEY key = key_;
-  key_ = NULL;
+  key_ = nullptr;
   return key;
 }
 
 bool RegKey::HasValue(const wchar_t* name) const {
-  return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
+  return RegQueryValueEx(key_, name, nullptr, nullptr, nullptr, nullptr) ==
+         ERROR_SUCCESS;
 }
 
 DWORD RegKey::GetValueCount() const {
   DWORD count = 0;
-  LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
-                                NULL, NULL, NULL, NULL);
+  LONG result =
+      RegQueryInfoKey(key_, nullptr, nullptr, nullptr, nullptr, nullptr,
+                      nullptr, &count, nullptr, nullptr, nullptr, nullptr);
   return (result == ERROR_SUCCESS) ? count : 0;
 }
 
 LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
   wchar_t buf[256];
   DWORD bufsize = size(buf);
-  LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL);
+  LONG r = ::RegEnumValue(key_, index, buf, &bufsize, nullptr, nullptr, nullptr,
+                          nullptr);
   if (r == ERROR_SUCCESS)
     name->assign(buf, bufsize);
 
@@ -244,7 +243,7 @@
 LONG RegKey::DeleteKey(const wchar_t* name) {
   DCHECK(key_);
   DCHECK(name);
-  HKEY subkey = NULL;
+  HKEY subkey = nullptr;
 
   // Verify the key exists before attempting delete to replicate previous
   // behavior.
@@ -261,7 +260,7 @@
   DCHECK(key_);
   DCHECK(name);
 
-  HKEY target_key = NULL;
+  HKEY target_key = nullptr;
   LONG result =
       RegOpenKeyEx(key_, name, 0, KEY_READ | wow64access_, &target_key);
 
@@ -269,8 +268,9 @@
     return result;
 
   DWORD count = 0;
-  result = RegQueryInfoKey(target_key, NULL, 0, NULL, NULL, NULL, NULL, &count,
-                           NULL, NULL, NULL, NULL);
+  result =
+      RegQueryInfoKey(target_key, nullptr, nullptr, nullptr, nullptr, nullptr,
+                      nullptr, &count, nullptr, nullptr, nullptr, nullptr);
 
   RegCloseKey(target_key);
 
@@ -356,7 +356,7 @@
                        void* data,
                        DWORD* dsize,
                        DWORD* dtype) const {
-  LONG result = RegQueryValueEx(key_, name, 0, dtype,
+  LONG result = RegQueryValueEx(key_, name, nullptr, dtype,
                                 reinterpret_cast<LPBYTE>(data), dsize);
   return result;
 }
@@ -367,7 +367,7 @@
 
   DWORD type = REG_MULTI_SZ;
   DWORD size = 0;
-  LONG result = ReadValue(name, NULL, &size, &type);
+  LONG result = ReadValue(name, nullptr, &size, &type);
   if (result != ERROR_SUCCESS || size == 0)
     return result;
 
@@ -375,7 +375,7 @@
     return ERROR_CANTREAD;
 
   std::vector<wchar_t> buffer(size / sizeof(wchar_t));
-  result = ReadValue(name, buffer.data(), &size, NULL);
+  result = ReadValue(name, buffer.data(), &size, nullptr);
   if (result != ERROR_SUCCESS || size == 0)
     return result;
 
@@ -393,8 +393,8 @@
 }
 
 LONG RegKey::WriteValue(const wchar_t* name, DWORD in_value) {
-  return WriteValue(
-      name, &in_value, static_cast<DWORD>(sizeof(in_value)), REG_DWORD);
+  return WriteValue(name, &in_value, static_cast<DWORD>(sizeof(in_value)),
+                    REG_DWORD);
 }
 
 LONG RegKey::WriteValue(const wchar_t* name, const wchar_t* in_value) {
@@ -434,7 +434,7 @@
   if (result == ERROR_SUCCESS)
     return result;
 
-  HKEY target_key = NULL;
+  HKEY target_key = nullptr;
   result = RegOpenKeyEx(root_key, name, 0, KEY_ENUMERATE_SUB_KEYS | access,
                         &target_key);
 
@@ -458,7 +458,7 @@
     DWORD key_size = kMaxKeyNameLength;
     result =
         RegEnumKeyEx(target_key, 0, WriteInto(&key_name, kMaxKeyNameLength),
-                     &key_size, NULL, NULL, NULL, NULL);
+                     &key_size, nullptr, nullptr, nullptr, nullptr);
 
     if (result != ERROR_SUCCESS)
       break;
@@ -501,15 +501,16 @@
   LONG result =
       RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
-    key_ = NULL;
+    key_ = nullptr;
   } else {
     DWORD count = 0;
-    result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
-                               NULL, NULL, NULL, NULL);
+    result =
+        ::RegQueryInfoKey(key_, nullptr, nullptr, nullptr, nullptr, nullptr,
+                          nullptr, &count, nullptr, nullptr, nullptr, nullptr);
 
     if (result != ERROR_SUCCESS) {
       ::RegCloseKey(key_);
-      key_ = NULL;
+      key_ = nullptr;
     } else {
       index_ = count - 1;
     }
@@ -525,8 +526,9 @@
 
 DWORD RegistryValueIterator::ValueCount() const {
   DWORD count = 0;
-  LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL,
-                                  &count, NULL, NULL, NULL, NULL);
+  LONG result =
+      ::RegQueryInfoKey(key_, nullptr, nullptr, nullptr, nullptr, nullptr,
+                        nullptr, &count, nullptr, nullptr, nullptr, nullptr);
   if (result != ERROR_SUCCESS)
     return 0;
 
@@ -534,7 +536,7 @@
 }
 
 bool RegistryValueIterator::Valid() const {
-  return key_ != NULL && index_ >= 0;
+  return key_ != nullptr && index_ >= 0;
 }
 
 void RegistryValueIterator::operator++() {
@@ -549,7 +551,7 @@
     // |value_size_| is in bytes. Reserve the last character for a NUL.
     value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
     LONG result = ::RegEnumValue(
-        key_, index_, WriteInto(&name_, name_size), &name_size, NULL, &type_,
+        key_, index_, WriteInto(&name_, name_size), &name_size, nullptr, &type_,
         reinterpret_cast<BYTE*>(value_.data()), &value_size_);
 
     if (result == ERROR_MORE_DATA) {
@@ -565,8 +567,8 @@
       value_size_ = static_cast<DWORD>((value_.size() - 1) * sizeof(wchar_t));
       name_size = name_size == capacity ? MAX_REGISTRY_NAME_SIZE : capacity;
       result = ::RegEnumValue(
-          key_, index_, WriteInto(&name_, name_size), &name_size, NULL, &type_,
-          reinterpret_cast<BYTE*>(value_.data()), &value_size_);
+          key_, index_, WriteInto(&name_, name_size), &name_size, nullptr,
+          &type_, reinterpret_cast<BYTE*>(value_.data()), &value_size_);
     }
 
     if (result == ERROR_SUCCESS) {
@@ -602,8 +604,9 @@
 
 DWORD RegistryKeyIterator::SubkeyCount() const {
   DWORD count = 0;
-  LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
-                                  NULL, NULL, NULL, NULL, NULL);
+  LONG result =
+      ::RegQueryInfoKey(key_, nullptr, nullptr, nullptr, &count, nullptr,
+                        nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
   if (result != ERROR_SUCCESS)
     return 0;
 
@@ -611,7 +614,7 @@
 }
 
 bool RegistryKeyIterator::Valid() const {
-  return key_ != NULL && index_ >= 0;
+  return key_ != nullptr && index_ >= 0;
 }
 
 void RegistryKeyIterator::operator++() {
@@ -623,8 +626,8 @@
   if (Valid()) {
     DWORD ncount = static_cast<DWORD>(size(name_));
     FILETIME written;
-    LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, NULL,
-                            &written);
+    LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, nullptr, nullptr,
+                            nullptr, &written);
     if (ERROR_SUCCESS == r)
       return true;
   }
@@ -640,15 +643,16 @@
   LONG result =
       RegOpenKeyEx(root_key, folder_key, 0, KEY_READ | wow64access, &key_);
   if (result != ERROR_SUCCESS) {
-    key_ = NULL;
+    key_ = nullptr;
   } else {
     DWORD count = 0;
-    result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL);
+    result =
+        ::RegQueryInfoKey(key_, nullptr, nullptr, nullptr, &count, nullptr,
+                          nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
 
     if (result != ERROR_SUCCESS) {
       ::RegCloseKey(key_);
-      key_ = NULL;
+      key_ = nullptr;
     } else {
       index_ = count - 1;
     }
diff --git a/base/win/registry.h b/base/win/registry.h
index f772821..b845737e 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -77,7 +77,7 @@
   LONG GetValueNameAt(int index, std::wstring* name) const;
 
   // True while the key is valid.
-  bool Valid() const { return key_ != NULL; }
+  bool Valid() const { return key_ != nullptr; }
 
   // Kills a key and everything that lives below it; please be careful when
   // using it.
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc
index 50be1d32..88a39d09 100644
--- a/base/win/registry_unittest.cc
+++ b/base/win/registry_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/win/registry.h"
 
 #include <windows.h>
+
 #include <stdint.h>
 
 #include <cstring>
@@ -77,8 +78,8 @@
 
   std::wstring foo_key(kRootKey);
   foo_key += L"\\Foo";
-  ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
-                                      KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 
   {
     ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
@@ -137,8 +138,8 @@
   RegKey key;
   std::wstring foo_key(kRootKey);
   foo_key += L"\\Foo";
-  ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
-                                      KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                                     KEY_READ | KEY_SET_VALUE));
   ASSERT_TRUE(key.Valid());
@@ -162,8 +163,8 @@
   RegKey key;
   std::wstring foo_key(kRootKey);
   foo_key += L"\\Foo";
-  ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
-                                      KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                                     KEY_READ | KEY_SET_VALUE));
   ASSERT_TRUE(key.Valid());
@@ -258,14 +259,12 @@
 
   // Test redirected key access from non-redirected.
   ASSERT_EQ(ERROR_SUCCESS,
-            key.Create(HKEY_LOCAL_MACHINE,
-                       foo_software_key_.c_str(),
+            key.Create(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(),
                        KEY_WRITE | kRedirectedViewMask));
   ASSERT_NE(ERROR_SUCCESS,
             key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(), KEY_READ));
   ASSERT_NE(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE,
-                     foo_software_key_.c_str(),
+            key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(),
                      KEY_READ | kNativeViewMask));
 
   // Open the non-redirected view of the parent and try to delete the test key.
@@ -303,14 +302,12 @@
 
   // Test non-redirected key access from redirected.
   ASSERT_EQ(ERROR_SUCCESS,
-            key.Create(HKEY_LOCAL_MACHINE,
-                       foo_software_key_.c_str(),
+            key.Create(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(),
                        KEY_WRITE | kNativeViewMask));
   ASSERT_EQ(ERROR_SUCCESS,
             key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(), KEY_READ));
   ASSERT_NE(ERROR_SUCCESS,
-            key.Open(HKEY_LOCAL_MACHINE,
-                     foo_software_key_.c_str(),
+            key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(),
                      KEY_READ | kRedirectedViewMask));
 
   // Open the redirected view of the parent and try to delete the test key
@@ -326,10 +323,8 @@
 
 TEST_F(RegistryTest, OpenSubKey) {
   RegKey key;
-  ASSERT_EQ(ERROR_SUCCESS,
-            key.Open(HKEY_CURRENT_USER,
-                     kRootKey,
-                     KEY_READ | KEY_CREATE_SUB_KEY));
+  ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey,
+                                    KEY_READ | KEY_CREATE_SUB_KEY));
 
   ASSERT_NE(ERROR_SUCCESS, key.OpenKey(L"foo", KEY_READ));
   ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"foo", KEY_READ));
@@ -347,19 +342,19 @@
 
 class TestChangeDelegate {
  public:
-   TestChangeDelegate() : called_(false) {}
-   ~TestChangeDelegate() {}
+  TestChangeDelegate() : called_(false) {}
+  ~TestChangeDelegate() {}
 
-   void OnKeyChanged() {
-     RunLoop::QuitCurrentWhenIdleDeprecated();
-     called_ = true;
-   }
+  void OnKeyChanged() {
+    RunLoop::QuitCurrentWhenIdleDeprecated();
+    called_ = true;
+  }
 
-   bool WasCalled() {
-     bool was_called = called_;
-     called_ = false;
-     return was_called;
-   }
+  bool WasCalled() {
+    bool was_called = called_;
+    called_ = false;
+    return was_called;
+  }
 
  private:
   bool called_;
@@ -372,8 +367,8 @@
 
   std::wstring foo_key(kRootKey);
   foo_key += L"\\Foo";
-  ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
-                                      KEY_READ));
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));
 
   ASSERT_TRUE(key.StartWatching(
       BindRepeating(&TestChangeDelegate::OnKeyChanged, Unretained(&delegate))));
@@ -382,7 +377,7 @@
   // Make some change.
   RegKey key2;
   ASSERT_EQ(ERROR_SUCCESS, key2.Open(HKEY_CURRENT_USER, foo_key.c_str(),
-                                      KEY_READ | KEY_SET_VALUE));
+                                     KEY_READ | KEY_SET_VALUE));
   ASSERT_TRUE(key2.Valid());
   EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(L"name", L"data"));
 
diff --git a/base/win/resource_util.cc b/base/win/resource_util.cc
index 0c10078..c538d6e 100644
--- a/base/win/resource_util.cc
+++ b/base/win/resource_util.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/logging.h"
 #include "base/win/resource_util.h"
+#include "base/logging.h"
 
 namespace base {
 namespace win {
@@ -21,9 +21,9 @@
     return false;
   }
 
-  HRSRC hres_info = FindResource(module, MAKEINTRESOURCE(resource_id),
-                                 resource_type);
-  if (NULL == hres_info)
+  HRSRC hres_info =
+      FindResource(module, MAKEINTRESOURCE(resource_id), resource_type);
+  if (nullptr == hres_info)
     return false;
 
   DWORD data_size = SizeofResource(module, hres_info);
diff --git a/base/win/resource_util.h b/base/win/resource_util.h
index 00687b9..ffc4ce04 100644
--- a/base/win/resource_util.h
+++ b/base/win/resource_util.h
@@ -9,6 +9,7 @@
 #define BASE_WIN_RESOURCE_UTIL_H_
 
 #include <windows.h>
+
 #include <stddef.h>
 
 #include "base/base_export.h"
diff --git a/base/win/scoped_bstr.h b/base/win/scoped_bstr.h
index a3d3684d..31ce210 100644
--- a/base/win/scoped_bstr.h
+++ b/base/win/scoped_bstr.h
@@ -6,6 +6,7 @@
 #define BASE_WIN_SCOPED_BSTR_H_
 
 #include <windows.h>
+
 #include <oleauto.h>
 #include <stddef.h>
 
@@ -77,9 +78,7 @@
   // Returns the number of bytes allocated for the BSTR.
   size_t ByteLength() const;
 
-  operator BSTR() const {
-    return bstr_;
-  }
+  operator BSTR() const { return bstr_; }
 
   // Forbid comparison of ScopedBstr types.  You should never have the same
   // BSTR owned by two different scoped_ptrs.
diff --git a/base/win/scoped_bstr_unittest.cc b/base/win/scoped_bstr_unittest.cc
index 66cb0bd..e551808c 100644
--- a/base/win/scoped_bstr_unittest.cc
+++ b/base/win/scoped_bstr_unittest.cc
@@ -21,15 +21,15 @@
 
 void DumbBstrTests() {
   ScopedBstr b;
-  EXPECT_TRUE(b == NULL);
+  EXPECT_TRUE(b == nullptr);
   EXPECT_EQ(0u, b.Length());
   EXPECT_EQ(0u, b.ByteLength());
-  b.Reset(NULL);
-  EXPECT_TRUE(b == NULL);
-  EXPECT_TRUE(b.Release() == NULL);
+  b.Reset(nullptr);
+  EXPECT_TRUE(b == nullptr);
+  EXPECT_TRUE(b.Release() == nullptr);
   ScopedBstr b2;
   b.Swap(b2);
-  EXPECT_TRUE(b2 == NULL);
+  EXPECT_TRUE(b2 == nullptr);
 }
 
 void GiveMeABstr(BSTR* ret) {
@@ -47,15 +47,15 @@
   EXPECT_EQ(0u, b1.Length());
   EXPECT_STREQ(b2, kTestString1);
   BSTR tmp = b2.Release();
-  EXPECT_TRUE(tmp != NULL);
+  EXPECT_TRUE(tmp != nullptr);
   EXPECT_STREQ(tmp, kTestString1);
-  EXPECT_TRUE(b2 == NULL);
+  EXPECT_TRUE(b2 == nullptr);
   SysFreeString(tmp);
 
   GiveMeABstr(b2.Receive());
-  EXPECT_TRUE(b2 != NULL);
+  EXPECT_TRUE(b2 != nullptr);
   b2.Reset();
-  EXPECT_TRUE(b2.AllocateBytes(100) != NULL);
+  EXPECT_TRUE(b2.AllocateBytes(100) != nullptr);
   EXPECT_EQ(100u, b2.ByteLength());
   EXPECT_EQ(100 / sizeof(kTestString1[0]), b2.Length());
   lstrcpy(static_cast<BSTR>(b2), kTestString1);
@@ -64,7 +64,7 @@
   b2.SetByteLen(lstrlen(b2) * sizeof(kTestString2[0]));
   EXPECT_EQ(b2.Length(), static_cast<size_t>(lstrlen(b2)));
 
-  EXPECT_TRUE(b1.Allocate(kTestString2) != NULL);
+  EXPECT_TRUE(b1.Allocate(kTestString2) != nullptr);
   EXPECT_EQ(test2_len, b1.Length());
   b1.SetByteLen((test2_len - 1) * sizeof(kTestString2[0]));
   EXPECT_EQ(test2_len - 1, b1.Length());
diff --git a/base/win/scoped_co_mem.h b/base/win/scoped_co_mem.h
index a3737dd..8c4eac2e 100644
--- a/base/win/scoped_co_mem.h
+++ b/base/win/scoped_co_mem.h
@@ -19,22 +19,18 @@
 //   SHGetSomeInfo(&file_item, ...);
 //   ...
 //   return;  <-- memory released
-template<typename T>
+template <typename T>
 class ScopedCoMem {
  public:
-  ScopedCoMem() : mem_ptr_(NULL) {}
-  ~ScopedCoMem() {
-    Reset(NULL);
-  }
+  ScopedCoMem() : mem_ptr_(nullptr) {}
+  ~ScopedCoMem() { Reset(nullptr); }
 
-  T** operator&() {  // NOLINT
-    DCHECK(mem_ptr_ == NULL);  // To catch memory leaks.
+  T** operator&() {               // NOLINT
+    DCHECK(mem_ptr_ == nullptr);  // To catch memory leaks.
     return &mem_ptr_;
   }
 
-  operator T*() {
-    return mem_ptr_;
-  }
+  operator T*() { return mem_ptr_; }
 
   T* operator->() {
     DCHECK(mem_ptr_ != NULL);
@@ -52,9 +48,7 @@
     mem_ptr_ = ptr;
   }
 
-  T* get() const {
-    return mem_ptr_;
-  }
+  T* get() const { return mem_ptr_; }
 
  private:
   T* mem_ptr_;
diff --git a/base/win/scoped_com_initializer.cc b/base/win/scoped_com_initializer.cc
index 6fbb903..a604403 100644
--- a/base/win/scoped_com_initializer.cc
+++ b/base/win/scoped_com_initializer.cc
@@ -31,7 +31,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // COINIT_DISABLE_OLE1DDE is always added based on:
   // https://docs.microsoft.com/en-us/windows/desktop/learnwin32/initializing-the-com-library
-  hr_ = CoInitializeEx(NULL, init | COINIT_DISABLE_OLE1DDE);
+  hr_ = CoInitializeEx(nullptr, init | COINIT_DISABLE_OLE1DDE);
   DCHECK_NE(RPC_E_CHANGED_MODE, hr_) << "Invalid COM thread model change";
 }
 
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index 4f54df5..de68545 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -17,14 +17,18 @@
 }
 
 // Static.
-void VerifierTraits::StartTracking(HANDLE handle, const void* owner,
-                                   const void* pc1, const void* pc2) {
+void VerifierTraits::StartTracking(HANDLE handle,
+                                   const void* owner,
+                                   const void* pc1,
+                                   const void* pc2) {
   return ScopedHandleVerifier::Get()->StartTracking(handle, owner, pc1, pc2);
 }
 
 // Static.
-void VerifierTraits::StopTracking(HANDLE handle, const void* owner,
-                                  const void* pc1, const void* pc2) {
+void VerifierTraits::StopTracking(HANDLE handle,
+                                  const void* owner,
+                                  const void* pc1,
+                                  const void* pc2) {
   return ScopedHandleVerifier::Get()->StopTracking(handle, owner, pc1, pc2);
 }
 
diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h
index 4f9cada..8720889 100644
--- a/base/win/scoped_handle.h
+++ b/base/win/scoped_handle.h
@@ -19,8 +19,8 @@
 #include <intrin.h>
 #define BASE_WIN_GET_CALLER _ReturnAddress()
 #elif defined(COMPILER_GCC)
-#define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\
-    __builtin_return_address(0))
+#define BASE_WIN_GET_CALLER \
+  __builtin_extract_return_addr(\ __builtin_return_address(0))
 #endif
 
 namespace base {
@@ -51,13 +51,9 @@
     Set(other.Take());
   }
 
-  ~GenericScopedHandle() {
-    Close();
-  }
+  ~GenericScopedHandle() { Close(); }
 
-  bool IsValid() const {
-    return Traits::IsHandleValid(handle_);
-  }
+  bool IsValid() const { return Traits::IsHandleValid(handle_); }
 
   GenericScopedHandle& operator=(GenericScopedHandle&& other) {
     DCHECK_NE(this, &other);
@@ -80,9 +76,7 @@
     }
   }
 
-  Handle Get() const {
-    return handle_;
-  }
+  Handle Get() const { return handle_; }
 
   // Transfers ownership away from this object.
   Handle Take() WARN_UNUSED_RESULT {
@@ -126,13 +120,11 @@
 
   // Returns true if the handle value is valid.
   static bool IsHandleValid(HANDLE handle) {
-    return handle != NULL && handle != INVALID_HANDLE_VALUE;
+    return handle != nullptr && handle != INVALID_HANDLE_VALUE;
   }
 
   // Returns NULL handle value.
-  static HANDLE NullHandle() {
-    return NULL;
-  }
+  static HANDLE NullHandle() { return nullptr; }
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits);
@@ -143,10 +135,14 @@
  public:
   typedef HANDLE Handle;
 
-  static void StartTracking(HANDLE handle, const void* owner,
-                            const void* pc1, const void* pc2) {}
-  static void StopTracking(HANDLE handle, const void* owner,
-                           const void* pc1, const void* pc2) {}
+  static void StartTracking(HANDLE handle,
+                            const void* owner,
+                            const void* pc1,
+                            const void* pc2) {}
+  static void StopTracking(HANDLE handle,
+                           const void* owner,
+                           const void* pc1,
+                           const void* pc2) {}
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits);
@@ -157,10 +153,14 @@
  public:
   typedef HANDLE Handle;
 
-  static void StartTracking(HANDLE handle, const void* owner,
-                            const void* pc1, const void* pc2);
-  static void StopTracking(HANDLE handle, const void* owner,
-                           const void* pc1, const void* pc2);
+  static void StartTracking(HANDLE handle,
+                            const void* owner,
+                            const void* pc1,
+                            const void* pc2);
+  static void StopTracking(HANDLE handle,
+                           const void* owner,
+                           const void* pc1,
+                           const void* pc2);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits);
diff --git a/base/win/scoped_handle_test_dll.cc b/base/win/scoped_handle_test_dll.cc
index 75484aa4..a2ddadc73 100644
--- a/base/win/scoped_handle_test_dll.cc
+++ b/base/win/scoped_handle_test_dll.cc
@@ -52,7 +52,7 @@
   if (!ready_event)
     return false;
 
-  ThreadParams thread_params = { ready_event, start_event };
+  ThreadParams thread_params = {ready_event, start_event};
 
   for (size_t i = 0; i < kNumThreads; i++) {
     HANDLE thread_handle =
@@ -100,7 +100,7 @@
   if (!my_module)
     return false;
 
-  HMODULE main_module = ::GetModuleHandle(NULL);
+  HMODULE main_module = ::GetModuleHandle(nullptr);
 
 #if BUILDFLAG(SINGLE_MODULE_MODE_HANDLE_VERIFIER)
   // In a component build ActiveVerifier will always be created inside base.dll
@@ -122,6 +122,6 @@
   return InternalRunThreadTest() && InternalRunLocationTest();
 }
 
-}  // testing
-}  // win
-}  // base
+}  // namespace testing
+}  // namespace win
+}  // namespace base
diff --git a/base/win/scoped_handle_unittest.cc b/base/win/scoped_handle_unittest.cc
index fc09bb0..d9ffbc86 100644
--- a/base/win/scoped_handle_unittest.cc
+++ b/base/win/scoped_handle_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <windows.h>
+
 #include <winternl.h>
 
 #include "base/base_switches.h"
@@ -56,11 +57,14 @@
       GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtClose"));
   ASSERT_NE(nullptr, ntclose);
 
-  ASSERT_DEATH({
-    base::win::ScopedHandle handle_holder(handle);
-    ntclose(handle);
-    // Destructing a ScopedHandle with an illegally closed handle should fail.
-  }, "");
+  ASSERT_DEATH(
+      {
+        base::win::ScopedHandle handle_holder(handle);
+        ntclose(handle);
+        // Destructing a ScopedHandle with an illegally closed handle should
+        // fail.
+      },
+      "");
 }
 
 TEST(ScopedHandleTest, ActiveVerifierDoubleTracking) {
@@ -69,9 +73,7 @@
 
   base::win::ScopedHandle handle_holder(handle);
 
-  ASSERT_DEATH({
-    base::win::ScopedHandle handle_holder2(handle);
-  }, "");
+  ASSERT_DEATH({ base::win::ScopedHandle handle_holder2(handle); }, "");
 }
 
 TEST(ScopedHandleTest, ActiveVerifierWrongOwner) {
@@ -79,10 +81,12 @@
   ASSERT_NE(HANDLE(nullptr), handle);
 
   base::win::ScopedHandle handle_holder(handle);
-  ASSERT_DEATH({
-    base::win::ScopedHandle handle_holder2;
-    handle_holder2.handle_ = handle;
-  }, "");
+  ASSERT_DEATH(
+      {
+        base::win::ScopedHandle handle_holder2;
+        handle_holder2.handle_ = handle;
+      },
+      "");
   ASSERT_TRUE(handle_holder.IsValid());
   handle_holder.Close();
 }
@@ -91,10 +95,12 @@
   HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
   ASSERT_NE(HANDLE(nullptr), handle);
 
-  ASSERT_DEATH({
-    base::win::ScopedHandle handle_holder;
-    handle_holder.handle_ = handle;
-  }, "");
+  ASSERT_DEATH(
+      {
+        base::win::ScopedHandle handle_holder;
+        handle_holder.handle_ = handle;
+      },
+      "");
 
   ASSERT_TRUE(::CloseHandle(handle));
 }
diff --git a/base/win/scoped_handle_verifier.cc b/base/win/scoped_handle_verifier.cc
index 191a240..916d413e 100644
--- a/base/win/scoped_handle_verifier.cc
+++ b/base/win/scoped_handle_verifier.cc
@@ -4,9 +4,10 @@
 
 #include "base/win/scoped_handle_verifier.h"
 
-#include <stddef.h>
 #include <windows.h>
 
+#include <stddef.h>
+
 #include <unordered_map>
 
 #include "base/debug/alias.h"
@@ -25,7 +26,7 @@
 
 namespace {
 
-base::win::internal::ScopedHandleVerifier* g_active_verifier = NULL;
+base::win::internal::ScopedHandleVerifier* g_active_verifier = nullptr;
 typedef void* (*GetHandleVerifierFn)();
 typedef std::unordered_map<HANDLE,
                            base::win::internal::ScopedHandleVerifierInfo,
diff --git a/base/win/scoped_hdc.h b/base/win/scoped_hdc.h
index 890e34a..4532d91 100644
--- a/base/win/scoped_hdc.h
+++ b/base/win/scoped_hdc.h
@@ -19,9 +19,7 @@
 // GetDC.
 class ScopedGetDC {
  public:
-  explicit ScopedGetDC(HWND hwnd)
-      : hwnd_(hwnd),
-        hdc_(GetDC(hwnd)) {
+  explicit ScopedGetDC(HWND hwnd) : hwnd_(hwnd), hdc_(GetDC(hwnd)) {
     if (hwnd_) {
       DCHECK(IsWindow(hwnd_));
       DCHECK(hdc_);
@@ -54,17 +52,11 @@
  public:
   typedef HDC Handle;
 
-  static bool CloseHandle(HDC handle) {
-    return ::DeleteDC(handle) != FALSE;
-  }
+  static bool CloseHandle(HDC handle) { return ::DeleteDC(handle) != FALSE; }
 
-  static bool IsHandleValid(HDC handle) {
-    return handle != NULL;
-  }
+  static bool IsHandleValid(HDC handle) { return handle != NULL; }
 
-  static HDC NullHandle() {
-    return NULL;
-  }
+  static HDC NullHandle() { return NULL; }
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(CreateDCTraits);
diff --git a/base/win/scoped_hglobal.h b/base/win/scoped_hglobal.h
index abe9a5a..7dc568c 100644
--- a/base/win/scoped_hglobal.h
+++ b/base/win/scoped_hglobal.h
@@ -6,6 +6,7 @@
 #define BASE_WIN_SCOPED_HGLOBAL_H_
 
 #include <windows.h>
+
 #include <stddef.h>
 
 #include "base/macros.h"
@@ -14,15 +15,13 @@
 namespace win {
 
 // Like ScopedHandle except for HGLOBAL.
-template<class T>
+template <class T>
 class ScopedHGlobal {
  public:
   explicit ScopedHGlobal(HGLOBAL glob) : glob_(glob) {
     data_ = static_cast<T>(GlobalLock(glob_));
   }
-  ~ScopedHGlobal() {
-    GlobalUnlock(glob_);
-  }
+  ~ScopedHGlobal() { GlobalUnlock(glob_); }
 
   T get() { return data_; }
 
diff --git a/base/win/scoped_hstring_unittest.cc b/base/win/scoped_hstring_unittest.cc
index 37ccef3b..da67ed1c 100644
--- a/base/win/scoped_hstring_unittest.cc
+++ b/base/win/scoped_hstring_unittest.cc
@@ -38,12 +38,12 @@
   EXPECT_EQ(kTestString1, contents);
 
   hstring.reset();
-  EXPECT_TRUE(hstring == NULL);
-  EXPECT_EQ(NULL, hstring.get());
+  EXPECT_TRUE(hstring == nullptr);
+  EXPECT_EQ(nullptr, hstring.get());
 
   ScopedHString hstring2 = ScopedHString::Create(kTestString2);
   hstring.swap(hstring2);
-  EXPECT_TRUE(hstring2 == NULL);
+  EXPECT_TRUE(hstring2 == nullptr);
 
   buffer = hstring.GetAsUTF8();
   EXPECT_EQ(kTestString2, UTF8ToWide(buffer));
diff --git a/base/win/scoped_process_information.cc b/base/win/scoped_process_information.cc
index 935a4cc..42ad375 100644
--- a/base/win/scoped_process_information.cc
+++ b/base/win/scoped_process_information.cc
@@ -19,10 +19,9 @@
   if (!source)
     return true;
 
-  HANDLE temp = NULL;
-  if (!::DuplicateHandle(::GetCurrentProcess(), source,
-                         ::GetCurrentProcess(), &temp, 0, FALSE,
-                         DUPLICATE_SAME_ACCESS)) {
+  HANDLE temp = nullptr;
+  if (!::DuplicateHandle(::GetCurrentProcess(), source, ::GetCurrentProcess(),
+                         &temp, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
     DWORD last_error = ::GetLastError();
     DPLOG(ERROR) << "Failed to duplicate a handle " << last_error;
     ::SetLastError(last_error);
@@ -35,11 +34,11 @@
 }  // namespace
 
 ScopedProcessInformation::ScopedProcessInformation()
-    : process_id_(0), thread_id_(0) {
-}
+    : process_id_(0), thread_id_(0) {}
 
 ScopedProcessInformation::ScopedProcessInformation(
-    const PROCESS_INFORMATION& process_info) : process_id_(0), thread_id_(0) {
+    const PROCESS_INFORMATION& process_info)
+    : process_id_(0), thread_id_(0) {
   Set(process_info);
 }
 
@@ -48,8 +47,8 @@
 }
 
 bool ScopedProcessInformation::IsValid() const {
-  return process_id_ || process_handle_.Get() ||
-         thread_id_ || thread_handle_.Get();
+  return process_id_ || process_handle_.Get() || thread_id_ ||
+         thread_handle_.Get();
 }
 
 void ScopedProcessInformation::Close() {
diff --git a/base/win/scoped_process_information.h b/base/win/scoped_process_information.h
index 01df861..bbbdbfb 100644
--- a/base/win/scoped_process_information.h
+++ b/base/win/scoped_process_information.h
@@ -49,24 +49,16 @@
   HANDLE TakeThreadHandle();
 
   // Returns the held process handle, if any, while retaining ownership.
-  HANDLE process_handle() const {
-    return process_handle_.Get();
-  }
+  HANDLE process_handle() const { return process_handle_.Get(); }
 
   // Returns the held thread handle, if any, while retaining ownership.
-  HANDLE thread_handle() const {
-    return thread_handle_.Get();
-  }
+  HANDLE thread_handle() const { return thread_handle_.Get(); }
 
   // Returns the held process id, if any.
-  DWORD process_id() const {
-    return process_id_;
-  }
+  DWORD process_id() const { return process_id_; }
 
   // Returns the held thread id, if any.
-  DWORD thread_id() const {
-    return thread_id_;
-  }
+  DWORD thread_id() const { return thread_id_; }
 
  private:
   ScopedHandle process_handle_;
diff --git a/base/win/scoped_process_information_unittest.cc b/base/win/scoped_process_information_unittest.cc
index 7eb9356a..e74d6c1 100644
--- a/base/win/scoped_process_information_unittest.cc
+++ b/base/win/scoped_process_information_unittest.cc
@@ -49,14 +49,16 @@
 }
 
 void ScopedProcessInformationTest::DoCreateProcess(
-    const std::string& main_id, PROCESS_INFORMATION* process_handle) {
+    const std::string& main_id,
+    PROCESS_INFORMATION* process_handle) {
   base::CommandLine::StringType cmd_line =
       MakeCmdLine(main_id).GetCommandLineString();
   STARTUPINFO startup_info = {};
   startup_info.cb = sizeof(startup_info);
 
-  EXPECT_TRUE(::CreateProcess(NULL, base::data(cmd_line), NULL, NULL, false, 0,
-                              NULL, NULL, &startup_info, process_handle));
+  EXPECT_TRUE(::CreateProcess(nullptr, base::data(cmd_line), nullptr, nullptr,
+                              false, 0, nullptr, nullptr, &startup_info,
+                              process_handle));
 }
 
 TEST_F(ScopedProcessInformationTest, InitiallyInvalid) {
@@ -82,7 +84,7 @@
 
   HANDLE process = process_info.TakeProcessHandle();
   EXPECT_EQ(kProcessHandle, process);
-  EXPECT_EQ(NULL, process_info.process_handle());
+  EXPECT_EQ(nullptr, process_info.process_handle());
   EXPECT_EQ(0u, process_info.process_id());
   EXPECT_TRUE(process_info.IsValid());
   process_info.Take();
@@ -94,7 +96,7 @@
 
   HANDLE thread = process_info.TakeThreadHandle();
   EXPECT_EQ(kThreadHandle, thread);
-  EXPECT_EQ(NULL, process_info.thread_handle());
+  EXPECT_EQ(nullptr, process_info.thread_handle());
   EXPECT_EQ(0u, process_info.thread_id());
   EXPECT_TRUE(process_info.IsValid());
   process_info.Take();
diff --git a/base/win/scoped_propvariant.h b/base/win/scoped_propvariant.h
index aa9afec..0f1d5c85 100644
--- a/base/win/scoped_propvariant.h
+++ b/base/win/scoped_propvariant.h
@@ -17,13 +17,9 @@
 // construction and destruction of this class.
 class ScopedPropVariant {
  public:
-  ScopedPropVariant() {
-    PropVariantInit(&pv_);
-  }
+  ScopedPropVariant() { PropVariantInit(&pv_); }
 
-  ~ScopedPropVariant() {
-    Reset();
-  }
+  ~ScopedPropVariant() { Reset(); }
 
   // Returns a pointer to the underlying PROPVARIANT for use as an out param in
   // a function call.
diff --git a/base/win/scoped_select_object.h b/base/win/scoped_select_object.h
index 59b21c1..d4b1a81 100644
--- a/base/win/scoped_select_object.h
+++ b/base/win/scoped_select_object.h
@@ -17,8 +17,7 @@
 class ScopedSelectObject {
  public:
   ScopedSelectObject(HDC hdc, HGDIOBJ object)
-      : hdc_(hdc),
-        oldobj_(SelectObject(hdc, object)) {
+      : hdc_(hdc), oldobj_(SelectObject(hdc, object)) {
     DCHECK(hdc_);
     DCHECK(object);
     DCHECK(oldobj_ != NULL && oldobj_ != HGDI_ERROR);
diff --git a/base/win/scoped_variant.h b/base/win/scoped_variant.h
index afeecce..ac14dc2 100644
--- a/base/win/scoped_variant.h
+++ b/base/win/scoped_variant.h
@@ -6,6 +6,7 @@
 #define BASE_WIN_SCOPED_VARIANT_H_
 
 #include <windows.h>
+
 #include <oleauto.h>
 #include <stdint.h>
 
@@ -66,9 +67,7 @@
 
   ~ScopedVariant();
 
-  inline VARTYPE type() const {
-    return var_.vt;
-  }
+  inline VARTYPE type() const { return var_.vt; }
 
   // Give ScopedVariant ownership over an already allocated VARIANT.
   void Reset(const VARIANT& var = kEmptyVariant);
@@ -149,9 +148,7 @@
 
   // Allows the ScopedVariant instance to be passed to functions either by value
   // or by const reference.
-  operator const VARIANT&() const {
-    return var_;
-  }
+  operator const VARIANT&() const { return var_; }
 
   // Used as a debug check to see if we're leaking anything.
   static bool IsLeakableVarType(VARTYPE vt);
diff --git a/base/win/scoped_variant_unittest.cc b/base/win/scoped_variant_unittest.cc
index ef762f9..e4820d7 100644
--- a/base/win/scoped_variant_unittest.cc
+++ b/base/win/scoped_variant_unittest.cc
@@ -18,7 +18,7 @@
 static const wchar_t kTestString2[] = L"Also used to create BSTRs";
 
 void GiveMeAVariant(VARIANT* ret) {
-  EXPECT_TRUE(ret != NULL);
+  EXPECT_TRUE(ret != nullptr);
   ret->vt = VT_BSTR;
   V_BSTR(ret) = ::SysAllocString(kTestString1);
 }
@@ -28,8 +28,7 @@
 // when AddRef is called and decrements it when Release is called.
 class FakeComObject : public IDispatch {
  public:
-  FakeComObject() : ref_(0) {
-  }
+  FakeComObject() : ref_(0) {}
 
   STDMETHOD_(DWORD, AddRef)() override {
     ref_++;
@@ -51,21 +50,14 @@
     return E_NOTIMPL;
   }
 
-  STDMETHOD(Invoke)(DISPID,
-                    REFIID,
-                    LCID,
-                    WORD,
-                    DISPPARAMS*,
-                    VARIANT*,
-                    EXCEPINFO*,
-                    UINT*) override {
+  STDMETHOD(Invoke)
+  (DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*)
+      override {
     return E_NOTIMPL;
   }
 
   // A way to check the internal reference count of the class.
-  int ref_count() const {
-    return ref_;
-  }
+  int ref_count() const { return ref_; }
 
  protected:
   int ref_;
@@ -80,7 +72,8 @@
 
   ScopedVariant var_bstr(L"VT_BSTR");
   EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr()));
-  EXPECT_TRUE(V_BSTR(var_bstr.ptr()) != NULL);  // can't use EXPECT_NE for BSTR
+  EXPECT_TRUE(V_BSTR(var_bstr.ptr()) !=
+              nullptr);  // can't use EXPECT_NE for BSTR
   var_bstr.Reset();
   EXPECT_NE(VT_BSTR, V_VT(var_bstr.ptr()));
   var_bstr.Set(kTestString2);
@@ -179,14 +172,14 @@
 
   // Com interface tests
 
-  var.Set(static_cast<IDispatch*>(NULL));
+  var.Set(static_cast<IDispatch*>(nullptr));
   EXPECT_EQ(VT_DISPATCH, var.type());
-  EXPECT_EQ(NULL, V_DISPATCH(var.ptr()));
+  EXPECT_EQ(nullptr, V_DISPATCH(var.ptr()));
   var.Reset();
 
-  var.Set(static_cast<IUnknown*>(NULL));
+  var.Set(static_cast<IUnknown*>(nullptr));
   EXPECT_EQ(VT_UNKNOWN, var.type());
-  EXPECT_EQ(NULL, V_UNKNOWN(var.ptr()));
+  EXPECT_EQ(nullptr, V_UNKNOWN(var.ptr()));
   var.Reset();
 
   FakeComObject faker;
@@ -259,11 +252,11 @@
   }
 
   // SAFEARRAY tests
-  var.Set(static_cast<SAFEARRAY*>(NULL));
+  var.Set(static_cast<SAFEARRAY*>(nullptr));
   EXPECT_EQ(VT_EMPTY, var.type());
 
   SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100);
-  ASSERT_TRUE(sa != NULL);
+  ASSERT_TRUE(sa != nullptr);
 
   var.Set(sa);
   EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type()));
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
index 1e93435..0215ea5f 100644
--- a/base/win/shortcut.cc
+++ b/base/win/shortcut.cc
@@ -5,9 +5,9 @@
 #include "base/win/shortcut.h"
 
 #include <objbase.h>
+#include <propkey.h>
 #include <shellapi.h>
 #include <shlobj.h>
-#include <propkey.h>
 #include <wrl/client.h>
 
 #include "base/files/file_util.h"
@@ -35,7 +35,7 @@
                                   ComPtr<IPersistFile>* i_persist_file) {
   i_shell_link->Reset();
   i_persist_file->Reset();
-  if (FAILED(::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+  if (FAILED(::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
                                 IID_PPV_ARGS(i_shell_link->GetAddressOf()))) ||
       FAILED(i_shell_link->CopyTo(i_persist_file->GetAddressOf())) ||
       (shortcut && FAILED((*i_persist_file)->Load(shortcut, STGM_READWRITE)))) {
@@ -47,14 +47,12 @@
 }  // namespace
 
 ShortcutProperties::ShortcutProperties()
-    : icon_index(-1), dual_mode(false), options(0U) {
-}
+    : icon_index(-1), dual_mode(false), options(0U) {}
 
 ShortcutProperties::ShortcutProperties(const ShortcutProperties& other) =
     default;
 
-ShortcutProperties::~ShortcutProperties() {
-}
+ShortcutProperties::~ShortcutProperties() {}
 
 bool CreateOrUpdateShortcutLink(const FilePath& shortcut_path,
                                 const ShortcutProperties& properties,
@@ -79,7 +77,7 @@
   ComPtr<IPersistFile> i_persist_file;
   switch (operation) {
     case SHORTCUT_CREATE_ALWAYS:
-      InitializeShortcutInterfaces(NULL, &i_shell_link, &i_persist_file);
+      InitializeShortcutInterfaces(nullptr, &i_shell_link, &i_persist_file);
       break;
     case SHORTCUT_UPDATE_EXISTING:
       InitializeShortcutInterfaces(shortcut_path.value().c_str(), &i_shell_link,
@@ -93,7 +91,7 @@
       // so, initialize the interfaces to begin writing a new shortcut (to
       // overwrite the current one if successful).
       if (old_i_persist_file.Get())
-        InitializeShortcutInterfaces(NULL, &i_shell_link, &i_persist_file);
+        InitializeShortcutInterfaces(nullptr, &i_shell_link, &i_persist_file);
       break;
     default:
       NOTREACHED();
@@ -119,8 +117,8 @@
       return false;
   } else if (old_i_persist_file.Get()) {
     wchar_t current_arguments[MAX_PATH] = {0};
-    if (SUCCEEDED(old_i_shell_link->GetArguments(current_arguments,
-                                                 MAX_PATH))) {
+    if (SUCCEEDED(
+            old_i_shell_link->GetArguments(current_arguments, MAX_PATH))) {
       i_shell_link->SetArguments(current_arguments);
     }
   }
@@ -153,10 +151,9 @@
                                                 properties.app_id.c_str())) {
       return false;
     }
-    if (has_dual_mode &&
-        !SetBooleanValueForPropertyStore(property_store.Get(),
-                                         PKEY_AppUserModel_IsDualMode,
-                                         properties.dual_mode)) {
+    if (has_dual_mode && !SetBooleanValueForPropertyStore(
+                             property_store.Get(), PKEY_AppUserModel_IsDualMode,
+                             properties.dual_mode)) {
       return false;
     }
     if (has_toast_activator_clsid &&
@@ -186,10 +183,10 @@
     if (shortcut_existed) {
       // TODO(gab): SHCNE_UPDATEITEM might be sufficient here; further testing
       // required.
-      SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+      SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
     } else {
       SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, shortcut_path.value().c_str(),
-                     NULL);
+                     nullptr);
     }
   }
 
@@ -208,7 +205,7 @@
   ComPtr<IShellLink> i_shell_link;
 
   // Get pointer to the IShellLink interface.
-  if (FAILED(::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+  if (FAILED(::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
                                 IID_PPV_ARGS(&i_shell_link)))) {
     return false;
   }
@@ -227,7 +224,8 @@
 
   wchar_t temp[MAX_PATH];
   if (options & ShortcutProperties::PROPERTIES_TARGET) {
-    if (FAILED(i_shell_link->GetPath(temp, MAX_PATH, NULL, SLGP_UNCPRIORITY))) {
+    if (FAILED(
+            i_shell_link->GetPath(temp, MAX_PATH, nullptr, SLGP_UNCPRIORITY))) {
       return false;
     }
     properties->set_target(FilePath(temp));
@@ -269,8 +267,8 @@
 
     if (options & ShortcutProperties::PROPERTIES_APP_ID) {
       ScopedPropVariant pv_app_id;
-      if (property_store->GetValue(PKEY_AppUserModel_ID,
-                                   pv_app_id.Receive()) != S_OK) {
+      if (property_store->GetValue(PKEY_AppUserModel_ID, pv_app_id.Receive()) !=
+          S_OK) {
         return false;
       }
       switch (pv_app_id.get().vt) {
@@ -362,7 +360,7 @@
   DCHECK(CanPinShortcutToTaskbar());
 
   intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
-      NULL, L"taskbarpin", shortcut.value().c_str(), NULL, NULL, 0));
+      nullptr, L"taskbarpin", shortcut.value().c_str(), nullptr, nullptr, 0));
   return result > 32;
 }
 
@@ -370,7 +368,7 @@
   ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
 
   intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
-      NULL, L"taskbarunpin", shortcut.value().c_str(), NULL, NULL, 0));
+      nullptr, L"taskbarunpin", shortcut.value().c_str(), nullptr, nullptr, 0));
   return result > 32;
 }
 
diff --git a/base/win/shortcut.h b/base/win/shortcut.h
index 9f656ad5..6af85ec 100644
--- a/base/win/shortcut.h
+++ b/base/win/shortcut.h
@@ -6,6 +6,7 @@
 #define BASE_WIN_SHORTCUT_H_
 
 #include <windows.h>
+
 #include <stdint.h>
 
 #include "base/base_export.h"
diff --git a/base/win/shortcut_unittest.cc b/base/win/shortcut_unittest.cc
index 76c80dcf..5f80f4f 100644
--- a/base/win/shortcut_unittest.cc
+++ b/base/win/shortcut_unittest.cc
@@ -95,8 +95,8 @@
 TEST_F(ShortcutTest, CreateAndResolveShortcutProperties) {
   // Test all properties.
   FilePath file_1(temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Link1.lnk")));
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      file_1, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(file_1, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties properties_read_1;
   ASSERT_TRUE(ResolveShortcutProperties(
@@ -119,8 +119,8 @@
   FilePath file_2(temp_dir_.GetPath().Append(FILE_PATH_LITERAL("Link2.lnk")));
   ShortcutProperties only_target_properties;
   only_target_properties.set_target(link_properties_.target);
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      file_2, only_target_properties, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(file_2, only_target_properties,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties properties_read_2;
   ASSERT_TRUE(ResolveShortcutProperties(
@@ -143,11 +143,11 @@
   ShortcutProperties only_target_properties;
   only_target_properties.set_target(link_properties_.target);
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, only_target_properties, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, only_target_properties,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   FilePath resolved_name;
-  EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, NULL));
+  EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, nullptr));
 
   char read_contents[base::size(kFileContents)];
   base::ReadFile(resolved_name, read_contents, base::size(read_contents));
@@ -155,8 +155,8 @@
 }
 
 TEST_F(ShortcutTest, ResolveShortcutWithArgs) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   FilePath resolved_name;
   std::wstring args;
@@ -173,47 +173,45 @@
   target_and_args_properties.set_target(link_properties_.target);
   target_and_args_properties.set_arguments(link_properties_.arguments);
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, target_and_args_properties,
-      SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, target_and_args_properties,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ValidateShortcut(link_file_, target_and_args_properties);
 }
 
 TEST_F(ShortcutTest, CreateShortcutVerifyProperties) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ValidateShortcut(link_file_, link_properties_);
 }
 
 TEST_F(ShortcutTest, UpdateShortcutVerifyProperties) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_2_, SHORTCUT_UPDATE_EXISTING));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_2_,
+                                         SHORTCUT_UPDATE_EXISTING));
 
   ValidateShortcut(link_file_, link_properties_2_);
 }
 
 TEST_F(ShortcutTest, UpdateShortcutUpdateOnlyTargetAndResolve) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties update_only_target_properties;
   update_only_target_properties.set_target(link_properties_2_.target);
 
   ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, update_only_target_properties,
-      SHORTCUT_UPDATE_EXISTING));
+      link_file_, update_only_target_properties, SHORTCUT_UPDATE_EXISTING));
 
   ShortcutProperties expected_properties = link_properties_;
   expected_properties.set_target(link_properties_2_.target);
   ValidateShortcut(link_file_, expected_properties);
 
   FilePath resolved_name;
-  EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, NULL));
+  EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, nullptr));
 
   char read_contents[base::size(kFileContents2)];
   base::ReadFile(resolved_name, read_contents, base::size(read_contents));
@@ -221,15 +219,14 @@
 }
 
 TEST_F(ShortcutTest, UpdateShortcutMakeDualMode) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties make_dual_mode_properties;
   make_dual_mode_properties.set_dual_mode(true);
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, make_dual_mode_properties,
-      SHORTCUT_UPDATE_EXISTING));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, make_dual_mode_properties,
+                                         SHORTCUT_UPDATE_EXISTING));
 
   ShortcutProperties expected_properties = link_properties_;
   expected_properties.set_dual_mode(true);
@@ -237,15 +234,14 @@
 }
 
 TEST_F(ShortcutTest, UpdateShortcutRemoveDualMode) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_2_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_2_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties remove_dual_mode_properties;
   remove_dual_mode_properties.set_dual_mode(false);
 
   ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, remove_dual_mode_properties,
-      SHORTCUT_UPDATE_EXISTING));
+      link_file_, remove_dual_mode_properties, SHORTCUT_UPDATE_EXISTING));
 
   ShortcutProperties expected_properties = link_properties_2_;
   expected_properties.set_dual_mode(false);
@@ -253,15 +249,14 @@
 }
 
 TEST_F(ShortcutTest, UpdateShortcutClearArguments) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties clear_arguments_properties;
   clear_arguments_properties.set_arguments(std::wstring());
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, clear_arguments_properties,
-      SHORTCUT_UPDATE_EXISTING));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, clear_arguments_properties,
+                                         SHORTCUT_UPDATE_EXISTING));
 
   ShortcutProperties expected_properties = link_properties_;
   expected_properties.set_arguments(std::wstring());
@@ -269,31 +264,31 @@
 }
 
 TEST_F(ShortcutTest, FailUpdateShortcutThatDoesNotExist) {
-  ASSERT_FALSE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_UPDATE_EXISTING));
+  ASSERT_FALSE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                          SHORTCUT_UPDATE_EXISTING));
   ASSERT_FALSE(PathExists(link_file_));
 }
 
 TEST_F(ShortcutTest, ReplaceShortcutAllProperties) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_2_, SHORTCUT_REPLACE_EXISTING));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_2_,
+                                         SHORTCUT_REPLACE_EXISTING));
 
   ValidateShortcut(link_file_, link_properties_2_);
 }
 
 TEST_F(ShortcutTest, ReplaceShortcutSomeProperties) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   ShortcutProperties new_properties;
   new_properties.set_target(link_properties_2_.target);
   new_properties.set_arguments(link_properties_2_.arguments);
   new_properties.set_description(link_properties_2_.description);
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, new_properties, SHORTCUT_REPLACE_EXISTING));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, new_properties,
+                                         SHORTCUT_REPLACE_EXISTING));
 
   // Expect only properties in |new_properties| to be set, all other properties
   // should have been overwritten.
@@ -306,22 +301,21 @@
 }
 
 TEST_F(ShortcutTest, FailReplaceShortcutThatDoesNotExist) {
-  ASSERT_FALSE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_REPLACE_EXISTING));
+  ASSERT_FALSE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                          SHORTCUT_REPLACE_EXISTING));
   ASSERT_FALSE(PathExists(link_file_));
 }
 
 // Test that the old arguments remain on the replaced shortcut when not
 // otherwise specified.
 TEST_F(ShortcutTest, ReplaceShortcutKeepOldArguments) {
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_,
+                                         SHORTCUT_CREATE_ALWAYS));
 
   // Do not explicitly set the arguments.
-  link_properties_2_.options &=
-      ~ShortcutProperties::PROPERTIES_ARGUMENTS;
-  ASSERT_TRUE(CreateOrUpdateShortcutLink(
-      link_file_, link_properties_2_, SHORTCUT_REPLACE_EXISTING));
+  link_properties_2_.options &= ~ShortcutProperties::PROPERTIES_ARGUMENTS;
+  ASSERT_TRUE(CreateOrUpdateShortcutLink(link_file_, link_properties_2_,
+                                         SHORTCUT_REPLACE_EXISTING));
 
   ShortcutProperties expected_properties(link_properties_2_);
   expected_properties.set_arguments(link_properties_.arguments);
diff --git a/base/win/startup_information.cc b/base/win/startup_information.cc
index 372b85e..a78508d 100644
--- a/base/win/startup_information.cc
+++ b/base/win/startup_information.cc
@@ -45,10 +45,9 @@
   return true;
 }
 
-bool StartupInformation::UpdateProcThreadAttribute(
-    DWORD_PTR attribute,
-    void* value,
-    size_t size) {
+bool StartupInformation::UpdateProcThreadAttribute(DWORD_PTR attribute,
+                                                   void* value,
+                                                   size_t size) {
   if (!startup_info_.lpAttributeList)
     return false;
   return !!::UpdateProcThreadAttribute(startup_info_.lpAttributeList, 0,
@@ -58,4 +57,3 @@
 
 }  // namespace win
 }  // namespace base
-
diff --git a/base/win/startup_information.h b/base/win/startup_information.h
index 2d4edaf5..7ef6965 100644
--- a/base/win/startup_information.h
+++ b/base/win/startup_information.h
@@ -5,11 +5,12 @@
 #ifndef BASE_WIN_STARTUP_INFORMATION_H_
 #define BASE_WIN_STARTUP_INFORMATION_H_
 
-#include <memory>
-
 #include <windows.h>
+
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/base_export.h"
 #include "base/macros.h"
 
@@ -29,9 +30,7 @@
   // Sets one entry in the initialized attribute list.
   // |value| needs to live at least as long as the StartupInformation object
   // this is called on.
-  bool UpdateProcThreadAttribute(DWORD_PTR attribute,
-                                 void* value,
-                                 size_t size);
+  bool UpdateProcThreadAttribute(DWORD_PTR attribute, void* value, size_t size);
 
   LPSTARTUPINFOW startup_info() { return &startup_info_.StartupInfo; }
   LPSTARTUPINFOW startup_info() const {
diff --git a/base/win/startup_information_unittest.cc b/base/win/startup_information_unittest.cc
index eb15822..b407d20d 100644
--- a/base/win/startup_information_unittest.cc
+++ b/base/win/startup_information_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/win/startup_information.h"
 
 #include <windows.h>
+
 #include <stddef.h>
 
 #include "base/files/file_path.h"
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index 80e8e978..bca2c75 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -85,7 +85,7 @@
 }
 
 void __cdecl ForceCrashOnSigAbort(int) {
-  *((volatile int*)0) = 0x1337;
+  *((volatile int*)nullptr) = 0x1337;
 }
 
 // Returns the current platform role. We use the PowerDeterminePlatformRoleEx
@@ -251,8 +251,8 @@
   }
 
   // This function should be only invoked for machines with touch screens.
-  if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH)
-        != NID_INTEGRATED_TOUCH) {
+  if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) !=
+      NID_INTEGRATED_TOUCH) {
     if (reason) {
       *reason += "NID_INTEGRATED_TOUCH\n";
       result = true;
@@ -289,7 +289,7 @@
   // 3. If step 1 and 2 fail then we check attached keyboards and return true
   //    if we find ACPI\* or HID\VID* keyboards.
 
-  typedef BOOL (WINAPI* GetAutoRotationState)(PAR_STATE state);
+  typedef BOOL(WINAPI * GetAutoRotationState)(PAR_STATE state);
   static const auto get_rotation_state = reinterpret_cast<GetAutoRotationState>(
       GetUser32FunctionPointer("GetAutoRotationState"));
   if (get_rotation_state) {
@@ -309,13 +309,15 @@
     }
   }
 
-  const GUID KEYBOARD_CLASS_GUID =
-      { 0x4D36E96B, 0xE325,  0x11CE,
-          { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
+  const GUID KEYBOARD_CLASS_GUID = {
+      0x4D36E96B,
+      0xE325,
+      0x11CE,
+      {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}};
 
   // Query for all the keyboard devices.
-  HDEVINFO device_info =
-      SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT);
+  HDEVINFO device_info = SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, nullptr,
+                                             nullptr, DIGCF_PRESENT);
   if (device_info == INVALID_HANDLE_VALUE) {
     if (reason)
       *reason += "No keyboard info\n";
@@ -326,7 +328,7 @@
   // the count is more than 1 we assume that a keyboard is present. This is
   // under the assumption that there will always be one keyboard device.
   for (DWORD i = 0;; ++i) {
-    SP_DEVINFO_DATA device_info_data = { 0 };
+    SP_DEVINFO_DATA device_info_data = {0};
     device_info_data.cbSize = sizeof(device_info_data);
     if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data))
       break;
@@ -362,7 +364,7 @@
 
 bool GetUserSidString(std::wstring* user_sid) {
   // Get the current token.
-  HANDLE token = NULL;
+  HANDLE token = nullptr;
   if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
     return false;
   ScopedHandle token_scoped(token);
@@ -416,8 +418,7 @@
     return false;
   }
 
-  return SetPropVariantValueForPropertyStore(property_store,
-                                             property_key,
+  return SetPropVariantValueForPropertyStore(property_store, property_key,
                                              property_value);
 }
 
@@ -430,8 +431,7 @@
     return false;
   }
 
-  return SetPropVariantValueForPropertyStore(property_store,
-                                             property_key,
+  return SetPropVariantValueForPropertyStore(property_store, property_key,
                                              property_value);
 }
 
@@ -456,8 +456,7 @@
   DCHECK_LT(lstrlen(app_id), 64);
   DCHECK_EQ(wcschr(app_id, L' '), nullptr);
 
-  return SetStringValueForPropertyStore(property_store,
-                                        PKEY_AppUserModel_ID,
+  return SetStringValueForPropertyStore(property_store, PKEY_AppUserModel_ID,
                                         app_id);
 }
 
@@ -469,7 +468,7 @@
                          const std::wstring& command) {
   RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE);
   return (autorun_key.WriteValue(name.c_str(), command.c_str()) ==
-      ERROR_SUCCESS);
+          ERROR_SUCCESS);
 }
 
 bool RemoveCommandFromAutoRun(HKEY root_key, const std::wstring& name) {
@@ -658,7 +657,7 @@
       // Buffer size was too small. Try again with a larger buffer. A little
       // more room is given to avoid multiple expensive calls to
       // ::EnumProcessModules() just because one module has been added.
-      snapshot->resize(num_modules + 8, NULL);
+      snapshot->resize(num_modules + 8, nullptr);
     }
   } while (--retries_remaining);
 
@@ -672,8 +671,8 @@
 
 void DisableFlicks(HWND hwnd) {
   ::SetProp(hwnd, MICROSOFT_TABLETPENSERVICE_PROPERTY,
-      reinterpret_cast<HANDLE>(TABLET_DISABLE_FLICKS |
-          TABLET_DISABLE_FLICKFALLBACKKEYS));
+            reinterpret_cast<HANDLE>(TABLET_DISABLE_FLICKS |
+                                     TABLET_DISABLE_FLICKFALLBACKKEYS));
 }
 
 bool IsProcessPerMonitorDpiAware() {
diff --git a/base/win/win_util_unittest.cc b/base/win/win_util_unittest.cc
index 17f8e8e..977d04c 100644
--- a/base/win/win_util_unittest.cc
+++ b/base/win/win_util_unittest.cc
@@ -58,10 +58,10 @@
   // Load in a new module. Pick zipfldr.dll as it is present from WinXP to
   // Win10, including ARM64 Win10, and yet rarely used.
   const FilePath::CharType dll_name[] = FILE_PATH_LITERAL("zipfldr.dll");
-  ASSERT_EQ(NULL, ::GetModuleHandle(dll_name));
+  ASSERT_EQ(nullptr, ::GetModuleHandle(dll_name));
 
   ScopedNativeLibrary new_dll((FilePath(dll_name)));
-  ASSERT_NE(static_cast<HMODULE>(NULL), new_dll.get());
+  ASSERT_NE(static_cast<HMODULE>(nullptr), new_dll.get());
   ASSERT_TRUE(GetLoadedModulesSnapshot(::GetCurrentProcess(), &snapshot));
   ASSERT_GT(snapshot.size(), original_snapshot_size);
   ASSERT_TRUE(Contains(snapshot, new_dll.get()));
diff --git a/base/win/wincrypt_shim.h b/base/win/wincrypt_shim.h
index ba94a87..06c896d 100644
--- a/base/win/wincrypt_shim.h
+++ b/base/win/wincrypt_shim.h
@@ -10,6 +10,7 @@
 // Chromium headers which include wincrypt should instead include this header.
 
 #include <windows.h>
+
 #include <wincrypt.h>
 
 // Undefine the macros which conflict with OpenSSL and define replacements. See
@@ -18,8 +19,8 @@
 #undef X509_EXTENSIONS
 #undef X509_NAME
 
-#define WINCRYPT_X509_CERT_PAIR ((LPCSTR) 53)
-#define WINCRYPT_X509_EXTENSIONS ((LPCSTR) 5)
-#define WINCRYPT_X509_NAME ((LPCSTR) 7)
+#define WINCRYPT_X509_CERT_PAIR ((LPCSTR)53)
+#define WINCRYPT_X509_EXTENSIONS ((LPCSTR)5)
+#define WINCRYPT_X509_NAME ((LPCSTR)7)
 
 #endif  // BASE_WIN_WINCRYPT_SHIM_H_
diff --git a/base/win/windows_types.h b/base/win/windows_types.h
index 60c4ffe..8b663bb 100644
--- a/base/win/windows_types.h
+++ b/base/win/windows_types.h
@@ -129,10 +129,11 @@
   PVOID Ptr;
 };
 
-
 // Define some commonly used Windows constants. Note that the layout of these
 // macros - including internal spacing - must be 100% consistent with windows.h.
 
+// clang-format off
+
 #ifndef INVALID_HANDLE_VALUE
 // Work around there being two slightly different definitions in the SDK.
 #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
@@ -199,6 +200,8 @@
                                   &                           \
                                  (~SYNCHRONIZE))
 
+// clang-format on
+
 // Define some macros needed when prototyping Windows functions.
 
 #define DECLSPEC_IMPORT __declspec(dllimport)
diff --git a/base/win/wmi.cc b/base/win/wmi.cc
index 02bf6a89..3e0b8c4 100644
--- a/base/win/wmi.cc
+++ b/base/win/wmi.cc
@@ -120,12 +120,12 @@
   // We're only expecting int32_t or uint32_t values, so no need for
   // ScopedVariant.
   VARIANT ret_value = {{{VT_EMPTY}}};
-  hr = out_params->Get(L"ReturnValue", 0, &ret_value, nullptr, 0);
+  hr = out_params->Get(L"ReturnValue", 0, &ret_value, nullptr, nullptr);
   if (FAILED(hr) || V_I4(&ret_value) != 0)
     return false;
 
   VARIANT pid = {{{VT_EMPTY}}};
-  hr = out_params->Get(L"ProcessId", 0, &pid, nullptr, 0);
+  hr = out_params->Get(L"ProcessId", 0, &pid, nullptr, nullptr);
   if (FAILED(hr) || V_I4(&pid) == 0)
     return false;
 
@@ -170,13 +170,14 @@
     return;
 
   ScopedVariant manufacturer;
-  hr = class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), 0, 0);
+  hr = class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), nullptr,
+                         nullptr);
   if (SUCCEEDED(hr) && manufacturer.type() == VT_BSTR) {
     manufacturer_.assign(V_BSTR(manufacturer.ptr()),
                          ::SysStringLen(V_BSTR(manufacturer.ptr())));
   }
   ScopedVariant model;
-  hr = class_object->Get(L"Model", 0, model.Receive(), 0, 0);
+  hr = class_object->Get(L"Model", 0, model.Receive(), nullptr, nullptr);
   if (SUCCEEDED(hr) && model.type() == VT_BSTR) {
     model_.assign(V_BSTR(model.ptr()), ::SysStringLen(V_BSTR(model.ptr())));
   }
@@ -202,7 +203,8 @@
     return;
 
   ScopedVariant serial_number;
-  hr = class_obj->Get(L"SerialNumber", 0, serial_number.Receive(), 0, 0);
+  hr = class_obj->Get(L"SerialNumber", 0, serial_number.Receive(), nullptr,
+                      nullptr);
   if (SUCCEEDED(hr) && serial_number.type() == VT_BSTR) {
     serial_number_.assign(V_BSTR(serial_number.ptr()),
                           ::SysStringLen(V_BSTR(serial_number.ptr())));
diff --git a/base/win/wrapped_window_proc.cc b/base/win/wrapped_window_proc.cc
index 1b95a80..355f0e2f 100644
--- a/base/win/wrapped_window_proc.cc
+++ b/base/win/wrapped_window_proc.cc
@@ -10,17 +10,16 @@
 
 namespace {
 
-base::win::WinProcExceptionFilter s_exception_filter = NULL;
+base::win::WinProcExceptionFilter s_exception_filter = nullptr;
 
 HMODULE GetModuleFromWndProc(WNDPROC window_proc) {
-  HMODULE instance = NULL;
+  HMODULE instance = nullptr;
   // Converting a pointer-to-function to a void* is undefined behavior, but
   // Windows (and POSIX) APIs require it to work.
   void* address = reinterpret_cast<void*>(window_proc);
   if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
-                            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
-                            static_cast<char*>(address),
-                            &instance)) {
+                                GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+                            static_cast<char*>(address), &instance)) {
     NOTREACHED();
   }
   return instance;
@@ -40,8 +39,8 @@
 }
 
 int CallExceptionFilter(EXCEPTION_POINTERS* info) {
-  return s_exception_filter ? s_exception_filter(info) :
-                              EXCEPTION_CONTINUE_SEARCH;
+  return s_exception_filter ? s_exception_filter(info)
+                            : EXCEPTION_CONTINUE_SEARCH;
 }
 
 BASE_EXPORT void InitializeWindowClass(const char16* class_name,
@@ -71,7 +70,7 @@
   class_out->hIconSm = small_icon;
 
   // Check if |window_proc| is valid.
-  DCHECK(class_out->hInstance != NULL);
+  DCHECK(class_out->hInstance != nullptr);
 }
 
 }  // namespace win
diff --git a/base/win/wrapped_window_proc.h b/base/win/wrapped_window_proc.h
index e5168164..0742019a0 100644
--- a/base/win/wrapped_window_proc.h
+++ b/base/win/wrapped_window_proc.h
@@ -23,13 +23,13 @@
 // expected behavior for this function is to not return, instead of returning
 // EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not
 // prepared to handle exceptions.
-typedef int (__cdecl *WinProcExceptionFilter)(EXCEPTION_POINTERS* info);
+typedef int(__cdecl* WinProcExceptionFilter)(EXCEPTION_POINTERS* info);
 
 // Sets the filter to deal with exceptions inside a WindowProc. Returns the old
 // exception filter, if any.
 // This function should be called before any window is created.
-BASE_EXPORT WinProcExceptionFilter SetWinProcExceptionFilter(
-    WinProcExceptionFilter filter);
+BASE_EXPORT WinProcExceptionFilter
+SetWinProcExceptionFilter(WinProcExceptionFilter filter);
 
 // Calls the registered exception filter.
 BASE_EXPORT int CallExceptionFilter(EXCEPTION_POINTERS* info);
@@ -73,7 +73,7 @@
   LRESULT rv = 0;
   __try {
     rv = proc(hwnd, message, wparam, lparam);
-  } __except(CallExceptionFilter(GetExceptionInformation())) {
+  } __except (CallExceptionFilter(GetExceptionInformation())) {
   }
   return rv;
 }
diff --git a/base/win/wrapped_window_proc_unittest.cc b/base/win/wrapped_window_proc_unittest.cc
index 25ba2d42..4d3b88e 100644
--- a/base/win/wrapped_window_proc_unittest.cc
+++ b/base/win/wrapped_window_proc_unittest.cc
@@ -11,10 +11,12 @@
 WPARAM kCrashMsg = 98765;
 
 // A trivial WindowProc that generates an exception.
-LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT message,
-                                WPARAM wparam, LPARAM lparam) {
+LRESULT CALLBACK TestWindowProc(HWND hwnd,
+                                UINT message,
+                                WPARAM wparam,
+                                LPARAM lparam) {
   if (message == kCrashMsg)
-    RaiseException(kExceptionCode, 0, 0, NULL);
+    RaiseException(kExceptionCode, 0, 0, nullptr);
   return DefWindowProc(hwnd, message, wparam, lparam);
 }
 
@@ -29,12 +31,10 @@
 
   ~TestWrappedExceptionFiter() {
     EXPECT_EQ(s_filter_, this);
-    s_filter_ = NULL;
+    s_filter_ = nullptr;
   }
 
-  bool called() {
-    return called_;
-  }
+  bool called() { return called_; }
 
   // The actual exception filter just records the exception.
   static int Filter(EXCEPTION_POINTERS* info) {
@@ -48,12 +48,12 @@
   bool called_;
   static TestWrappedExceptionFiter* s_filter_;
 };
-TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = NULL;
+TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = nullptr;
 
 }  // namespace.
 
 TEST(WrappedWindowProc, CatchesExceptions) {
-  HINSTANCE hinst = GetModuleHandle(NULL);
+  HINSTANCE hinst = GetModuleHandle(nullptr);
   std::wstring class_name(L"TestClass");
 
   WNDCLASS wc = {0};
@@ -62,8 +62,8 @@
   wc.lpszClassName = class_name.c_str();
   RegisterClass(&wc);
 
-  HWND window = CreateWindow(class_name.c_str(), 0, 0, 0, 0, 0, 0, HWND_MESSAGE,
-                             0, hinst, 0);
+  HWND window = CreateWindow(class_name.c_str(), nullptr, 0, 0, 0, 0, 0,
+                             HWND_MESSAGE, nullptr, hinst, nullptr);
   ASSERT_TRUE(window);
 
   // Before generating the exception we make sure that the filter will see it.
diff --git a/build/android/gyp/compile_resources.py b/build/android/gyp/compile_resources.py
index 8c2f41c..4b03a37 100755
--- a/build/android/gyp/compile_resources.py
+++ b/build/android/gyp/compile_resources.py
@@ -31,6 +31,7 @@
 from util import manifest_utils
 from util import resource_utils
 
+
 # Name of environment variable that can be used to force this script to
 # put temporary resource files into specific sub-directories, instead of
 # temporary ones.
@@ -265,9 +266,8 @@
       yield os.path.join(root, f)
 
 
-def _DuplicateZhResources(resource_dirs):
+def _DuplicateZhResources(resource_dirs, path_info):
   """Duplicate Taiwanese resources into Hong-Kong specific directory."""
-  renamed_paths = dict()
   for resource_dir in resource_dirs:
     # We use zh-TW resources for zh-HK (if we have zh-TW resources).
     for path in _IterFiles(resource_dir):
@@ -275,12 +275,12 @@
         hk_path = path.replace('zh-rTW', 'zh-rHK')
         build_utils.MakeDirectory(os.path.dirname(hk_path))
         shutil.copyfile(path, hk_path)
-        renamed_paths[os.path.relpath(hk_path, resource_dir)] = os.path.relpath(
-            path, resource_dir)
-  return renamed_paths
+        path_info.RegisterRename(
+            os.path.relpath(path, resource_dir),
+            os.path.relpath(hk_path, resource_dir))
 
 
-def _RenameLocaleResourceDirs(resource_dirs):
+def _RenameLocaleResourceDirs(resource_dirs, path_info):
   """Rename locale resource directories into standard names when necessary.
 
   This is necessary to deal with the fact that older Android releases only
@@ -309,11 +309,7 @@
 
   Args:
     resource_dirs: list of top-level resource directories.
-  Returns:
-    A dictionary mapping renamed paths to their original location
-    (e.g. '.../values-tl/strings.xml' -> ' .../values-fil/strings.xml').
   """
-  renamed_paths = dict()
   for resource_dir in resource_dirs:
     for path in _IterFiles(resource_dir):
       locale = resource_utils.FindLocaleInStringResourceFilePath(path)
@@ -334,9 +330,9 @@
           continue
         build_utils.MakeDirectory(os.path.dirname(path2))
         shutil.move(path, path2)
-        renamed_paths[os.path.relpath(path2, resource_dir)] = os.path.relpath(
-            path, resource_dir)
-  return renamed_paths
+        path_info.RegisterRename(
+            os.path.relpath(path, resource_dir),
+            os.path.relpath(path2, resource_dir))
 
 
 def _ToAndroidLocales(locale_whitelist, support_zh_hk):
@@ -369,12 +365,11 @@
   return set(ret)
 
 
-def _MoveImagesToNonMdpiFolders(res_root):
+def _MoveImagesToNonMdpiFolders(res_root, path_info):
   """Move images from drawable-*-mdpi-* folders to drawable-* folders.
 
   Why? http://crbug.com/289843
   """
-  renamed_paths = dict()
   for src_dir_name in os.listdir(res_root):
     src_components = src_dir_name.split('-')
     if src_components[0] != 'drawable' or 'mdpi' not in src_components:
@@ -394,9 +389,9 @@
       dst_file = os.path.join(dst_dir, src_file_name)
       assert not os.path.lexists(dst_file)
       shutil.move(src_file, dst_file)
-      renamed_paths[os.path.relpath(dst_file, res_root)] = os.path.relpath(
-          src_file, res_root)
-  return renamed_paths
+      path_info.RegisterRename(
+          os.path.relpath(src_file, res_root),
+          os.path.relpath(dst_file, res_root))
 
 
 def _FixManifest(options, temp_dir):
@@ -511,8 +506,7 @@
       build_utils.MatchesGlob(path, resource_blacklist_exceptions))
 
 
-def _ConvertToWebP(webp_binary, png_files):
-  renamed_paths = dict()
+def _ConvertToWebP(webp_binary, png_files, path_info):
   pool = multiprocessing.pool.ThreadPool(10)
   def convert_image(png_path_tuple):
     png_path, original_dir = png_path_tuple
@@ -522,34 +516,31 @@
         '-lossless', '-o', webp_path]
     subprocess.check_call(args)
     os.remove(png_path)
-    renamed_paths[os.path.relpath(webp_path, original_dir)] = os.path.relpath(
-        png_path, original_dir)
+    path_info.RegisterRename(
+        os.path.relpath(png_path, original_dir),
+        os.path.relpath(webp_path, original_dir))
 
   pool.map(convert_image, [f for f in png_files
                            if not _PNG_WEBP_BLACKLIST_PATTERN.match(f[0])])
   pool.close()
   pool.join()
-  return renamed_paths
 
 
-def _RemoveImageExtensions(directory):
+def _RemoveImageExtensions(directory, path_info):
   """Remove extensions from image files in the passed directory.
 
   This reduces binary size but does not affect android's ability to load the
   images.
-
-  Returns: dict[destination] -> source
   """
-  renamed_paths = {}
   for f in _IterFiles(directory):
     if (f.endswith('.png') or f.endswith('.webp')) and not f.endswith('.9.png'):
       path_with_extension = f
       path_no_extension = os.path.splitext(path_with_extension)[0]
       if path_no_extension != path_with_extension:
         shutil.move(path_with_extension, path_no_extension)
-        renamed_paths[os.path.relpath(path_no_extension, directory)] = (
-            os.path.relpath(path_with_extension, directory))
-  return renamed_paths
+        path_info.RegisterRename(
+            os.path.relpath(path_with_extension, directory),
+            os.path.relpath(path_no_extension, directory))
 
 
 def _CompileDeps(aapt2_path, dep_subdirs, temp_dir):
@@ -587,17 +578,12 @@
   return partials
 
 
-def _CreateResourceInfoFile(renamed_paths, info_path, dependencies_res_zips):
-  lines = set()
+def _CreateResourceInfoFile(path_info, info_path, dependencies_res_zips):
   for zip_file in dependencies_res_zips:
     zip_info_file_path = zip_file + '.info'
     if os.path.exists(zip_info_file_path):
-      with open(zip_info_file_path, 'r') as zip_info_file:
-        lines.update(zip_info_file.readlines())
-  for dest, source in renamed_paths.iteritems():
-    lines.add('Rename:{},{}\n'.format(dest, source))
-  with open(info_path, 'w') as info_file:
-    info_file.writelines(sorted(lines))
+      path_info.MergeInfoFile(zip_info_file_path)
+  path_info.Write(info_path)
 
 
 def _RemoveUnwantedLocalizedStrings(dep_subdirs, options):
@@ -676,9 +662,9 @@
   """
   dep_subdirs = resource_utils.ExtractDeps(options.dependencies_res_zips,
                                            build.deps_dir)
-  renamed_paths = dict()
-  renamed_paths.update(_DuplicateZhResources(dep_subdirs))
-  renamed_paths.update(_RenameLocaleResourceDirs(dep_subdirs))
+  path_info = resource_utils.ResourceInfoFile()
+  _DuplicateZhResources(dep_subdirs, path_info)
+  _RenameLocaleResourceDirs(dep_subdirs, path_info)
 
   _RemoveUnwantedLocalizedStrings(dep_subdirs, options)
 
@@ -695,13 +681,10 @@
       elif f.endswith('.png'):
         png_paths.append((f, directory))
   if png_paths and options.png_to_webp:
-    renamed_paths.update(_ConvertToWebP(options.webp_binary, png_paths))
+    _ConvertToWebP(options.webp_binary, png_paths, path_info)
   for directory in dep_subdirs:
-    renamed_paths.update(_MoveImagesToNonMdpiFolders(directory))
-    renamed_paths.update(_RemoveImageExtensions(directory))
-
-  _CreateResourceInfoFile(renamed_paths, build.info_path,
-                          options.dependencies_res_zips)
+    _MoveImagesToNonMdpiFolders(directory, path_info)
+    _RemoveImageExtensions(directory, path_info)
 
   link_command = [
       options.aapt2_path,
@@ -778,7 +761,15 @@
   else:
     link_command += ['-o', build.arsc_path]
 
-  build_utils.CheckOutput(link_command, print_stdout=False, print_stderr=False)
+  link_proc = subprocess.Popen(link_command)
+
+  # Create .res.info file in parallel.
+  _CreateResourceInfoFile(path_info, build.info_path,
+                          options.dependencies_res_zips)
+
+  exit_code = link_proc.wait()
+  if exit_code:
+    raise subprocess.CalledProcessError(exit_code, link_command)
 
   if options.proguard_file and (options.shared_resources
                                 or options.app_as_shared_lib):
diff --git a/build/android/gyp/jinja_template.py b/build/android/gyp/jinja_template.py
index 4d5c403..ba335a2 100755
--- a/build/android/gyp/jinja_template.py
+++ b/build/android/gyp/jinja_template.py
@@ -75,7 +75,7 @@
 
 def _ProcessFiles(processor, input_filenames, inputs_base_dir, outputs_zip):
   with build_utils.TempDir() as temp_dir:
-    files_to_zip = dict()
+    path_info = resource_utils.ResourceInfoFile()
     for input_filename in input_filenames:
       relpath = os.path.relpath(os.path.abspath(input_filename),
                                 os.path.abspath(inputs_base_dir))
@@ -87,9 +87,9 @@
       parent_dir = os.path.dirname(output_filename)
       build_utils.MakeDirectory(parent_dir)
       _ProcessFile(processor, input_filename, output_filename)
-      files_to_zip[relpath] = input_filename
+      path_info.AddMapping(relpath, input_filename)
 
-    resource_utils.CreateResourceInfoFile(files_to_zip, outputs_zip)
+    path_info.Write(outputs_zip + '.info')
     build_utils.ZipDir(outputs_zip, temp_dir)
 
 
diff --git a/build/android/gyp/prepare_resources.py b/build/android/gyp/prepare_resources.py
index 88909866..a526604 100755
--- a/build/android/gyp/prepare_resources.py
+++ b/build/android/gyp/prepare_resources.py
@@ -103,25 +103,22 @@
 
 
 def _ZipResources(resource_dirs, zip_path, ignore_pattern):
-  # Python zipfile does not provide a way to replace a file (it just writes
-  # another file with the same name). So, first collect all the files to put
-  # in the zip (with proper overriding), and then zip them.
   # ignore_pattern is a string of ':' delimited list of globs used to ignore
   # files that should not be part of the final resource zip.
-  files_to_zip = dict()
-  files_to_zip_without_generated = dict()
+  files_to_zip = []
+  path_info = resource_utils.ResourceInfoFile()
   for index, resource_dir in enumerate(resource_dirs):
     for path, archive_path in resource_utils.IterResourceFilesInDirectories(
         [resource_dir], ignore_pattern):
+      # Put the non-prefixed path in the .info file.
+      path_info.AddMapping(archive_path, path)
+
       resource_dir_name = os.path.basename(resource_dir)
       archive_path = '{}_{}/{}'.format(index, resource_dir_name, archive_path)
-      # We want the original resource dirs in the .info file rather than the
-      # generated overridden path.
-      if not path.startswith('/tmp'):
-        files_to_zip_without_generated[archive_path] = path
-      files_to_zip[archive_path] = path
-  resource_utils.CreateResourceInfoFile(files_to_zip_without_generated,
-                                        zip_path)
+      files_to_zip.append((archive_path, path))
+
+  path_info.Write(zip_path + '.info')
+
   with zipfile.ZipFile(zip_path, 'w') as z:
     # This magic comment signals to resource_utils.ExtractDeps that this zip is
     # not just the contents of a single res dir, without the encapsulating res/
@@ -129,7 +126,7 @@
     # the contents of possibly multiple res/ dirs each within an encapsulating
     # directory within the zip.
     z.comment = resource_utils.MULTIPLE_RES_MAGIC_STRING
-    build_utils.DoZip(files_to_zip.iteritems(), z)
+    build_utils.DoZip(files_to_zip, z)
 
 
 def _GenerateRTxt(options, dep_subdirs, gen_dir):
@@ -185,21 +182,6 @@
       package_command, print_stdout=False, print_stderr=False)
 
 
-def _GenerateResourcesZip(output_resource_zip, input_resource_dirs,
-                          strip_drawables):
-  """Generate a .resources.zip file fron a list of input resource dirs.
-
-  Args:
-    output_resource_zip: Path to the output .resources.zip file.
-    input_resource_dirs: A list of input resource directories.
-  """
-
-  ignore_pattern = resource_utils.AAPT_IGNORE_PATTERN
-  if strip_drawables:
-    ignore_pattern += ':*drawable*'
-  _ZipResources(input_resource_dirs, output_resource_zip, ignore_pattern)
-
-
 def _OnStaleMd5(options):
   with resource_utils.BuildContext() as build:
     if options.sources:
@@ -250,8 +232,11 @@
       build_utils.ZipDir(options.srcjar_out, build.srcjar_dir)
 
     if options.resource_zip_out:
-      _GenerateResourcesZip(options.resource_zip_out, options.resource_dirs,
-                            options.strip_drawables)
+      ignore_pattern = resource_utils.AAPT_IGNORE_PATTERN
+      if options.strip_drawables:
+        ignore_pattern += ':*drawable*'
+      _ZipResources(options.resource_dirs, options.resource_zip_out,
+                    ignore_pattern)
 
 
 def main(args):
diff --git a/build/android/gyp/util/resource_utils.py b/build/android/gyp/util/resource_utils.py
index f60788b..8105801 100644
--- a/build/android/gyp/util/resource_utils.py
+++ b/build/android/gyp/util/resource_utils.py
@@ -216,20 +216,77 @@
         yield path, archive_path
 
 
-def CreateResourceInfoFile(files_to_zip, zip_path):
-  """Given a mapping of archive paths to their source, write an info file.
+class ResourceInfoFile(object):
+  """Helper for building up .res.info files."""
 
-  The info file contains lines of '{archive_path},{source_path}' for ease of
-  parsing. Assumes that there is no comma in the file names.
+  def __init__(self):
+    # Dict of archive_path -> source_path for the current target.
+    self._entries = {}
+    # List of (old_archive_path, new_archive_path) tuples.
+    self._renames = []
+    # We don't currently support using both AddMapping and MergeInfoFile.
+    self._add_mapping_was_called = False
 
-  Args:
-    files_to_zip: Dict mapping path in the zip archive to original source.
-    zip_path: Path where the zip file ends up, this is where the info file goes.
-  """
-  info_file_path = zip_path + '.info'
-  with open(info_file_path, 'w') as info_file:
-    for archive_path, source_path in files_to_zip.iteritems():
-      info_file.write('{},{}\n'.format(archive_path, source_path))
+  def AddMapping(self, archive_path, source_path):
+    """Adds a single |archive_path| -> |source_path| entry."""
+    self._add_mapping_was_called = True
+    # "values/" files do not end up in the apk except through resources.arsc.
+    if archive_path.startswith('values'):
+      return
+    source_path = os.path.normpath(source_path)
+    new_value = self._entries.setdefault(archive_path, source_path)
+    if new_value != source_path:
+      raise Exception('Duplicate AddMapping for "{}". old={} new={}'.format(
+          archive_path, new_value, source_path))
+
+  def RegisterRename(self, old_archive_path, new_archive_path):
+    """Records an archive_path rename.
+
+    |old_archive_path| does not need to currently exist in the mappings. Renames
+    are buffered and replayed only when Write() is called.
+    """
+    if not old_archive_path.startswith('values'):
+      self._renames.append((old_archive_path, new_archive_path))
+
+  def MergeInfoFile(self, info_file_path):
+    """Merges the mappings from |info_file_path| into this object.
+
+    Any existing entries are overridden.
+    """
+    assert not self._add_mapping_was_called
+    # Allows clobbering, which is used when overriding resources.
+    with open(info_file_path) as f:
+      self._entries.update(l.rstrip().split('\t') for l in f)
+
+  def _ApplyRenames(self):
+    applied_renames = set()
+    ret = self._entries
+    for rename_tup in self._renames:
+      # Duplicate entries happen for resource overrides.
+      # Use a "seen" set to ensure we still error out if multiple renames
+      # happen for the same old_archive_path with different new_archive_paths.
+      if rename_tup in applied_renames:
+        continue
+      applied_renames.add(rename_tup)
+      old_archive_path, new_archive_path = rename_tup
+      ret[new_archive_path] = ret[old_archive_path]
+      del ret[old_archive_path]
+
+    self._entries = None
+    self._renames = None
+    return ret
+
+  def Write(self, info_file_path):
+    """Applies renames and writes out the file.
+
+    No other methods may be called after this.
+    """
+    entries = self._ApplyRenames()
+    lines = []
+    for archive_path, source_path in entries.iteritems():
+      lines.append('{}\t{}\n'.format(archive_path, source_path))
+    with open(info_file_path, 'w') as info_file:
+      info_file.writelines(sorted(lines))
 
 
 def _ParseTextSymbolsFile(path, fix_package_ids=False):
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml
index 46375282..004b4e0 100644
--- a/build/android/lint/suppressions.xml
+++ b/build/android/lint/suppressions.xml
@@ -151,6 +151,8 @@
     <!-- see crbug.com/542435 -->
     <ignore regexp="android_webview/nonembedded/java/res"/>
     <ignore regexp="android_webview/tools/system_webview_shell/apk/res"/>
+    <!-- This is intentional to reduce APK size. See: http://crrev/c/1352161 -->
+    <ignore regexp="chrome/android/features/autofill_assistant/java/res"/>
     <ignore regexp="chrome/android/webapk/shell_apk/res"/>
     <ignore regexp="chromecast/internal"/>
     <!-- crbug.com/457918 is tracking missing assets -->
diff --git a/build/android/pylib/utils/device_dependencies.py b/build/android/pylib/utils/device_dependencies.py
index 99555dc..f20d3b3 100644
--- a/build/android/pylib/utils/device_dependencies.py
+++ b/build/android/pylib/utils/device_dependencies.py
@@ -34,6 +34,9 @@
     re.compile(r'.*llvm-symbolizer'),
     re.compile(r'.*md5sum_bin'),
     re.compile(os.path.join('.*', 'development', 'scripts', 'stack')),
+
+    # Required for java deobfuscation on the host:
+    re.compile(r'.*third_party/jdk/.*'),
 ]
 
 
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 927ab9fd..27638b33 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1451,7 +1451,6 @@
       test_suite = invoker.target_name
       test_type = "junit"
       ignore_all_data_deps = true
-      forward_variables_from(invoker, [ "android_manifest_path" ])
       resource_apk = _resource_arsc_output
     }
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 180113a2c3..c63e24b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1545,6 +1545,8 @@
           cflags += [
             # TODO(https://crbug.com/1031169): Clean up and enable.
             "-Wno-misleading-indentation",
+            # TODO(https://crbug.com/1035171): Clean up and enable.
+            "-Wno-enum-enum-conversion",
           ]
         }
       }
diff --git a/build/config/linux/libdrm/BUILD.gn b/build/config/linux/libdrm/BUILD.gn
index 05fb6a5c..def3c3f 100644
--- a/build/config/linux/libdrm/BUILD.gn
+++ b/build/config/linux/libdrm/BUILD.gn
@@ -7,12 +7,10 @@
 assert(is_linux)
 
 declare_args() {
-  # Controls whether the build should use the version of libdrm
-  # library shipped with the system. In release builds of Chrome OS we
-  # use the system version, but when building on dev workstations we
-  # bundle it because Ubuntu doesn't ship a usable version.
-  # Chromecast will use this as well.
-  use_system_libdrm = is_chromeos_device
+  # Controls whether the build should use the version of libdrm library shipped
+  # with the system. In release builds of desktop Linux and Chrome OS we use the
+  # system version. Chromecast will use this as well.
+  use_system_libdrm = is_chromeos_device || is_desktop_linux
 }
 
 if (use_system_libdrm) {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 1d91115..6b204b7 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8893885631337921504
\ No newline at end of file
+8893753533999477040
\ No newline at end of file
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index 0a89d07..f97ad871 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -171,11 +171,13 @@
   libcurl4-gnutls-dev
   libdrm-dev
   libelf-dev
+  libevdev-dev
   libffi-dev
   libgbm-dev
   libglib2.0-dev
   libglu1-mesa-dev
   libgtk-3-dev
+  libinput-dev
   libkrb5-dev
   libnspr4-dev
   libnss3-dev
@@ -238,12 +240,16 @@
   libcairo2
   libcap2
   libcups2
+  libdrm2
+  libevdev2
   libexpat1
   libffi6
   libfontconfig1
   libfreetype6
+  libgbm1
   libglib2.0-0
   libgtk-3-0
+  libinput10
   libpam0g
   libpango1.0-0
   libpci3
@@ -506,6 +512,12 @@
 if package_exists libgnome-keyring-dev; then
   lib_list="${lib_list} libgnome-keyring-dev"
 fi
+if package_exists libvulkan-dev; then
+    dev_list="${dev_list} libvulkan-dev"
+fi
+if package_exists libvulkan1; then
+    lib_list="${lib_list} libvulkan1"
+fi
 
 # Cross-toolchain strip is needed for building the sysroots.
 if package_exists binutils-arm-linux-gnueabihf; then
diff --git a/build/util/android_chrome_version.py b/build/util/android_chrome_version.py
index 91d31e97..e1ae3bfb 100644
--- a/build/util/android_chrome_version.py
+++ b/build/util/android_chrome_version.py
@@ -90,9 +90,6 @@
         ('WEBVIEW_STABLE', 'WEBVIEW_STABLE', '32_64'),
         ('WEBVIEW_BETA', 'WEBVIEW_BETA', '32_64'),
         ('WEBVIEW_DEV', 'WEBVIEW_DEV', '32_64'),
-        ('WEBVIEW_32_STABLE', 'WEBVIEW_STABLE', '32'),
-        ('WEBVIEW_32_BETA', 'WEBVIEW_BETA', '32'),
-        ('WEBVIEW_32_DEV', 'WEBVIEW_DEV', '32'),
     ]
 }
 
diff --git a/build/util/version.gni b/build/util/version.gni
index 90f79942..a4fff4d3 100644
--- a/build/util/version.gni
+++ b/build/util/version.gni
@@ -56,10 +56,7 @@
         "trichrome_32_version_code = \"@TRICHROME_32_VERSION_CODE@\" " +
         "trichrome_32_64_version_code = \"@TRICHROME_32_64_VERSION_CODE@\" " +
         "trichrome_64_32_version_code = \"@TRICHROME_64_32_VERSION_CODE@\" " +
-        "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" " +
-        "webview_32_stable_version_code = \"@WEBVIEW_32_STABLE_VERSION_CODE@\" " +
-        "webview_32_beta_version_code = \"@WEBVIEW_32_BETA_VERSION_CODE@\" " +
-        "webview_32_dev_version_code = \"@WEBVIEW_32_DEV_VERSION_CODE@\" "
+        "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" "
   }
 
   _script_arguments += [
@@ -122,9 +119,6 @@
                            "webview_beta_version_code",
                            "webview_dev_version_code",
                            "webview_stable_version_code",
-                           "webview_32_beta_version_code",
-                           "webview_32_dev_version_code",
-                           "webview_32_stable_version_code",
                          ])
 
   chrome_version_name = chrome_version_full
@@ -150,9 +144,6 @@
       "TrichromeChrome3264: $trichrome_32_64_version_code",
       "TrichromeChrome6432: $trichrome_64_32_version_code",
       "TrichromeChrome64: $trichrome_64_version_code",
-      "AndroidWebview32Stable: $webview_32_stable_version_code",
-      "AndroidWebview32Beta: $webview_32_beta_version_code",
-      "AndroidWebview32Dev: $webview_32_dev_version_code",
     ]
   }
 
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc
index 667545f..2a47a37 100644
--- a/cc/metrics/frame_sequence_tracker.cc
+++ b/cc/metrics/frame_sequence_tracker.cc
@@ -417,7 +417,7 @@
 FrameSequenceTracker::~FrameSequenceTracker() {
 }
 
-void FrameSequenceTracker::ReportMetrics() {
+void FrameSequenceTracker::ReportMetricsForTesting() {
   metrics_->ReportMetrics();
 }
 
@@ -470,8 +470,10 @@
                        << args.sequence_number << ")";
   UpdateTrackedFrameData(&begin_main_frame_data_, args.source_id,
                          args.sequence_number);
-  if (!first_received_main_sequence_)
+  if (!first_received_main_sequence_ ||
+      first_received_main_sequence_ <= last_no_main_damage_sequence_) {
     first_received_main_sequence_ = args.sequence_number;
+  }
   main_throughput().frames_expected +=
       begin_main_frame_data_.previous_sequence_delta;
 }
diff --git a/cc/metrics/frame_sequence_tracker.h b/cc/metrics/frame_sequence_tracker.h
index 085fc6a8..976e389 100644
--- a/cc/metrics/frame_sequence_tracker.h
+++ b/cc/metrics/frame_sequence_tracker.h
@@ -93,6 +93,7 @@
   void Merge(std::unique_ptr<FrameSequenceMetrics> metrics);
   bool HasEnoughDataForReporting() const;
   bool HasDataLeftForReporting() const;
+  // Report related metrics: throughput, checkboarding...
   void ReportMetrics();
 
   ThroughputData& impl_throughput() { return impl_throughput_; }
@@ -325,8 +326,7 @@
 
   bool ShouldIgnoreSequence(uint64_t sequence_number) const;
 
-  // Report related metrics: throughput, checkboarding...
-  void ReportMetrics();
+  void ReportMetricsForTesting();
 
   const FrameSequenceTrackerType type_;
 
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc
index 30b9234..f9a5a03 100644
--- a/cc/metrics/frame_sequence_tracker_unittest.cc
+++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -122,7 +122,7 @@
     // Test that there is no main thread frames expected.
     tracker_->impl_throughput().frames_expected = 100u;
     tracker_->impl_throughput().frames_produced = 85u;
-    tracker_->ReportMetrics();
+    tracker_->ReportMetricsForTesting();
     histogram_tester.ExpectTotalCount(
         "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 1u);
     histogram_tester.ExpectTotalCount(
@@ -135,7 +135,7 @@
     tracker_->impl_throughput().frames_produced = 85u;
     tracker_->main_throughput().frames_expected = 150u;
     tracker_->main_throughput().frames_produced = 25u;
-    tracker_->ReportMetrics();
+    tracker_->ReportMetricsForTesting();
     histogram_tester.ExpectTotalCount(
         "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u);
     histogram_tester.ExpectTotalCount(
@@ -148,7 +148,7 @@
     tracker_->main_throughput().frames_produced = 1u;
     tracker_->impl_throughput().frames_expected = 2u;
     tracker_->impl_throughput().frames_produced = 1u;
-    tracker_->ReportMetrics();
+    tracker_->ReportMetricsForTesting();
     histogram_tester.ExpectTotalCount(
         "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u);
     histogram_tester.ExpectTotalCount(
@@ -161,7 +161,7 @@
     tracker_->impl_throughput().frames_produced = 118u;
     tracker_->main_throughput().frames_expected = 120u;
     tracker_->main_throughput().frames_produced = 118u;
-    tracker_->ReportMetrics();
+    tracker_->ReportMetricsForTesting();
     histogram_tester.ExpectTotalCount(
         "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 3u);
     histogram_tester.ExpectTotalCount(
@@ -170,7 +170,7 @@
         "Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 3u);
   }
 
-  void ReportMetrics() { tracker_->ReportMetrics(); }
+  void ReportMetrics() { tracker_->ReportMetricsForTesting(); }
 
   base::TimeDelta TimeDeltaToReort() const {
     return tracker_->time_delta_to_report_;
diff --git a/cc/paint/discardable_image_map.cc b/cc/paint/discardable_image_map.cc
index 47b0c7b..3fc6eb8 100644
--- a/cc/paint/discardable_image_map.cc
+++ b/cc/paint/discardable_image_map.cc
@@ -90,8 +90,8 @@
     }
   }
 
-  bool all_images_are_srgb() const {
-    return color_stats_srgb_image_count_ == color_stats_total_image_count_;
+  bool contains_non_srgb_images() const {
+    return color_stats_srgb_image_count_ != color_stats_total_image_count_;
   }
 
  private:
@@ -421,7 +421,7 @@
   animated_images_metadata_ = generator.TakeAnimatedImagesMetadata();
   paint_worklet_inputs_ = generator.TakePaintWorkletInputs();
   decoding_mode_map_ = generator.TakeDecodingModeMap();
-  all_images_are_srgb_ = generator.all_images_are_srgb();
+  contains_non_srgb_images_ = generator.contains_non_srgb_images();
   auto images = generator.TakeImages();
   images_rtree_.Build(
       images,
diff --git a/cc/paint/discardable_image_map.h b/cc/paint/discardable_image_map.h
index a64ab29..5b282eff 100644
--- a/cc/paint/discardable_image_map.h
+++ b/cc/paint/discardable_image_map.h
@@ -59,7 +59,7 @@
   void GetDiscardableImagesInRect(const gfx::Rect& rect,
                                   std::vector<const DrawImage*>* images) const;
   const Rects& GetRectsForImage(PaintImage::Id image_id) const;
-  bool all_images_are_srgb() const { return all_images_are_srgb_; }
+  bool contains_non_srgb_images() const { return contains_non_srgb_images_; }
   const std::vector<AnimatedImageMetadata>& animated_images_metadata() const {
     return animated_images_metadata_;
   }
@@ -91,7 +91,7 @@
   base::flat_map<PaintImage::Id, Rects> image_id_to_rects_;
   std::vector<AnimatedImageMetadata> animated_images_metadata_;
   base::flat_map<PaintImage::Id, PaintImage::DecodingMode> decoding_mode_map_;
-  bool all_images_are_srgb_ = false;
+  bool contains_non_srgb_images_ = false;
 
   RTree<DrawImage> images_rtree_;
 
diff --git a/cc/paint/discardable_image_map_unittest.cc b/cc/paint/discardable_image_map_unittest.cc
index 23e9c99..3adf8824 100644
--- a/cc/paint/discardable_image_map_unittest.cc
+++ b/cc/paint/discardable_image_map_unittest.cc
@@ -1143,20 +1143,28 @@
 
   FakeContentLayerClient content_layer_client;
   content_layer_client.set_bounds(visible_rect.size());
-  content_layer_client.add_draw_image(discardable_image, gfx::Point(0, 0),
-                                      PaintFlags());
+
   scoped_refptr<DisplayItemList> display_list =
       content_layer_client.PaintContentsToDisplayList(
           ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
   display_list->GenerateDiscardableImagesMetadata();
   const DiscardableImageMap& image_map = display_list->discardable_image_map();
 
+  EXPECT_FALSE(image_map.contains_non_srgb_images());
+
+  content_layer_client.add_draw_image(discardable_image, gfx::Point(0, 0),
+                                      PaintFlags());
+  display_list = content_layer_client.PaintContentsToDisplayList(
+      ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
+  display_list->GenerateDiscardableImagesMetadata();
+  const DiscardableImageMap& image_map2 = display_list->discardable_image_map();
+
   if (!image_color_space.IsValid())
-    EXPECT_TRUE(image_map.all_images_are_srgb());
+    EXPECT_FALSE(image_map2.contains_non_srgb_images());
   else if (image_color_space == gfx::ColorSpace::CreateSRGB())
-    EXPECT_TRUE(image_map.all_images_are_srgb());
+    EXPECT_FALSE(image_map2.contains_non_srgb_images());
   else
-    EXPECT_FALSE(image_map.all_images_are_srgb());
+    EXPECT_TRUE(image_map2.contains_non_srgb_images());
 }
 
 gfx::ColorSpace test_color_spaces[] = {
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc
index 6093114..64a0d00 100644
--- a/cc/paint/paint_op_buffer_serializer.cc
+++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -274,25 +274,59 @@
     if (skip_op)
       continue;
 
-    if (op->GetType() != PaintOpType::DrawRecord) {
-      bool success = false;
-      if (op->IsPaintOpWithFlags()) {
-        success = SerializeOpWithFlags(static_cast<const PaintOpWithFlags*>(op),
-                                       &options, params, iter.alpha());
-      } else {
-        success = SerializeOp(op, options, params);
-      }
-
-      if (!success)
-        return;
+    if (op->GetType() == PaintOpType::DrawRecord) {
+      int save_count = text_blob_canvas_.getSaveCount();
+      Save(options, params);
+      SerializeBuffer(static_cast<const DrawRecordOp*>(op)->record.get(),
+                      nullptr);
+      RestoreToCount(save_count, options, params);
       continue;
     }
 
-    int save_count = text_blob_canvas_.getSaveCount();
-    Save(options, params);
-    SerializeBuffer(static_cast<const DrawRecordOp*>(op)->record.get(),
-                    nullptr);
-    RestoreToCount(save_count, options, params);
+    if (op->GetType() == PaintOpType::DrawImageRect &&
+        static_cast<const DrawImageRectOp*>(op)->image.IsPaintWorklet()) {
+      DCHECK(options.image_provider);
+      const DrawImageRectOp* draw_op = static_cast<const DrawImageRectOp*>(op);
+      ImageProvider::ScopedResult result =
+          options.image_provider->GetRasterContent(DrawImage(draw_op->image));
+      if (!result || !result.paint_record())
+        continue;
+
+      int save_count = text_blob_canvas_.getSaveCount();
+      Save(options, params);
+      // The following ops are copying the canvas's ops from
+      // DrawImageRectOp::RasterWithFlags.
+      SkMatrix trans = SkMatrix::MakeRectToRect(draw_op->src, draw_op->dst,
+                                                SkMatrix::kFill_ScaleToFit);
+      ConcatOp concat_op(trans);
+      bool success = SerializeOp(&concat_op, options, params);
+      if (!success)
+        return;
+      ClipRectOp clip_rect_op(draw_op->src, SkClipOp::kIntersect, false);
+      success = SerializeOp(&clip_rect_op, options, params);
+      if (!success)
+        return;
+      SaveLayerOp save_layer_op(&draw_op->src, options.flags_to_serialize);
+      success = SerializeOpWithFlags(&save_layer_op, &options, params, 255);
+      if (!success)
+        return;
+
+      SerializeBuffer(result.paint_record(), nullptr);
+      RestoreToCount(save_count, options, params);
+
+      continue;
+    }
+
+    bool success = false;
+    if (op->IsPaintOpWithFlags()) {
+      success = SerializeOpWithFlags(static_cast<const PaintOpWithFlags*>(op),
+                                     &options, params, iter.alpha());
+    } else {
+      success = SerializeOp(op, options, params);
+    }
+
+    if (!success)
+      return;
   }
 }
 
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc
index d9bf6fc9..1d4c732 100644
--- a/cc/paint/paint_op_writer.cc
+++ b/cc/paint/paint_op_writer.cc
@@ -363,9 +363,17 @@
   const auto& ctm = options_.canvas->getTotalMatrix();
 
   if (type == PaintShader::Type::kImage) {
-    return original->CreateDecodedImage(ctm, quality, options_.image_provider,
-                                        paint_image_transfer_cache_entry_id,
-                                        &quality, paint_image_needs_mips);
+    if (!original->paint_image().IsPaintWorklet()) {
+      return original->CreateDecodedImage(ctm, quality, options_.image_provider,
+                                          paint_image_transfer_cache_entry_id,
+                                          &quality, paint_image_needs_mips);
+    }
+    sk_sp<PaintShader> record_shader =
+        original->CreatePaintWorkletRecord(options_.image_provider);
+    if (!record_shader)
+      return nullptr;
+    return record_shader->CreateScaledPaintRecord(
+        ctm, options_.max_texture_size, paint_record_post_scale);
   }
 
   if (type == PaintShader::Type::kPaintRecord) {
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc
index b68e6130..e73d5da 100644
--- a/cc/paint/paint_shader.cc
+++ b/cc/paint/paint_shader.cc
@@ -339,6 +339,21 @@
   return shader;
 }
 
+sk_sp<PaintShader> PaintShader::CreatePaintWorkletRecord(
+    ImageProvider* image_provider) const {
+  DCHECK_EQ(shader_type_, Type::kImage);
+  DCHECK(image_ && image_.IsPaintWorklet());
+
+  ImageProvider::ScopedResult result =
+      image_provider->GetRasterContent(DrawImage(image_));
+  if (!result || !result.paint_record())
+    return nullptr;
+  SkMatrix local_matrix = GetLocalMatrix();
+  return PaintShader::MakePaintRecord(
+      sk_ref_sp<PaintRecord>(result.paint_record()), tile_, tx_, ty_,
+      &local_matrix);
+}
+
 sk_sp<PaintShader> PaintShader::CreateDecodedImage(
     const SkMatrix& ctm,
     SkFilterQuality quality,
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h
index 2ce5770..27b6554 100644
--- a/cc/paint/paint_shader.h
+++ b/cc/paint/paint_shader.h
@@ -205,6 +205,10 @@
                                         SkFilterQuality* raster_quality,
                                         bool* needs_mips) const;
 
+  // Creates a paint record shader for worklet-backed images.
+  sk_sp<PaintShader> CreatePaintWorkletRecord(
+      ImageProvider* image_provider) const;
+
   void SetColorsAndPositions(const SkColor* colors,
                              const SkScalar* positions,
                              int count);
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc
index 86bd980..eb5fd96 100644
--- a/cc/raster/raster_buffer_provider.cc
+++ b/cc/raster/raster_buffer_provider.cc
@@ -41,7 +41,7 @@
     case viz::RG_88:
     case viz::RGBX_8888:
     case viz::BGRX_8888:
-    case viz::RGBX_1010102:
+    case viz::RGBA_1010102:
     case viz::BGRX_1010102:
     case viz::YVU_420:
     case viz::YUV_420_BIPLANAR:
@@ -140,7 +140,7 @@
     case viz::RG_88:
     case viz::RGBX_8888:
     case viz::BGRX_8888:
-    case viz::RGBX_1010102:
+    case viz::RGBA_1010102:
     case viz::BGRX_1010102:
     case viz::YVU_420:
     case viz::YUV_420_BIPLANAR:
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 76108b9..6a560c6a 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -376,9 +376,11 @@
 }
 
 void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) {
-  if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME)
+  if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME &&
+      !begin_main_frame_sent_during_impl_) {
     begin_main_frame_sent_during_impl_ = true;
-  frame_trackers_.NotifyBeginMainFrame(args);
+    frame_trackers_.NotifyBeginMainFrame(args);
+  }
 }
 
 void LayerTreeHostImpl::BeginMainFrameAborted(
@@ -2307,6 +2309,14 @@
   // outside of begin-impl frame pipeline. Avoid notifying the trackers in such
   // cases.
   if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
+    if (!begin_main_frame_sent_during_impl_) {
+      frame_trackers_.NotifyBeginMainFrame(
+          current_begin_frame_tracker_.Current());
+      if (!begin_main_frame_expected_during_impl_) {
+        frame_trackers_.NotifyMainFrameCausedNoDamage(
+            current_begin_frame_tracker_.Current());
+      }
+    }
     frame_trackers_.NotifySubmitFrame(
         compositor_frame.metadata.frame_token, frame->has_missing_content,
         frame->begin_frame_ack, frame->origin_begin_main_frame_args);
@@ -2664,7 +2674,12 @@
   frame_trackers_.NotifyBeginImplFrame(args);
 
   begin_main_frame_expected_during_impl_ = client_->IsBeginMainFrameExpected();
-  begin_main_frame_sent_during_impl_ = false;
+  if (begin_main_frame_expected_during_impl_) {
+    begin_main_frame_sent_during_impl_ = true;
+    frame_trackers_.NotifyBeginMainFrame(args);
+  } else {
+    begin_main_frame_sent_during_impl_ = false;
+  }
 
   if (is_likely_to_require_a_draw_) {
     // Optimistically schedule a draw. This will let us expect the tile manager
@@ -2707,18 +2722,6 @@
 }
 
 void LayerTreeHostImpl::DidFinishImplFrame() {
-  if (!begin_main_frame_sent_during_impl_ &&
-      !begin_main_frame_expected_during_impl_) {
-    // A begin-main-frame was never dispatched for this BeginFrameArgs, and one
-    // was not expected to be dispatched either. So notify the trackers of the
-    // begin-main-frame, and not to expect any updates from it. This is
-    // necessary to make sure the trackers can correctly know which frames were
-    // not expected to produce any updates.
-    frame_trackers_.NotifyBeginMainFrame(
-        current_begin_frame_tracker_.Current());
-    frame_trackers_.NotifyMainFrameCausedNoDamage(
-        current_begin_frame_tracker_.Current());
-  }
   frame_trackers_.NotifyFrameEnd(current_begin_frame_tracker_.Current());
   impl_thread_phase_ = ImplThreadPhase::IDLE;
   current_begin_frame_tracker_.Finish();
@@ -2728,7 +2731,26 @@
                                            FrameSkippedReason reason) {
   if (layer_tree_frame_sink_)
     layer_tree_frame_sink_->DidNotProduceFrame(ack);
-  // TODO(sad): Notify |frame_trackers_| if |reason| is no-damage.
+
+  // If a frame was not submitted because there was no damage, then notify the
+  // trackers.
+  if (reason == FrameSkippedReason::kNoDamage &&
+      impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
+    // It is possible that |ack| is for a 'future frame', i.e. for the next
+    // frame from the one currently being handled by the compositor (represented
+    // by the BeginFrameArgs instance in |current_begin_frame_tracker_|). This
+    // can happen, for example, when a frame is skipped early for
+    // latency-recovery, while the previous frame is still being processed.
+    // Notify the trackers only when this is *not* the case (since the trackers
+    // are not notified about the start of the future frame either).
+    const auto& args = current_begin_frame_tracker_.Current();
+    if (args.source_id == ack.source_id &&
+        args.sequence_number == ack.sequence_number) {
+      frame_trackers_.NotifyImplFrameCausedNoDamage(ack);
+      if (begin_main_frame_sent_during_impl_)
+        frame_trackers_.NotifyMainFrameCausedNoDamage(args);
+    }
+  }
 }
 
 void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
@@ -3906,12 +3928,6 @@
   ScrollNode* scrolling_node = nullptr;
   bool scroll_on_main_thread = false;
 
-  // TODO(bokan): This appears Mac-specific - from
-  // https://codereview.chromium.org/2486673008 Suspect it is unnecessary - a
-  // fling should just produce GSUs without an intermediate GSB and GSE.
-  if (scroll_state->is_in_inertial_phase())
-    scrolling_node = CurrentlyScrollingNode();
-
   if (!scrolling_node) {
     ClearCurrentlyScrollingNode();
 
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 118fbff..679d340 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -1345,9 +1345,8 @@
   UIResourceId test_id1_;
 };
 
-// http://crbug.com/803532 : Flaky on Win 7 (dbg) and linux tsan
-#if (defined(NDEBUG) || !defined(OS_WIN)) && \
-    (!defined(THREAD_SANITIZER) || !defined(OS_LINUX))
+// http://crbug.com/803532 : Flaky on every bot
+#if 0
 SINGLE_THREAD_TEST_F(UIResourceLostBeforeCommit);
 #endif
 MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit);
diff --git a/chrome/DEPS b/chrome/DEPS
index 5998970..5124c2a 100644
--- a/chrome/DEPS
+++ b/chrome/DEPS
@@ -19,6 +19,7 @@
   "+chrome/common",
   "+chrome/test",
   "+components/content_settings/core/common",
+  "+components/embedder_support/switches.h",
   "+components/error_page/common",
   "+components/omnibox/common",
   "+components/services/heap_profiling/public",
diff --git a/chrome/VERSION b/chrome/VERSION
index c33e0c0..e8eac21 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=81
 MINOR=0
-BUILD=4000
+BUILD=4001
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 73245261..9bf0ec5e 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -688,6 +688,7 @@
     "//third_party/android_deps:androidx_annotation_annotation_java",
     "//third_party/android_deps:com_android_support_mediarouter_v7_java",
     "//third_party/android_deps:com_android_support_recyclerview_v7_java",
+    "//third_party/android_deps:com_googlecode_java_diff_utils_diffutils_java",
     "//third_party/android_sdk/androidx_browser:androidx_browser_java",
     "//third_party/blink/public:blink_headers_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
@@ -1041,11 +1042,12 @@
       ]
 
       deps = chrome_test_xr_java_deps + [
+               ":chrome_test_util_java",
                "//chrome/android:chrome_test_xr_java",
+               "//components/module_installer/android:module_installer_java",
                "//third_party/gvr-android-sdk:controller_test_api_java",
                "//third_party/gvr-android-sdk:gvr_common_java",
-               ":chrome_test_util_java",
-               "//components/module_installer/android:module_installer_java",
+               "//ui/android:ui_java_test_support",
              ]
 
       data = [
@@ -2842,6 +2844,7 @@
     "java/src/org/chromium/chrome/browser/send_tab_to_self/TargetDeviceInfo.java",
     "java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java",
     "java/src/org/chromium/chrome/browser/settings/LocationSettings.java",
+    "java/src/org/chromium/chrome/browser/settings/NfcSystemLevelSetting.java",
     "java/src/org/chromium/chrome/browser/settings/about/AboutSettingsBridge.java",
     "java/src/org/chromium/chrome/browser/settings/autofill/AutofillProfileBridge.java",
     "java/src/org/chromium/chrome/browser/settings/password/PasswordEditingBridge.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 8e5d15e4..787f1a9c 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -937,6 +937,7 @@
   "java/src/org/chromium/chrome/browser/nfc/BeamCallback.java",
   "java/src/org/chromium/chrome/browser/nfc/BeamController.java",
   "java/src/org/chromium/chrome/browser/nfc/BeamProvider.java",
+  "java/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPrompt.java",
   "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java",
   "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java",
   "java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java",
@@ -1358,6 +1359,7 @@
   "java/src/org/chromium/chrome/browser/settings/MainPreferences.java",
   "java/src/org/chromium/chrome/browser/settings/ManagedPreferenceDelegate.java",
   "java/src/org/chromium/chrome/browser/settings/ManagedPreferencesUtils.java",
+  "java/src/org/chromium/chrome/browser/settings/NfcSystemLevelSetting.java",
   "java/src/org/chromium/chrome/browser/settings/SearchUtils.java",
   "java/src/org/chromium/chrome/browser/settings/SeekBarPreference.java",
   "java/src/org/chromium/chrome/browser/settings/SettingsActivity.java",
@@ -1463,6 +1465,7 @@
   "java/src/org/chromium/chrome/browser/settings/website/LocalStorageInfo.java",
   "java/src/org/chromium/chrome/browser/settings/website/LocationCategory.java",
   "java/src/org/chromium/chrome/browser/settings/website/ManageSpaceActivity.java",
+  "java/src/org/chromium/chrome/browser/settings/website/NfcCategory.java",
   "java/src/org/chromium/chrome/browser/settings/website/NotificationCategory.java",
   "java/src/org/chromium/chrome/browser/settings/website/PermissionInfo.java",
   "java/src/org/chromium/chrome/browser/settings/website/SettingsNavigationSource.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index 77103d62..1c86fce8 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -113,6 +113,7 @@
   "junit/src/org/chromium/chrome/browser/metrics/VariationsSessionTest.java",
   "junit/src/org/chromium/chrome/browser/native_page/NativePageFactoryTest.java",
   "junit/src/org/chromium/chrome/browser/net/nqe/NetworkQualityProviderTest.java",
+  "junit/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPromptTest.java",
   "junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java",
   "junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java",
   "junit/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeUnitTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index aca70f5..b45ad5f0 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -47,6 +47,7 @@
   "javatests/src/org/chromium/chrome/browser/accessibility/FontSizePrefsTest.java",
   "javatests/src/org/chromium/chrome/browser/accessibility_tab_switcher/OverviewListLayoutTest.java",
   "javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java",
+  "javatests/src/org/chromium/chrome/browser/appmenu/OverviewAppMenuTest.java",
   "javatests/src/org/chromium/chrome/browser/appmenu/TabbedAppMenuTest.java",
   "javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java",
   "javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java",
@@ -102,6 +103,7 @@
   "javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java",
+  "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java",
@@ -234,7 +236,7 @@
   "javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowIntegrationTest.java",
   "javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowTestHelper.java",
   "javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtilsTest.java",
-  "javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java",
+  "javatests/src/org/chromium/chrome/browser/night_mode/ChromeNightModeTestUtils.java",
   "javatests/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilderTest.java",
   "javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java",
   "javatests/src/org/chromium/chrome/browser/notifications/NotificationBuilderBaseTest.java",
@@ -509,7 +511,6 @@
   "javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappAuthenticatorTest.java",
-  "javatests/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java",
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-hdpi/autofill_assistant_shadow_bg_image.9.png b/chrome/android/features/autofill_assistant/java/res/drawable-hdpi/autofill_assistant_shadow_bg_image.9.png
deleted file mode 100644
index c7c71213..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable-hdpi/autofill_assistant_shadow_bg_image.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-mdpi/autofill_assistant_shadow_bg_image.9.png b/chrome/android/features/autofill_assistant/java/res/drawable-mdpi/autofill_assistant_shadow_bg_image.9.png
deleted file mode 100644
index c448df6..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable-mdpi/autofill_assistant_shadow_bg_image.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml b/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml
similarity index 60%
copy from chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml
copy to chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml
index 98e8c47..769f51c6b 100644
--- a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml
+++ b/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml
@@ -5,8 +5,9 @@
 <shape
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
-    <corners
-        android:radius="12dp" />
-    <solid
-        android:color="@color/modern_secondary_color" />
+  <corners android:radius="8dp" />
+  <!-- TODO(b/146413939): Move to @color/default_chip_outline_color once available. -->
+  <stroke
+      android:color="@color/modern_grey_700"
+      android:width="1dp" />
 </shape>
\ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-xhdpi/autofill_assistant_shadow_bg_image.9.png b/chrome/android/features/autofill_assistant/java/res/drawable-xhdpi/autofill_assistant_shadow_bg_image.9.png
deleted file mode 100644
index 5bd2838..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable-xhdpi/autofill_assistant_shadow_bg_image.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-xxhdpi/autofill_assistant_shadow_bg_image.9.png b/chrome/android/features/autofill_assistant/java/res/drawable-xxhdpi/autofill_assistant_shadow_bg_image.9.png
deleted file mode 100644
index e4b37f9..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable-xxhdpi/autofill_assistant_shadow_bg_image.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-xxxhdpi/autofill_assistant_shadow_bg_image.9.png b/chrome/android/features/autofill_assistant/java/res/drawable-xxxhdpi/autofill_assistant_shadow_bg_image.9.png
deleted file mode 100644
index f5ccda67..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable-xxxhdpi/autofill_assistant_shadow_bg_image.9.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml b/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml
similarity index 60%
rename from chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml
rename to chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml
index 98e8c47..d0a7b640 100644
--- a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_shadow_bg.xml
+++ b/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml
@@ -5,8 +5,9 @@
 <shape
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
-    <corners
-        android:radius="12dp" />
-    <solid
-        android:color="@color/modern_secondary_color" />
+  <corners android:radius="8dp" />
+  <!-- TODO(b/146413939): Move to @color/default_chip_outline_color once available. -->
+  <stroke
+      android:color="@color/modern_grey_300"
+      android:width="1dp" />
 </shape>
\ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_shadow_bg.xml b/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_shadow_bg.xml
deleted file mode 100644
index 2a9ff6af..0000000
--- a/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_shadow_bg.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-<inset
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/autofill_assistant_shadow_bg_image"
-    android:insetTop="-60dp"
-    android:insetBottom="-68dp"
-    android:insetLeft="-40dp"
-    android:insetRight="-40dp"/>
\ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml
index 950007c..45531f0 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_details.xml
@@ -7,7 +7,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@drawable/autofill_assistant_shadow_bg"
+    android:background="@drawable/autofill_assistant_details_bg"
     android:padding="16dp"
     android:visibility="gone"
     android:orientation="vertical">
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml
index c73c8f3..e2ed31d 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml
@@ -34,17 +34,17 @@
             android:id="@+id/expand_label"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.BlackCaption"/>
+            android:textAppearance="@style/TextAppearance.BlueLink2"/>
         <TextView
             android:id="@+id/minimize_label"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.BlackCaption"/>
+            android:textAppearance="@style/TextAppearance.BlueLink2"/>
         <org.chromium.ui.widget.ChromeImageView
             android:id="@+id/chevron"
             android:layout_width="16dp"
             android:layout_height="16dp"
-            android:tint="@color/control_normal_color"
+            android:tint="@color/blue_when_enabled"
             app:srcCompat="@drawable/ic_expand_more_black_24dp"
             tools:ignore="ContentDescription"/>
     </LinearLayout>
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_divider.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_divider.xml
index 93d9cd73..890addc8 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_divider.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_divider.xml
@@ -3,9 +3,11 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
+<!-- TODO(b/144417635): Use @color/divider_line_bg_color once available. -->
 <View style="@style/HorizontalDivider"
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="1dp"
+      android:background="@color/divider_bg_color"
       android:layout_marginStart="@dimen/autofill_assistant_bottombar_horizontal_spacing"
       android:layout_marginEnd="@dimen/autofill_assistant_bottombar_horizontal_spacing"/>
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_title.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_title.xml
index cbf7b87..96f5c4b 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_title.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_section_title.xml
@@ -14,7 +14,7 @@
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
-              android:textAppearance="@style/TextAppearance.BlackTitle2"/>
+              android:textAppearance="@style/TextAppearance.AssistantBlackTitle"/>
 
     <Space android:layout_width="0dp"
            android:layout_height="0dp"
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_terms_and_conditions.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_terms_and_conditions.xml
index 505e1489..1dffe2d 100644
--- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_terms_and_conditions.xml
+++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_payment_request_terms_and_conditions.xml
@@ -31,5 +31,5 @@
         android:layout_marginEnd="@dimen/autofill_assistant_bottombar_horizontal_spacing"
         android:background="@drawable/autofill_assistant_lightblue_rect_bg"
         android:padding="8dp"
-        android:textAppearance="@style/TextAppearance.AssistantBlackCaption"/>
+        android:textAppearance="@style/TextAppearance.BlackCaption"/>
 </LinearLayout>
diff --git a/chrome/android/features/autofill_assistant/java/res/values-v17/styles.xml b/chrome/android/features/autofill_assistant/java/res/values-v17/styles.xml
index c8e24deb..bc27fc1 100644
--- a/chrome/android/features/autofill_assistant/java/res/values-v17/styles.xml
+++ b/chrome/android/features/autofill_assistant/java/res/values-v17/styles.xml
@@ -13,6 +13,7 @@
     <style name="TextAppearance.AssistantDetailsPrice" parent="TextAppearance.BlackBodyDefault">
         <item name="android:textStyle">bold</item>
     </style>
+    <!-- TODO(b/144149405): Move this to TextAppearance.BlackBodyDefault with @font/accent_font_medium. -->
     <style name="TextAppearance.AssistantBlackTitle" parent="TextAppearance.AccentMediumStyle">
         <item name="android:textColor">@color/default_text_color_list</item>
         <item name="android:textSize">@dimen/text_size_medium</item>
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java
index 227a7cf..0a7711a 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java
@@ -293,7 +293,7 @@
             return;
         }
 
-        IdentityServicesProvider.getIdentityManager().getAccessToken(
+        IdentityServicesProvider.get().getIdentityManager().getAccessToken(
                 mAccount, AUTH_TOKEN_TYPE, new IdentityManager.GetAccessTokenCallback() {
                     @Override
                     public void onGetTokenSuccess(String token) {
@@ -319,7 +319,7 @@
             return;
         }
 
-        IdentityServicesProvider.getIdentityManager().invalidateAccessToken(accessToken);
+        IdentityServicesProvider.get().getIdentityManager().invalidateAccessToken(accessToken);
     }
 
     /** Returns the e-mail address that corresponds to the access token or an empty string. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
index 92dd69b..b4b8f25 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
@@ -229,8 +229,9 @@
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.autofill_assistant_payment_request_choice_list_padding_end),
                 verticalPadding);
+        // TODO(b/144417635): Change to omnibox_bg_color once available.
         list.setBackgroundColor(ApiCompatibilityUtils.getColor(
-                mContext.getResources(), R.color.payments_section_edit_background));
+                mContext.getResources(), R.color.default_bg_color_elev_0));
         list.setTag(AssistantTagsForTesting.COLLECT_USER_DATA_CHOICE_LIST);
         if (addButtonText != null) {
             list.setOnAddButtonClickedListener(() -> createOrEditItem(null));
diff --git a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_eu.xtb b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_eu.xtb
index 740be69b..ec7e2f0 100644
--- a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_eu.xtb
+++ b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_eu.xtb
@@ -8,7 +8,9 @@
 <translation id="4437727785356380473">Itxi da Chrome-ko Google-ren Laguntzailea.</translation>
 <translation id="4517854969512651305">Handitu balioa</translation>
 <translation id="4850886885716139402">Ikusi</translation>
+<translation id="4952448020231702394">Google-ren Laguntzailea eginbideari esker, denbora aurreztuko duzu webguneko ekintzak bizkorrago eginda, hala nola bilaketak eta ordainketak.</translation>
 <translation id="5267269112080050255">Altuera osoan ireki da Chrome-ko Google-ren Laguntzailea.</translation>
+<translation id="6235816755461937614">Google-ren Laguntzailea eginbideak ahozko nahiz idatzizko kontsultak bidaltzen dizkio Chrome-ri. Gordeta duzun informazio pertsonal eta garrantzitsuarekin batera, webgunearen URLa eta edukia bidaliko ditu Chrome-k Google-ra. Kontsultaren arabera, helbide elektronikoa edo kreditu-txartel mota ere bidaliko dira. Aukera hori desaktibatzeko, joan Chrome-ren ezarpenetara. <ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /></translation>
 <translation id="6555233628095991027">Altuera erdian ireki da Chrome-ko Google-ren Laguntzailea.</translation>
 <translation id="6973932557599545801">Barkatu, ezin dizut lagundu. Egin aurrera zeuk bakarrik.</translation>
 <translation id="7658239707568436148">Utzi</translation>
diff --git a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_fr.xtb b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_fr.xtb
index a7bb409..d90bef02 100644
--- a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_fr.xtb
+++ b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_fr.xtb
@@ -8,9 +8,9 @@
 <translation id="4437727785356380473">L'Assistant Google dans Chrome est fermé.</translation>
 <translation id="4517854969512651305">Augmenter la valeur</translation>
 <translation id="4850886885716139402">Afficher</translation>
-<translation id="4952448020231702394">L'Assistant Google vous permet de finaliser des actions sur le Web (régler des achats ou effectuer une recherche, par exemple) et, ainsi, de gagner du temps.</translation>
+<translation id="4952448020231702394">L'Assistant Google vous permet d'effectuer des actions sur le Web (régler des achats ou effectuer une recherche, par exemple) et, ainsi, de gagner du temps.</translation>
 <translation id="5267269112080050255">L'Assistant Google dans Chrome est ouvert à hauteur maximale.</translation>
-<translation id="6235816755461937614">L'Assistant Google envoie les requêtes textuelles et vocales à Chrome. L'URL et le contenu du site sont envoyés à Google via Chrome, ainsi que les informations personnelles pertinentes. Selon la requête, il peut s'agir de l'adresse e-mail et du type de carte de crédit. Vous pouvez désactiver cette option dans les paramètres de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
+<translation id="6235816755461937614">L'Assistant Google envoie les requêtes textuelles et vocales à Chrome. L'URL et le contenu du site sont envoyés à Google via Chrome, de même que les informations personnelles pertinentes. Selon la requête, il peut s'agir de l'adresse e-mail et du type de carte de paiement. Vous pouvez désactiver cette option dans les paramètres de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
 <translation id="6555233628095991027">L'Assistant Google dans Chrome est ouvert à mi-hauteur.</translation>
 <translation id="6973932557599545801">Malheureusement, je ne peux pas vous aider. Veuillez continuer manuellement.</translation>
 <translation id="7658239707568436148">Annuler</translation>
diff --git a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_km.xtb b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_km.xtb
index f9663ea..2b28b34 100644
--- a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_km.xtb
+++ b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_km.xtb
@@ -8,7 +8,9 @@
 <translation id="4437727785356380473">បាន​បិទ Google ជំនួយការនៅក្នុង Chrome ។</translation>
 <translation id="4517854969512651305">បង្កើន​តម្លៃ</translation>
 <translation id="4850886885716139402">មើល</translation>
+<translation id="4952448020231702394">Google ជំនួយការ​ជួយសន្សំពេល​របស់អ្នក តាមរយៈ​ការជួយ​អ្នក​ក្នុងការ​បញ្ចប់​សកម្មភាព​ផ្សេងៗ​នៅលើ​បណ្ដាញដូចជា ​ការស្វែងរក និង​ការបង់ប្រាក់ចេញ​ជាដើម​។</translation>
 <translation id="5267269112080050255">Google ជំនួយការ​នៅក្នុង Chrome បាន​បើកក្នុងកម្ពស់ពេញ។</translation>
+<translation id="6235816755461937614">Google ជំនួយការ​ផ្ញើ​សំណួរ (អក្សរ និង​សំឡេង) ទៅ Chrome​។ Chrome នឹង​ផ្ញើ URL និង​ខ្លឹមសាររបស់​គេហទំព័រ​ ក៏ដូចជា​ព័ត៌មាន​ផ្ទាល់ខ្លួន​ដែល​ពាក់ព័ន្ធ​​ទៅ Google​។ សកម្មភាព​នេះ​ក៏អាច​រួមបញ្ចូល​ប្រភេទ​បណ្ណឥណទាន និង​អ៊ីមែល​ផងដែរ អាស្រ័យ​លើ​សំណួរ​។ អ្នក​អាច​បិទ​សកម្មភាព​នេះ​នៅក្នុង​ការកំណត់ Chrome​។ <ph name="BEGIN_LINK" />ស្វែងយល់​បន្ថែម<ph name="END_LINK" /></translation>
 <translation id="6555233628095991027">Google ជំនួយការ​នៅក្នុង Chrome បាន​បើកក្នុងកម្ពស់ពាក់កណ្ដាល។</translation>
 <translation id="6973932557599545801">សូមអភ័យទោស ខ្ញុំ​មិនអាច​ជួយបានទេ សូមបន្ត​ដោយ​ខ្លួនឯង។</translation>
 <translation id="7658239707568436148">បដិសេធ</translation>
diff --git a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_sq.xtb b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_sq.xtb
index ea59d87..20b56ca 100644
--- a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_sq.xtb
+++ b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_sq.xtb
@@ -8,7 +8,7 @@
 <translation id="4437727785356380473">"Asistenti i Google" në Chrome është i mbyllur.</translation>
 <translation id="4517854969512651305">Rrit vlerën</translation>
 <translation id="4850886885716139402">Pamja</translation>
-<translation id="4952448020231702394">"Asistenti i Google" të kursen kohë duke të ndihmuar të përfundon veprimet në ueb, si kërkimi dhe përfundimi i blerjes.</translation>
+<translation id="4952448020231702394">"Asistenti i Google" të kursen kohë duke të ndihmuar të përfundosh veprimet në ueb, si kërkimi dhe përfundimi i blerjes.</translation>
 <translation id="5267269112080050255">"Asistenti i Google" në Chrome është hapur në lartësi të plotë.</translation>
 <translation id="6235816755461937614">"Asistenti i Google" i dërgon Chrome kërkesa (me tekst dhe me zë). Chrome do të dërgojë te Google URL-në e sajtit, përmbajtjen e tij si edhe informacione të lidhura personale. Në varësi të kërkesës kjo mund të përfshijë email-in dhe llojin e kartës së kreditit. Këtë mund ta çaktivizosh te cilësimet e Chrome. <ph name="BEGIN_LINK" />Mëso më shumë<ph name="END_LINK" /></translation>
 <translation id="6555233628095991027">"Asistenti i Google" në Chrome është hapur në gjysmë lartësi.</translation>
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
index d9b1f03..109eec4 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
@@ -17,6 +17,7 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
+import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
@@ -33,6 +34,7 @@
 import static org.chromium.chrome.browser.autofill_assistant.AssistantTagsForTesting.COLLECT_USER_DATA_TERMS_REQUIRE_REVIEW;
 import static org.chromium.chrome.browser.autofill_assistant.AssistantTagsForTesting.VERTICAL_EXPANDER_CHEVRON;
 
+import android.support.test.espresso.matcher.ViewMatchers.Visibility;
 import android.support.test.filters.MediumTest;
 import android.view.View;
 import android.widget.TextView;
@@ -45,7 +47,6 @@
 
 import org.chromium.base.LocaleUtils;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.autofill_assistant.R;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.autofill.CardType;
@@ -558,7 +559,6 @@
      */
     @Test
     @MediumTest
-    @DisabledTest(message = "Flaky. crbug.com/1030217")
     public void testNonEmptyPaymentRequest() throws Exception {
         /* Add complete profile and credit card to the personal data manager. */
         PersonalDataManager.AutofillProfile profile =
@@ -621,20 +621,20 @@
         /* Non-empty sections should not be 'fixed', i.e., they can be expanded. */
         onView(allOf(withTagValue(is(VERTICAL_EXPANDER_CHEVRON)),
                        isDescendantOfA(is(viewHolder.mContactSection))))
-                .check(matches(isDisplayed()));
+                .check(matches(withEffectiveVisibility(Visibility.VISIBLE)));
         onView(allOf(withTagValue(is(VERTICAL_EXPANDER_CHEVRON)),
                        isDescendantOfA(is(viewHolder.mPaymentSection))))
-                .check(matches(isDisplayed()));
+                .check(matches(withEffectiveVisibility(Visibility.VISIBLE)));
         onView(allOf(withTagValue(is(VERTICAL_EXPANDER_CHEVRON)),
                        isDescendantOfA(is(viewHolder.mShippingSection))))
-                .check(matches(isDisplayed()));
+                .check(matches(withEffectiveVisibility(Visibility.VISIBLE)));
         onView(allOf(withTagValue(is(VERTICAL_EXPANDER_CHEVRON)),
                        isDescendantOfA(is(viewHolder.mLoginsSection))))
-                .check(matches(isDisplayed()));
+                .check(matches(withEffectiveVisibility(Visibility.VISIBLE)));
 
         /* All section dividers are visible. */
         for (View divider : viewHolder.mDividers) {
-            onView(is(divider)).check(matches(isDisplayed()));
+            onView(is(divider)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)));
         }
 
         /* Check contents of sections. */
diff --git a/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml b/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
index c140bd6..ed85e9d 100644
--- a/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
+++ b/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
@@ -29,10 +29,8 @@
         app:tabMode="fixed"
         app:tabMaxWidth="2000dp">
         <android.support.design.widget.TabItem
-            android:id="@+id/ss_home_tab"
             android:layout="@layout/ss_home_button"/>
         <android.support.design.widget.TabItem
-            android:id="@+id/ss_explore_tab"
             android:layout="@layout/ss_explore_button"/>
     </android.support.design.widget.TabLayout>
 </org.chromium.chrome.features.start_surface.BottomBarView>
\ No newline at end of file
diff --git a/chrome/android/features/start_surface/internal/java/res/layout/ss_explore_button.xml b/chrome/android/features/start_surface/internal/java/res/layout/ss_explore_button.xml
index 2deb5ac0..d29d83f 100644
--- a/chrome/android/features/start_surface/internal/java/res/layout/ss_explore_button.xml
+++ b/chrome/android/features/start_surface/internal/java/res/layout/ss_explore_button.xml
@@ -7,6 +7,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     style="@style/BottomToolbarButtonWrapper"
+    android:id="@+id/ss_explore_tab"
     android:background="@null"
     android:contentDescription="@string/accessibility_start_surface_bottom_explore_button" >
     <org.chromium.ui.widget.ChromeImageView
diff --git a/chrome/android/features/start_surface/internal/java/res/layout/ss_home_button.xml b/chrome/android/features/start_surface/internal/java/res/layout/ss_home_button.xml
index 5cf41e54..ec3f99f2 100644
--- a/chrome/android/features/start_surface/internal/java/res/layout/ss_home_button.xml
+++ b/chrome/android/features/start_surface/internal/java/res/layout/ss_home_button.xml
@@ -7,6 +7,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     style="@style/BottomToolbarButtonWrapper"
+    android:id="@+id/ss_home_tab"
     android:background="@null"
     android:contentDescription="@string/accessibility_start_surface_bottom_home_button" >
     <org.chromium.ui.widget.ChromeImageView
diff --git a/chrome/android/features/start_surface/internal/java/res/values/ids.xml b/chrome/android/features/start_surface/internal/java/res/values/ids.xml
new file mode 100644
index 0000000..5776a3a
--- /dev/null
+++ b/chrome/android/features/start_surface/internal/java/res/values/ids.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+
+<resources>
+    <item type="id" name="primary_tasks_surface_view" />
+    <item type="id" name="secondary_tasks_surface_view" />
+    <item type="id" name="start_surface_explore_view" />
+</resources>
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
index b0ff63f..e28b6875 100644
--- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
+++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -95,8 +95,10 @@
             sectionHeaderView =
                     (SectionHeaderView) inflater.inflate(R.layout.ss_feed_header, null, false);
         }
-        return new FeedSurfaceCoordinator(mActivity, null, null, null, sectionHeaderView,
-                exploreSurfaceActionHandler, isInNightMode, this);
+        FeedSurfaceCoordinator feedSurfaceCoordinator = new FeedSurfaceCoordinator(mActivity, null,
+                null, null, sectionHeaderView, exploreSurfaceActionHandler, isInNightMode, this);
+        feedSurfaceCoordinator.getView().setId(R.id.start_surface_explore_view);
+        return feedSurfaceCoordinator;
         // TODO(crbug.com/982018): Customize surface background for incognito and dark mode.
         // TODO(crbug.com/982018): Hide signin promo UI in incognito mode.
     }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
index 65eaa35..c932b06 100644
--- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
+++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
@@ -182,6 +182,7 @@
         mTasksSurface = TabManagementModuleProvider.getDelegate().createTasksSurface(mActivity,
                 mPropertyModel, mActivity.getToolbarManager().getFakeboxDelegate(),
                 mSurfaceMode == SurfaceMode.SINGLE_PANE);
+        mTasksSurface.getView().setId(R.id.primary_tasks_surface_view);
 
         mTasksSurfacePropertyModelChangeProcessor =
                 PropertyModelChangeProcessor.create(mPropertyModel,
@@ -214,6 +215,7 @@
         mSecondaryTasksSurface =
                 TabManagementModuleProvider.getDelegate().createTasksSurface(mActivity,
                         propertyModel, mActivity.getToolbarManager().getFakeboxDelegate(), false);
+        mSecondaryTasksSurface.getView().setId(R.id.secondary_tasks_surface_view);
         mSecondaryTasksSurfacePropertyModelChangeProcessor =
                 PropertyModelChangeProcessor.create(mPropertyModel,
                         new TasksSurfaceViewBinder.ViewHolder(mActivity.getCompositorViewHolder(),
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
index 10a48d0..ec22c62c 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -61,10 +61,10 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ApplicationTestUtils;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.MenuUtils;
 import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
@@ -106,7 +106,7 @@
     public TestRule mProcessor = new Features.InstrumentationProcessor();
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private StartSurfaceLayout mStartSurfaceLayout;
     private String mUrl;
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
new file mode 100644
index 0000000..811e49b6
--- /dev/null
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -0,0 +1,169 @@
+// 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.
+
+package org.chromium.chrome.features.start_surface;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.Espresso.pressBack;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.test.util.ViewUtils.waitForView;
+
+import android.support.test.filters.MediumTest;
+import android.view.ViewGroup;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.Restriction;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.flags.FeatureUtilities;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.UiRestriction;
+
+import java.util.concurrent.ExecutionException;
+
+/** Integration tests of the {@link StartSurface}. */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        "enable-features=" + ChromeFeatureList.START_SURFACE_ANDROID + "<Study",
+        "force-fieldtrials=Study/Group"})
+public class StartSurfaceTest {
+    private static final String BASE_PARAMS =
+            "force-fieldtrial-params=Study.Group:start_surface_variation";
+
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+
+    @Rule
+    public TestRule mProcessor = new Features.InstrumentationProcessor();
+
+    @Before
+    public void setUp() {
+        FeatureUtilities.setStartSurfaceEnabledForTesting(true);
+        mActivityTestRule.startMainActivityFromLauncher();
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"StartSurface"})
+    @CommandLineFlags.Add({BASE_PARAMS + "/tasksonly"})
+    public void testShowAndHideTasksOnlySurface() {
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
+        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+
+        onView(withId(org.chromium.chrome.start_surface.R.id.primary_tasks_surface_view))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
+                .check(matches(isDisplayed()));
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
+        assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"StartSurface"})
+    @CommandLineFlags.Add({BASE_PARAMS + "/single"})
+    public void testShowAndHideSingleSurface() {
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
+        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+
+        onView(withId(org.chromium.chrome.start_surface.R.id.primary_tasks_surface_view))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container))
+                .check(matches(isDisplayed()));
+
+        // Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
+        // percent of the view's area is displayed to the users. However, this view has negative
+        // margin which makes the percentage is less than 90.
+        // TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
+        try {
+            TestThreadUtils.runOnUiThreadBlocking(
+                    ()
+                            -> mActivityTestRule.getActivity()
+                                       .findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
+                                       .performClick());
+        } catch (ExecutionException e) {
+            assertTrue(false);
+        }
+        onView(isRoot()).check((r, e) -> {
+            waitForView((ViewGroup) r,
+                    withId(org.chromium.chrome.start_surface.R.id.secondary_tasks_surface_view));
+        });
+
+        pressBack();
+        onView(isRoot()).check((r, e) -> {
+            waitForView((ViewGroup) r,
+                    withId(org.chromium.chrome.start_surface.R.id.primary_tasks_surface_view));
+        });
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
+        assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"StartSurface"})
+    @CommandLineFlags.Add({BASE_PARAMS + "/twopanes"})
+    public void testShowAndHideTwoPanesSurface() {
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
+        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+
+        onView(withId(org.chromium.chrome.start_surface.R.id.primary_tasks_surface_view))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.start_surface.R.id.ss_bottom_bar))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
+                .check(matches(isDisplayed()));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
+                .check(matches(isDisplayed()));
+
+        onView(withId(org.chromium.chrome.start_surface.R.id.ss_explore_tab)).perform(click());
+        onView(isRoot()).check((r, e) -> {
+            waitForView((ViewGroup) r,
+                    withId(org.chromium.chrome.start_surface.R.id.start_surface_explore_view));
+        });
+
+        pressBack();
+        onView(isRoot()).check((r, e) -> {
+            waitForView((ViewGroup) r,
+                    withId(org.chromium.chrome.start_surface.R.id.primary_tasks_surface_view));
+        });
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
+        assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+    }
+}
+
+// TODO(crbug.com/1033909): Add more integration tests.
diff --git a/chrome/android/features/start_surface/internal/javatests/start_surface_test_java_sources.gni b/chrome/android/features/start_surface/internal/javatests/start_surface_test_java_sources.gni
index 7b32bb2..df6c744 100644
--- a/chrome/android/features/start_surface/internal/javatests/start_surface_test_java_sources.gni
+++ b/chrome/android/features/start_surface/internal/javatests/start_surface_test_java_sources.gni
@@ -8,5 +8,6 @@
   "//chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderTest.java",
   "//chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java",
   "//chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java",
+  "//chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java",
   "//chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderTest.java",
 ]
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiCoordinator.java
index 100f350..3071edf7 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiCoordinator.java
@@ -11,16 +11,23 @@
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ThemeColorProvider;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 
 /**
  * A coordinator for TabStrip component as a popup window in bottom toolbar.
  */
-public class TabGroupPopupUiCoordinator implements TabGroupPopupUi, Destroyable {
+public class TabGroupPopupUiCoordinator
+        implements TabGroupPopupUi, Destroyable, TabGroupPopupUiMediator.TabGroupPopUiUpdater {
     private final ThemeColorProvider mThemeColorProvider;
     private final ObservableSupplier<View> mAnchorViewSupplier;
     private final Callback<View> mAnchorViewSupplierCallback;
 
-    private ChromeActivity mActivity;
+    private PropertyModelChangeProcessor mModelChangeProcessor;
+    private View mAnchorView;
+    private TabGroupUiCoordinator mTabGroupUiCoordinator;
+    private TabGroupPopupUiMediator mMediator;
+    private TabGroupPopupUiParent mTabGroupPopupUiParent;
 
     TabGroupPopupUiCoordinator(
             ThemeColorProvider themeColorProvider, ObservableSupplier<View> parentViewSupplier) {
@@ -30,22 +37,59 @@
         mAnchorViewSupplier.addObserver(mAnchorViewSupplierCallback);
     }
 
+    // TabGroupPopUi implementation.
     @Override
     // TODO(crbug.com/1022827): Narrow down the dependencies required here and in
     // TabGroupUiCoordinator instead of passing in ChromeActivity.
     public void initializeWithNative(ChromeActivity activity) {
-        mActivity = activity;
+        PropertyModel model = new PropertyModel(TabGroupPopupUiProperties.ALL_KEYS);
+        mTabGroupPopupUiParent = new TabGroupPopupUiParent(activity, mAnchorView);
+        mTabGroupUiCoordinator = new TabGroupUiCoordinator(
+                mTabGroupPopupUiParent.getCurrentContainerView(), mThemeColorProvider);
+        mTabGroupUiCoordinator.initializeWithNative(activity, null);
+        mModelChangeProcessor = PropertyModelChangeProcessor.create(
+                model, mTabGroupPopupUiParent, TabGroupPopupUiViewBinder::bind);
+        mMediator = new TabGroupPopupUiMediator(model, activity.getTabModelSelector(),
+                activity.getOverviewModeBehavior(), activity.getFullscreenManager(), this,
+                mTabGroupUiCoordinator);
+        mMediator.onAnchorViewChanged(mAnchorView, mAnchorView.getId());
     }
 
-    private void onAnchorViewChanged(View v) {}
-
     @Override
     public View.OnLongClickListener getLongClickListenerForTriggering() {
-        return v -> true;
+        return v -> {
+            mMediator.maybeShowTabStrip();
+            return true;
+        };
     }
 
+    /**
+     * Destroy any members that needs clean up.
+     */
     @Override
     public void destroy() {
+        if (mMediator != null) {
+            mMediator.destroy();
+        }
+        if (mModelChangeProcessor != null) {
+            mModelChangeProcessor.destroy();
+        }
+        if (mTabGroupUiCoordinator != null) {
+            mTabGroupUiCoordinator.destroy();
+        }
         mAnchorViewSupplier.removeObserver(mAnchorViewSupplierCallback);
     }
+
+    // TabGroupPopUiUpdater implementation.
+    @Override
+    public void updateTabGroupPopUi() {
+        mTabGroupPopupUiParent.updateStripWindow();
+    }
+
+    private void onAnchorViewChanged(View anchorView) {
+        if (mAnchorView == anchorView) return;
+        mAnchorView = anchorView;
+        if (mMediator == null) return;
+        mMediator.onAnchorViewChanged(anchorView, anchorView.getId());
+    }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
index b020ef98..62f49fd 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -199,11 +199,4 @@
     public void setupLeftButtonOnClickListener(View.OnClickListener listener) {
         mMediator.setupLeftButtonOnClickListener(listener);
     }
-
-    /**
-     * @return {@link TabGroupUiMediator.TabGroupUiController} to control the TabGroupUi.
-     */
-    TabGroupUiMediator.TabGroupUiController getTabGroupUiController() {
-        return this;
-    }
 }
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
index fa9b19e8..b091134 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Verwyder</translation>
 <translation id="125153950246128346">Tik om nog 'n oortjie te sien</translation>
 <translation id="1657719826150349398">Skuif oortjie ondertoe</translation>
-<translation id="1778290789805128794">Skuif oortjie boontoe</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> oortjie}other{<ph name="TABS_COUNT_MANY" /> oortjies}}</translation>
 <translation id="2569352796411618312">Voorstel: <ph name="NUMBER_OF_TABS" /> van jou oortjies is nie onlangs gebruik nie. Maak hulle toe?</translation>
 <translation id="257674075312929031">Groep</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
index 60597cf..77c4936 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">አስወግድ</translation>
 <translation id="125153950246128346">ሌላ ትር ለመመልከት መታ ያድርጉ</translation>
 <translation id="1657719826150349398">ትርን ወደ ታች ያንቀሳቅሱ</translation>
-<translation id="1778290789805128794">ትርን ወደ ላይ አንቀሳቅስ</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ትር}one{<ph name="TABS_COUNT_MANY" /> ትሮች}other{<ph name="TABS_COUNT_MANY" /> ትሮች}}</translation>
 <translation id="2569352796411618312">ጥቆማ ሐሳብ፦ ከእርስዎ ትሮች <ph name="NUMBER_OF_TABS" /> ያክሉ በቅርቡ ጥቅም ላይ አልዋሉም። ይዘጉ?</translation>
 <translation id="257674075312929031">ቡድን</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
index a53eb1e..ef64772 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">إزالة</translation>
 <translation id="125153950246128346">يُرجى النقر للاطِّلاع على علامة تبويب أخرى</translation>
 <translation id="1657719826150349398">نقل علامة التبويب إلى أعلى الصفحة</translation>
-<translation id="1778290789805128794">نقل علامة التبويب إلى أعلى الصفحة</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{علامة تبويب واحدة (<ph name="TABS_COUNT_ONE" />)}zero{<ph name="TABS_COUNT_MANY" /> علامة تبويب}two{علامتا تبويب (<ph name="TABS_COUNT_MANY" />)}few{<ph name="TABS_COUNT_MANY" /> علامات تبويب}many{<ph name="TABS_COUNT_MANY" /> علامة تبويب}other{<ph name="TABS_COUNT_MANY" /> علامة تبويب}}</translation>
 <translation id="2569352796411618312">اقتراح: لم يتم استخدام <ph name="NUMBER_OF_TABS" /> من علامات التبويب مؤخرًا. هل تريد إغلاقها؟</translation>
 <translation id="257674075312929031">مجموعة</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
index 3946ad4..69639a0 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Silin</translation>
 <translation id="125153950246128346">Başqa taba baxmaq üçün klikləyin</translation>
 <translation id="1657719826150349398">Tabı aşağıya daşıyın</translation>
-<translation id="1778290789805128794">Tabı yuxarıya daşıyın</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}other{<ph name="TABS_COUNT_MANY" /> tab}}</translation>
 <translation id="2569352796411618312">Təklif: <ph name="NUMBER_OF_TABS" /> tabel bu yaxınlarda istifadə edilməyib. Bağlansınlar?</translation>
 <translation id="257674075312929031">Qrup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
index b872228..12e339a 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Выдаліць</translation>
 <translation id="125153950246128346">Націсніце, каб паглядзець іншую ўкладку</translation>
 <translation id="1657719826150349398">Перамясціць укладку ніжэй</translation>
-<translation id="1778290789805128794">Перамясціць укладку ўверх</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> укладка}one{<ph name="TABS_COUNT_MANY" /> укладка}few{<ph name="TABS_COUNT_MANY" /> укладкі}many{<ph name="TABS_COUNT_MANY" /> укладак}other{<ph name="TABS_COUNT_MANY" /> укладкі}}</translation>
 <translation id="2569352796411618312">Прапанова: некалькі (<ph name="NUMBER_OF_TABS" />) укладак пэўны час не выкарыстоўваліся. Закрыць іх?</translation>
 <translation id="257674075312929031">Група</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
index 5f64707..98b5f9d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Премахване</translation>
 <translation id="125153950246128346">Докоснете, за да видите друг раздел</translation>
 <translation id="1657719826150349398">Преместване на раздела надолу</translation>
-<translation id="1778290789805128794">Преместване на раздела най-горе</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> раздел}other{<ph name="TABS_COUNT_MANY" /> раздела}}</translation>
 <translation id="2569352796411618312">Предложение: <ph name="NUMBER_OF_TABS" /> от разделите ви не са използвани наскоро. Искате ли да ги затворите?</translation>
 <translation id="257674075312929031">Група</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
index 33be919..a44ae27 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">সরান</translation>
 <translation id="125153950246128346">অন্য ট্যাব দেখতে ট্যাপ করুন</translation>
 <translation id="1657719826150349398">ট্যাব নিচে সরান</translation>
-<translation id="1778290789805128794">ট্যাবটি উপরে সরান</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" />টি ট্যাব}one{<ph name="TABS_COUNT_MANY" />টি ট্যাব}other{<ph name="TABS_COUNT_MANY" />টি ট্যাব}}</translation>
 <translation id="2569352796411618312">সাজেশন: সব ট্যাবের মধ্যে থেকে <ph name="NUMBER_OF_TABS" />টি ট্যাব সম্প্রতি ব্যবহার করা হয়নি। সেগুলি বন্ধ করে দিতে চান?</translation>
 <translation id="257674075312929031">গ্রুপ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
index 16c76f5..87e105b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Ukloni</translation>
 <translation id="125153950246128346">Dodirnite da vidite drugu karticu</translation>
 <translation id="1657719826150349398">Pomjeranje kartice nadolje</translation>
-<translation id="1778290789805128794">Pomjeranje kartice na vrh</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> kartica}one{<ph name="TABS_COUNT_MANY" /> kartica}few{<ph name="TABS_COUNT_MANY" /> kartice}other{<ph name="TABS_COUNT_MANY" /> kartica}}</translation>
 <translation id="2569352796411618312">Prijedlog: U zadnje vrijeme niste koristili sljedeći broj kartica: <ph name="NUMBER_OF_TABS" />. Zatvoriti ih?</translation>
 <translation id="257674075312929031">Grupa</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
index 0a936f2..428f44c 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Suprimeix</translation>
 <translation id="125153950246128346">Toca per veure una altra pestanya</translation>
 <translation id="1657719826150349398">Mou la pestanya cap avall</translation>
-<translation id="1778290789805128794">Mou la pestanya cap amunt</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> pestanya}other{<ph name="TABS_COUNT_MANY" /> pestanyes}}</translation>
 <translation id="2569352796411618312">Suggeriment: <ph name="NUMBER_OF_TABS" /> de les teves pestanyes no s'han utilitzat últimament. Vols tancar-les?</translation>
 <translation id="257674075312929031">Grup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
index 32cebae6..cb86198 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Odebrat</translation>
 <translation id="125153950246128346">Další kartu zobrazíte klepnutím</translation>
 <translation id="1657719826150349398">Přesunout kartu dolů</translation>
-<translation id="1778290789805128794">Přesunout kartu nahoru</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> karta}few{<ph name="TABS_COUNT_MANY" /> karty}many{<ph name="TABS_COUNT_MANY" /> karty}other{<ph name="TABS_COUNT_MANY" /> karet}}</translation>
 <translation id="2569352796411618312">Tento počet vašich karet v poslední době nebyl použit: <ph name="NUMBER_OF_TABS" />. Chcete je zavřít?</translation>
 <translation id="257674075312929031">Skupina</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
index 0b1160e..2246b65 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Fjern</translation>
 <translation id="125153950246128346">Tryk for at se en anden fane</translation>
 <translation id="1657719826150349398">Flyt fane ned</translation>
-<translation id="1778290789805128794">Flyt fane til toppen</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> fane}one{<ph name="TABS_COUNT_MANY" /> fane}other{<ph name="TABS_COUNT_MANY" /> faner}}</translation>
 <translation id="2569352796411618312">Forslag: <ph name="NUMBER_OF_TABS" /> af dine faner er ikke blevet brugt for nylig. Vil du lukke dem?</translation>
 <translation id="257674075312929031">Gruppe</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
index fc3a52e..30d2991 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Entfernen</translation>
 <translation id="125153950246128346">Tippen, um einen anderen Tab zu sehen</translation>
 <translation id="1657719826150349398">Tab nach unten verschieben</translation>
-<translation id="1778290789805128794">Tab nach oben verschieben</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> Tab}other{<ph name="TABS_COUNT_MANY" /> Tabs}}</translation>
 <translation id="2569352796411618312">Vorschlag: <ph name="NUMBER_OF_TABS" /> von Ihren Tabs wurden längere Zeit nicht verwendet. Möchten Sie sie schließen?</translation>
 <translation id="257674075312929031">Gruppe</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
index f0c6de8..9d1f4eb 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Κατάργηση</translation>
 <translation id="125153950246128346">Πατήστε για να δείτε μια άλλη καρτέλα</translation>
 <translation id="1657719826150349398">Μετακίνηση καρτέλας κάτω</translation>
-<translation id="1778290789805128794">Μετακίνηση καρτέλας επάνω</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> καρτέλα}other{<ph name="TABS_COUNT_MANY" /> καρτέλες}}</translation>
 <translation id="2569352796411618312">Πρόταση: <ph name="NUMBER_OF_TABS" /> από τις καρτέλες σας δεν έχουν χρησιμοποιηθεί πρόσφατα. Κλείσιμο αυτών των καρτελών;</translation>
 <translation id="257674075312929031">Ομάδα</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
index ef2ed37..240e5835 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Remove</translation>
 <translation id="125153950246128346">Tap to see another tab</translation>
 <translation id="1657719826150349398">Move tab down</translation>
-<translation id="1778290789805128794">Move tab top</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}other{<ph name="TABS_COUNT_MANY" /> tabs}}</translation>
 <translation id="2569352796411618312">Suggestion: <ph name="NUMBER_OF_TABS" /> of your tabs haven't been used lately. Close them?</translation>
 <translation id="257674075312929031">Group</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
index 19c9e392..dcde3fe0 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Quitar</translation>
 <translation id="125153950246128346">Presiona para ver otra pestaña</translation>
 <translation id="1657719826150349398">Mover la pestaña hacia abajo</translation>
-<translation id="1778290789805128794">Mover la pestaña hacia arriba</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> pestaña}other{<ph name="TABS_COUNT_MANY" /> pestañas}}</translation>
 <translation id="2569352796411618312">Sugerencia: Últimamente no usaste <ph name="NUMBER_OF_TABS" /> de tus pestañas. ¿Quieres cerrarlas?</translation>
 <translation id="257674075312929031">Grupo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
index 3017ec4c..b672870 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Quitar</translation>
 <translation id="125153950246128346">Pulsa para ver otra pestaña</translation>
 <translation id="1657719826150349398">Bajar pestaña</translation>
-<translation id="1778290789805128794">Subir pestaña</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> pestaña}other{<ph name="TABS_COUNT_MANY" /> pestañas}}</translation>
 <translation id="2569352796411618312">Sugerencia: <ph name="NUMBER_OF_TABS" /> de las pestañas no se han usado recientemente. ¿Quieres cerrarlas?</translation>
 <translation id="257674075312929031">Grupo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
index 0ed8e38..bf240b5 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Eemalda</translation>
 <translation id="125153950246128346">Puudutage muu vahelehe vaatamiseks</translation>
 <translation id="1657719826150349398">Teisalda vaheleht alla</translation>
-<translation id="1778290789805128794">Teisalda vaheleht üles</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> vaheleht}other{<ph name="TABS_COUNT_MANY" /> vahelehte}}</translation>
 <translation id="2569352796411618312">Soovitus: <ph name="NUMBER_OF_TABS" /> vahelehte pole hiljuti kasutatud. Kas sulgeda need?</translation>
 <translation id="257674075312929031">Rühm</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
index 9068625..a34ceabf 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
@@ -4,6 +4,7 @@
 <translation id="1075622780330595106">Fitxetako <ph name="NUMBER_OF_TABS" /> ez dira erabili azkenaldian. Itxi nahi dituzu?</translation>
 <translation id="1181037720776840403">Kendu</translation>
 <translation id="125153950246128346">Sakatu hau beste fitxa bat ikusteko</translation>
+<translation id="1657719826150349398">Eraman fitxa behera</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> fitxa}other{<ph name="TABS_COUNT_MANY" /> fitxa}}</translation>
 <translation id="2569352796411618312">Iradokizuna: fitxetako <ph name="NUMBER_OF_TABS" /> ez dira erabili azkenaldian. Itxi nahi dituzu?</translation>
 <translation id="257674075312929031">Taldea</translation>
@@ -20,11 +21,13 @@
 <translation id="58326064309361797">Fitxak taldekatzeko, arrasta itzazu</translation>
 <translation id="6040143037577758943">Itxi</translation>
 <translation id="6193448654517602979">Hautatu fitxak</translation>
+<translation id="6562820390860419811">Eraman fitxa ezkerrera</translation>
 <translation id="6615455863669487791">Erakuts iezadazu</translation>
 <translation id="6840760312327750441">Fitxak taldekatzeko, eduki fitxa bat sakatuta eta, ondoren, arrasta ezazu beste batera.</translation>
 <translation id="7151209024774799310">Kendu fitxak taldetik</translation>
 <translation id="7559245342362162951">Erakutsi taldearen fitxak pantaila osoko saretan</translation>
 <translation id="7792771145871471484">Berrikusi iradokizunak.</translation>
+<translation id="7885132941432959125">Eraman fitxa eskuinera</translation>
 <translation id="7966321538264951561">Baztertu iradokizunak.</translation>
 <translation id="83556505225171773">{TABS_COUNT,plural, =1{Itxi hautatutako <ph name="TABS_COUNT_ONE" /> fitxa}other{Itxi hautatutako <ph name="TABS_COUNT_MANY" /> fitxa}}</translation>
 <translation id="9150694013019234766">Fitxa batetik bestera joateko, erabili pantailaren behealdean dagoen fitxa taldea</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
index 0efbe80..b2d5626 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">حذف</translation>
 <translation id="125153950246128346">برای دیدن برگه دیگر ضربه بزنید</translation>
 <translation id="1657719826150349398">انتقال برگه به پایین</translation>
-<translation id="1778290789805128794">انتقال برگه به بالا</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> برگه}one{<ph name="TABS_COUNT_MANY" /> برگه}other{<ph name="TABS_COUNT_MANY" /> برگه}}</translation>
 <translation id="2569352796411618312">پیشنهاد: <ph name="NUMBER_OF_TABS" /> مورد از برگه‌هایتان اخیراً استفاده نشده‌اند. آن‌ها را می‌بندید؟</translation>
 <translation id="257674075312929031">گروه</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
index cd53d37..384497f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Poista</translation>
 <translation id="125153950246128346">Näytä toinen välilehti napauttamalla</translation>
 <translation id="1657719826150349398">Siirrä välilehti alaspäin</translation>
-<translation id="1778290789805128794">Siirrä välilehti ylimmäksi</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> välilehti}other{<ph name="TABS_COUNT_MANY" /> välilehteä}}</translation>
 <translation id="2569352796411618312">Ehdotus: <ph name="NUMBER_OF_TABS" /> välilehteä ei ole käytetty vähään aikaan. Suljetaanko ne?</translation>
 <translation id="257674075312929031">Ryhmä</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
index 42f97ea..9aac7791 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Alisin</translation>
 <translation id="125153950246128346">I-tap para tumingin ng iba pang tab</translation>
 <translation id="1657719826150349398">Ilipat ang tab sa ibaba</translation>
-<translation id="1778290789805128794">Ilipat ang tab sa itaas</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}one{<ph name="TABS_COUNT_MANY" /> tab}other{<ph name="TABS_COUNT_MANY" /> na tab}}</translation>
 <translation id="2569352796411618312">Suhestyon: <ph name="NUMBER_OF_TABS" /> sa iyong mga tab ang hindi nagamit nitong nakaraan. Isara ang mga ito?</translation>
 <translation id="257674075312929031">Pangkat</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
index 4458963d..18e26ad 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Supprimer</translation>
 <translation id="125153950246128346">Touchez pour afficher un autre onglet</translation>
 <translation id="1657719826150349398">Déplacer l'onglet vers le bas</translation>
-<translation id="1778290789805128794">Déplacer l'onglet vers le haut</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> onglet}one{<ph name="TABS_COUNT_MANY" /> onglet}other{<ph name="TABS_COUNT_MANY" /> onglets}}</translation>
 <translation id="2569352796411618312">Suggestion : <ph name="NUMBER_OF_TABS" /> de vos onglets n'ont pas été utilisés récemment. Les fermer?</translation>
 <translation id="257674075312929031">Groupe</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
index 386357d..91f8367 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Supprimer</translation>
 <translation id="125153950246128346">Appuyer pour afficher un autre onglet</translation>
 <translation id="1657719826150349398">Déplacer l'onglet vers le bas</translation>
-<translation id="1778290789805128794">Déplacer l'onglet vers le haut</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> onglet}one{<ph name="TABS_COUNT_MANY" /> onglet}other{<ph name="TABS_COUNT_MANY" /> onglets}}</translation>
 <translation id="2569352796411618312">Suggestion : <ph name="NUMBER_OF_TABS" /> des onglets ouverts n'ont pas été utilisés récemment. Voulez-vous les fermer ?</translation>
 <translation id="257674075312929031">Groupe</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
index aa69490f..105f8feb 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
@@ -5,9 +5,8 @@
 <translation id="1181037720776840403">Eliminar</translation>
 <translation id="125153950246128346">Toca para ver outra pestana</translation>
 <translation id="1657719826150349398">Mover pestana cara abaixo</translation>
-<translation id="1778290789805128794">Mover pestana cara arriba</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> pestana}other{<ph name="TABS_COUNT_MANY" /> pestanas}}</translation>
-<translation id="2569352796411618312">Suxestión: <ph name="NUMBER_OF_TABS" /> das pestanas que tes abertas leva/n sen utilizarse un bo anaco. Queres pechala/s?</translation>
+<translation id="2569352796411618312">Suxestión: <ph name="NUMBER_OF_TABS" /> das pestanas que tes abertas levan sen utilizarse un bo anaco. Queres pechalas?</translation>
 <translation id="257674075312929031">Grupo</translation>
 <translation id="2613747923081026172">Crear grupo</translation>
 <translation id="2671423594960767771">Compartir grupo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
index 2542f0b..0fd15ef 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">કાઢી નાખો</translation>
 <translation id="125153950246128346">અન્ય ટૅબ જોવા માટે ટૅપ કરો</translation>
 <translation id="1657719826150349398">ટૅબને નીચે ખસેડો</translation>
-<translation id="1778290789805128794">ટૅબને ટોચે ખસેડો</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ટૅબ}one{<ph name="TABS_COUNT_MANY" /> ટૅબ}other{<ph name="TABS_COUNT_MANY" /> ટૅબ}}</translation>
 <translation id="2569352796411618312">સૂચન: હજુ સુધી તમારા ટૅબમાંથી <ph name="NUMBER_OF_TABS" /> ટૅબનો ઉપયોગ કરવામાં આવ્યો નથી. તેને બંધ કરીએ?</translation>
 <translation id="257674075312929031">જૂથ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
index dda35f7a..a8ca8ae 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Ukloni</translation>
 <translation id="125153950246128346">Dodirnite za prikaz druge kartice</translation>
 <translation id="1657719826150349398">Pomakni karticu prema dolje</translation>
-<translation id="1778290789805128794">Premjesti vrh kartice</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> kartica}one{<ph name="TABS_COUNT_MANY" /> kartica}few{<ph name="TABS_COUNT_MANY" /> kartice}other{<ph name="TABS_COUNT_MANY" /> kartica}}</translation>
 <translation id="2569352796411618312">Prijedlog: broj vaših kartica koje niste koristili neko vrijeme: <ph name="NUMBER_OF_TABS" />. Želite li ih zatvoriti?</translation>
 <translation id="257674075312929031">Grupa</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
index 7c719e88..d326566 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Eltávolítás</translation>
 <translation id="125153950246128346">Koppintson másik lap megtekintéséhez</translation>
 <translation id="1657719826150349398">Lap mozgatása lefelé</translation>
-<translation id="1778290789805128794">Lap mozgatása fel</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> lap}other{<ph name="TABS_COUNT_MANY" /> lap}}</translation>
 <translation id="2569352796411618312">Javaslat: <ph name="NUMBER_OF_TABS" /> lapot nem használt mostanában. Szeretné bezárni őket?</translation>
 <translation id="257674075312929031">Csoport</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
index 90b4a55..a331d8c 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Ջնջել</translation>
 <translation id="125153950246128346">Հպեք՝ այլ ներդիրի անցնելու համար</translation>
 <translation id="1657719826150349398">Տեղափոխել ներդիրը ներքև</translation>
-<translation id="1778290789805128794">Տեղափոխել ներդիրը վերև</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ներդիր}one{<ph name="TABS_COUNT_MANY" /> ներդիր}other{<ph name="TABS_COUNT_MANY" /> ներդիր}}</translation>
 <translation id="2569352796411618312">Ձեր ներդիրներից <ph name="NUMBER_OF_TABS" />-ը վաղուց չեք օգտագործել։ Փակե՞լ դրանք։</translation>
 <translation id="257674075312929031">Խումբ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
index 649e01e..83779c7 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Hapus</translation>
 <translation id="125153950246128346">Ketuk untuk melihat tab lainnya</translation>
 <translation id="1657719826150349398">Pindahkan tab ke bawah</translation>
-<translation id="1778290789805128794">Pindahkan tab ke atas</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}other{<ph name="TABS_COUNT_MANY" /> tab}}</translation>
 <translation id="2569352796411618312">Saran: <ph name="NUMBER_OF_TABS" /> dari beberapa tab Anda belum digunakan akhir-akhir ini. Tutup?</translation>
 <translation id="257674075312929031">Grup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
index 46752cb2..58a1dbd 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Fjarlægja</translation>
 <translation id="125153950246128346">Ýttu til að sjá annan flipa</translation>
 <translation id="1657719826150349398">Færa flipa niður</translation>
-<translation id="1778290789805128794">Fela flipa efst</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> flipi}one{<ph name="TABS_COUNT_MANY" /> flipi}other{<ph name="TABS_COUNT_MANY" /> flipar}}</translation>
 <translation id="2569352796411618312">Tillaga: <ph name="NUMBER_OF_TABS" /> af flipunum þínum hafa ekki verið notaðir nýlega. Viltu loka þeim?</translation>
 <translation id="257674075312929031">Hópur</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
index d42eb85..710ac29 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Rimuovi</translation>
 <translation id="125153950246128346">Tocca per visualizzare un'altra scheda</translation>
 <translation id="1657719826150349398">Sposta scheda in basso</translation>
-<translation id="1778290789805128794">Sposta scheda in alto</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> scheda}other{<ph name="TABS_COUNT_MANY" /> schede}}</translation>
 <translation id="2569352796411618312">Suggerimento: <ph name="NUMBER_OF_TABS" /> delle tue schede non sono state usate ultimamente. Vuoi chiuderle?</translation>
 <translation id="257674075312929031">Gruppo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
index 5514c2ff..acb9a36 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">הסרה</translation>
 <translation id="125153950246128346">יש להקיש כדי לראות כרטיסייה אחרת</translation>
 <translation id="1657719826150349398">העברת הכרטיסיה למטה</translation>
-<translation id="1778290789805128794">העברת הכרטיסיה למעלה</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{כרטיסייה אחת (<ph name="TABS_COUNT_ONE" />)}two{<ph name="TABS_COUNT_MANY" /> כרטיסיות}many{<ph name="TABS_COUNT_MANY" /> כרטיסיות}other{<ph name="TABS_COUNT_MANY" /> כרטיסיות}}</translation>
 <translation id="2569352796411618312">הצעה: <ph name="NUMBER_OF_TABS" /> מהכרטיסיות לא היו בשימוש לאחרונה. לסגור אותן?</translation>
 <translation id="257674075312929031">קבוצה</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
index fd2f57b..04240ca 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">削除</translation>
 <translation id="125153950246128346">タップすると他のタブが表示されます</translation>
 <translation id="1657719826150349398">タブを下に移動</translation>
-<translation id="1778290789805128794">タブを一番上に移動</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> 個のタブ}other{<ph name="TABS_COUNT_MANY" /> 個のタブ}}</translation>
 <translation id="2569352796411618312">提案: しばらく使用していないタブが <ph name="NUMBER_OF_TABS" /> 個あります。これらのタブを閉じますか?</translation>
 <translation id="257674075312929031">グループ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
index c569b3b..2603fa2 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ამოშლა</translation>
 <translation id="125153950246128346">შეეხეთ სხვა ჩანართის სანახავად</translation>
 <translation id="1657719826150349398">ჩანართის ქვემოთ გადატანა</translation>
-<translation id="1778290789805128794">ჩანართის თავში გადატანა</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ჩანართი}other{<ph name="TABS_COUNT_MANY" /> ჩანართი}}</translation>
 <translation id="2569352796411618312">შემოთავაზება: თქვენი <ph name="NUMBER_OF_TABS" /> ჩანართი ბოლო დროს არ გამოგიყენებიათ. გსურთ მათი დახურვა?</translation>
 <translation id="257674075312929031">ჯგუფი</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
index b1573b7..8f6a22dc 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Өшіру</translation>
 <translation id="125153950246128346">Басқа қойынды көру үшін түртіңіз.</translation>
 <translation id="1657719826150349398">Қойындыны төмен жылжыту</translation>
-<translation id="1778290789805128794">Қойындыны жоғары жылжыту</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> қойынды}other{<ph name="TABS_COUNT_MANY" /> қойынды}}</translation>
 <translation id="2569352796411618312">Ұсыныс: <ph name="NUMBER_OF_TABS" /> қойынды біраздан бері пайдаланылмады. Олар жабылсын ба?</translation>
 <translation id="257674075312929031">Топ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
index da7aedf..0c93cd1 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
@@ -4,6 +4,7 @@
 <translation id="1075622780330595106">ផ្ទាំង <ph name="NUMBER_OF_TABS" /> របស់អ្នក​មិនត្រូវបាន​ប្រើទេ​នាពេល​ថ្មីៗនេះ។ បិទផ្ទាំង​ទាំងនោះឬ?</translation>
 <translation id="1181037720776840403">ដកចេញ</translation>
 <translation id="125153950246128346">ចុចដើម្បីមើល​ផ្ទាំងផ្សេងទៀត</translation>
+<translation id="1657719826150349398">ផ្លាស់ទី​ផ្ទាំង​ចុះក្រោម</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{ផ្ទាំង <ph name="TABS_COUNT_ONE" />}other{ផ្ទាំង <ph name="TABS_COUNT_MANY" />}}</translation>
 <translation id="2569352796411618312">ការណែនាំ៖ ផ្ទាំង <ph name="NUMBER_OF_TABS" /> របស់អ្នក​មិនត្រូវបាន​ប្រើទេ​នាពេល​ថ្មីៗនេះ។ បិទផ្ទាំង​ទាំងនោះឬ?</translation>
 <translation id="257674075312929031">ក្រុម</translation>
@@ -20,11 +21,13 @@
 <translation id="58326064309361797">អូសផ្ទាំង​នានា ដើម្បី​ដាក់ផ្ទាំង​ទាំងនោះ​ជាក្រុម</translation>
 <translation id="6040143037577758943">បិទ</translation>
 <translation id="6193448654517602979">ជ្រើសរើសផ្ទាំង</translation>
+<translation id="6562820390860419811">ផ្លាស់ទី​ផ្ទាំង​ទៅ​ខាងឆ្វេង</translation>
 <translation id="6615455863669487791">បង្ហាញខ្ញុំ</translation>
 <translation id="6840760312327750441">ដើម្បីដាក់​ផ្ទាំង​ជាក្រុម សូម​ចុចផ្ទាំង​ឱ្យជាប់។ រួចអូស​ផ្ទាំងនោះ​ដាក់លើ​ផ្ទាំង​ផ្សេងទៀត។</translation>
 <translation id="7151209024774799310">លុបផ្ទាំង​ចេញពីក្រុម</translation>
 <translation id="7559245342362162951">បង្ហាញផ្ទាំង​របស់ក្រុមនៅក្នុងក្រឡា​ពេញ​អេក្រង់</translation>
 <translation id="7792771145871471484">ពិនិត្យមើល​ការណែនាំ​។</translation>
+<translation id="7885132941432959125">ផ្លាស់ទី​ផ្ទាំង​ទៅ​ខាងស្ដាំ</translation>
 <translation id="7966321538264951561">ច្រានចោល​ការណែនាំ​។</translation>
 <translation id="83556505225171773">{TABS_COUNT,plural, =1{បិទ​ផ្ទាំង​ដែលបាន​ជ្រើសរើស <ph name="TABS_COUNT_ONE" />}other{បិទ​ផ្ទាំង​ដែលបាន​ជ្រើសរើស <ph name="TABS_COUNT_MANY" />}}</translation>
 <translation id="9150694013019234766">ប្ដូររវាងផ្ទាំង​នៅក្នុងក្រុម​ផ្ទាំងរបស់​អ្នកនៅជិតផ្នែកខាង​ក្រោមបំផុតរបស់​អេក្រង់</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
index 647a0190..9f7ff20 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ತೆಗೆದುಹಾಕು</translation>
 <translation id="125153950246128346">ಇನ್ನೊಂದು ಟ್ಯಾಬ್ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ</translation>
 <translation id="1657719826150349398">ಟ್ಯಾಬ್ ಅನ್ನು ಕೆಳಕ್ಕೆ ಸರಿಸಿ</translation>
-<translation id="1778290789805128794">ಟ್ಯಾಬ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಸರಿಸಿ</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ಟ್ಯಾಬ್}one{<ph name="TABS_COUNT_MANY" /> ಟ್ಯಾಬ್‌ಗಳು}other{<ph name="TABS_COUNT_MANY" /> ಟ್ಯಾಬ್‌ಗಳು}}</translation>
 <translation id="2569352796411618312">ಸಲಹೆ: ನೀವು ಈ ನಡುವೆ ಬಳಸದ <ph name="NUMBER_OF_TABS" /> ಟ್ಯಾಬ್‌ಗಳಿವೆ. ಅವುಗಳನ್ನು ಮುಚ್ಚಬೇಕೆ?</translation>
 <translation id="257674075312929031">ಗುಂಪು</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
index 2d44e77..6cfe03f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">삭제</translation>
 <translation id="125153950246128346">다른 탭을 보려면 탭하세요.</translation>
 <translation id="1657719826150349398">탭을 아래로 이동</translation>
-<translation id="1778290789805128794">탭을 상단으로 이동</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{탭 <ph name="TABS_COUNT_ONE" />개}other{탭 <ph name="TABS_COUNT_MANY" />개}}</translation>
 <translation id="2569352796411618312">추천: 최근 사용하지 않은 탭이 <ph name="NUMBER_OF_TABS" />개 있습니다. 탭을 닫으시겠습니까?</translation>
 <translation id="257674075312929031">그룹</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
index 55bb1e1..04567f6 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Алып салуу</translation>
 <translation id="125153950246128346">Башка өтмөктү көрүү үчүн, таптап коюңуз</translation>
 <translation id="1657719826150349398">Өтмөктү төмөн жылдыруу</translation>
-<translation id="1778290789805128794">Өтмөктү жогору жылдыруу</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> өтмөк}other{<ph name="TABS_COUNT_MANY" /> өтмөк}}</translation>
 <translation id="2569352796411618312">Сунуш: Өтмөктөрүңүздүн <ph name="NUMBER_OF_TABS" /> акыркы убакта колдонулган жок. Алар жабылсынбы?</translation>
 <translation id="257674075312929031">Топ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
index f7d6ce78..593da37 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ລຶບອອກ</translation>
 <translation id="125153950246128346">ແຕະເພື່ອເບິ່ງແຖບອື່ນ</translation>
 <translation id="1657719826150349398">ຍ້າຍແຖບລົງ</translation>
-<translation id="1778290789805128794">ຍ້າຍແຖບໄປເທິງສຸດ</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ແຖບ}other{<ph name="TABS_COUNT_MANY" /> ແຖບ}}</translation>
 <translation id="2569352796411618312">ການແນະນຳ: ທ່ານບໍ່ໄດ້ໃຊ້ແຖບຂອງທ່ານ <ph name="NUMBER_OF_TABS" /> ແຖບມາໄລຍະໜຶ່ງແລ້ວ. ປິດພວກມັນບໍ?</translation>
 <translation id="257674075312929031">ກຸ່ມ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
index 936c34ce..3ea9789 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Pašalinti</translation>
 <translation id="125153950246128346">Palieskite, kad peržiūrėtumėte kitą skirtuką</translation>
 <translation id="1657719826150349398">Perkelti skirtuką į apačią</translation>
-<translation id="1778290789805128794">Perkelti skirtuką į viršų</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> skirtukas}one{<ph name="TABS_COUNT_MANY" /> skirtukas}few{<ph name="TABS_COUNT_MANY" /> skirtukai}many{<ph name="TABS_COUNT_MANY" /> skirtuko}other{<ph name="TABS_COUNT_MANY" /> skirtukų}}</translation>
 <translation id="2569352796411618312">Pasiūlymas: pastaruoju metu nebuvo naudojama <ph name="NUMBER_OF_TABS" /> skirtuk. Uždaryti juos?</translation>
 <translation id="257674075312929031">Grupė</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
index 3b2778d..c918423c 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Noņemt</translation>
 <translation id="125153950246128346">Pieskarieties, lai skatītu citu cilni</translation>
 <translation id="1657719826150349398">Pārvietot cilni uz leju</translation>
-<translation id="1778290789805128794">Pārvietot cilni augšpusē</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> cilne}zero{<ph name="TABS_COUNT_MANY" /> cilnes}one{<ph name="TABS_COUNT_MANY" /> cilne}other{<ph name="TABS_COUNT_MANY" /> cilnes}}</translation>
 <translation id="2569352796411618312">Ieteikums: vairākas cilnes pēdējā laikā nav izmantotas (kopā <ph name="NUMBER_OF_TABS" />). Vai vēlaties tās aizvērt?</translation>
 <translation id="257674075312929031">Grupa</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
index 3b35ff56..a1bac50 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Отстрани</translation>
 <translation id="125153950246128346">Допрете за да видите друга картичка</translation>
 <translation id="1657719826150349398">Премести ја картичката надолу</translation>
-<translation id="1778290789805128794">Премести ја картичката погоре</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> картичка}one{<ph name="TABS_COUNT_MANY" /> картичка}other{<ph name="TABS_COUNT_MANY" /> картички}}</translation>
 <translation id="2569352796411618312">Предлог: <ph name="NUMBER_OF_TABS" /> ваши картички не се користени во последно време. Дали да се затворат?</translation>
 <translation id="257674075312929031">Група</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
index b99703b..b381d758 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Хасах</translation>
 <translation id="125153950246128346">Өөр табыг харахын тулд товшино уу</translation>
 <translation id="1657719826150349398">Табыг доош зөөх</translation>
-<translation id="1778290789805128794">Табыг дээд хэсэг рүү зөөх</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> таб}other{<ph name="TABS_COUNT_MANY" /> таб}}</translation>
 <translation id="2569352796411618312">Зөвлөмж: Таны табуудаас <ph name="NUMBER_OF_TABS" />-г нь сүүлийн үед ашиглаагүй байна. Тэдгээрийг хаах уу?</translation>
 <translation id="257674075312929031">Бүлэг</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
index 1bad3dd..372dfd8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Alih keluar</translation>
 <translation id="125153950246128346">Ketik untuk melihat tab lain</translation>
 <translation id="1657719826150349398">Alihkan tab ke bawah</translation>
-<translation id="1778290789805128794">Alihkan tab ke atas</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}other{<ph name="TABS_COUNT_MANY" /> tab}}</translation>
 <translation id="2569352796411618312">Cadangan: <ph name="NUMBER_OF_TABS" /> daripada tab anda sudah lama tidak digunakan. Tutup tab?</translation>
 <translation id="257674075312929031">Kumpulan</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
index d7ebb9c..dd59101 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ဖယ်ရှားရန်</translation>
 <translation id="125153950246128346">နောက်တဘ်တစ်ခုကြည့်ရန် တို့ပါ</translation>
 <translation id="1657719826150349398">တဘ်ကို အောက်သို့ ရွှေ့ရန်</translation>
-<translation id="1778290789805128794">တဘ်ကို အပေါ်ဆုံးသို့ ရွှေ့ရန်</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{တဘ် <ph name="TABS_COUNT_ONE" /> ခု}other{တဘ် <ph name="TABS_COUNT_MANY" /> ခု}}</translation>
 <translation id="2569352796411618312">အကြံပြုချက်- သင်၏တဘ် <ph name="NUMBER_OF_TABS" /> ခုကို အခုတစ်လော အသုံးပြုမထားပါ။ ၎င်းတို့ကို ပိတ်မလား။</translation>
 <translation id="257674075312929031">အုပ်စု</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
index fc205f5..12126de 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">हटाउनुहोस्</translation>
 <translation id="125153950246128346">अर्को ट्याब हेर्न ट्याप गर्नुहोस्</translation>
 <translation id="1657719826150349398">ट्याब सारेर तल लैजानुहोस्</translation>
-<translation id="1778290789805128794">ट्याब सारेर सिरानमा लैजानुहोस्</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ट्याब}other{<ph name="TABS_COUNT_MANY" /> ट्याबहरू}}</translation>
 <translation id="2569352796411618312">सुझाव: तपाईंले केही समय यता आफ्ना <ph name="NUMBER_OF_TABS" /> वटा ट्याबहरू प्रयोग गर्नुभएको छैन। तिनलाई बन्द गर्ने हो?</translation>
 <translation id="257674075312929031">समूह</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
index c29149b4..d7676df 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Verwijderen</translation>
 <translation id="125153950246128346">Tik om nog een tabblad te bekijken</translation>
 <translation id="1657719826150349398">Tabblad naar beneden verplaatsen</translation>
-<translation id="1778290789805128794">Tabblad bovenaan zetten</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tabblad}other{<ph name="TABS_COUNT_MANY" /> tabbladen}}</translation>
 <translation id="2569352796411618312">Suggestie: <ph name="NUMBER_OF_TABS" /> van je tabbladen zijn niet recent gebruikt. Wil je ze sluiten?</translation>
 <translation id="257674075312929031">Groep</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
index e69a9ccb..ed4b06d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Fjern</translation>
 <translation id="125153950246128346">Trykk for å se en annen fane</translation>
 <translation id="1657719826150349398">Flytt fanen nedover</translation>
-<translation id="1778290789805128794">Flytt fanen oppover</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> fane}other{<ph name="TABS_COUNT_MANY" /> faner}}</translation>
 <translation id="2569352796411618312">Forslag: <ph name="NUMBER_OF_TABS" /> av fanene dine er ikke brukt i det siste. Vil du lukke dem?</translation>
 <translation id="257674075312929031">Gruppe</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
index 84ac15e8..d7d572d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ଅପସାରଣ</translation>
 <translation id="125153950246128346">ଅନ୍ୟଏକ ଟାବ୍ ଦେଖିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ</translation>
 <translation id="1657719826150349398">ଟାବ୍‍କୁ ତଳକୁ ମୁଭ୍ କରନ୍ତୁ</translation>
-<translation id="1778290789805128794">ଟାବ୍‍ର ଶୀର୍ଷଭାଗକୁ ମୁଭ୍ କରନ୍ତୁ</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" />ଟି ଟାବ୍}other{<ph name="TABS_COUNT_MANY" />ଟି ଟାବ୍}}</translation>
 <translation id="2569352796411618312">ପ୍ରସ୍ତାବ: ଆପଣଙ୍କର <ph name="NUMBER_OF_TABS" />ଟି ଟାବ୍ ନିକଟରେ ବ୍ୟବହୃତ ହୋଇନାହିଁ। ସେଗୁଡ଼ିକୁ ବନ୍ଦ କରିବେ?</translation>
 <translation id="257674075312929031">ଗୋଷ୍ଠୀ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
index 68e31629..81adbdb 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Usuń</translation>
 <translation id="125153950246128346">Kliknij, by zobaczyć inną kartę</translation>
 <translation id="1657719826150349398">Przesuń kartę w dół</translation>
-<translation id="1778290789805128794">Przenieś kartę wyżej</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> karta}few{<ph name="TABS_COUNT_MANY" /> karty}many{<ph name="TABS_COUNT_MANY" /> kart}other{<ph name="TABS_COUNT_MANY" /> karty}}</translation>
 <translation id="2569352796411618312">Sugestia: od jakiegoś czasu nie używasz <ph name="NUMBER_OF_TABS" /> kart. Zamknąć je?</translation>
 <translation id="257674075312929031">Grupa</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
index 142b77d..295712e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Remover</translation>
 <translation id="125153950246128346">Toque para ver outra guia</translation>
 <translation id="1657719826150349398">Mover guia para baixo</translation>
-<translation id="1778290789805128794">Mover guia para cima</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> guia}one{<ph name="TABS_COUNT_MANY" /> guia}other{<ph name="TABS_COUNT_MANY" /> guias}}</translation>
 <translation id="2569352796411618312">Sugestão: <ph name="NUMBER_OF_TABS" /> das suas guias não foram usadas recentemente. Fechar todas elas?</translation>
 <translation id="257674075312929031">Grupo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
index 17e4c39..50d6e727 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Remover</translation>
 <translation id="125153950246128346">Toque para ver outro separador.</translation>
 <translation id="1657719826150349398">Mover o separador para baixo</translation>
-<translation id="1778290789805128794">Mover o separador para cima</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> separador}other{<ph name="TABS_COUNT_MANY" /> separadores}}</translation>
 <translation id="2569352796411618312">Sugestão: <ph name="NUMBER_OF_TABS" /> dos seus separadores não foram utilizados recentemente. Pretende fechá-los?</translation>
 <translation id="257674075312929031">Grupo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
index c844510..b15a1bd 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Elimină</translation>
 <translation id="125153950246128346">Atinge pentru a vedea altă filă</translation>
 <translation id="1657719826150349398">Mută fila mai jos</translation>
-<translation id="1778290789805128794">Mută fila mai sus</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> filă}few{<ph name="TABS_COUNT_MANY" /> file}other{<ph name="TABS_COUNT_MANY" /> de file}}</translation>
 <translation id="2569352796411618312">Sugestie: <ph name="NUMBER_OF_TABS" /> dintre file nu au fost folosite în ultima vreme. Vrei să le închizi?</translation>
 <translation id="257674075312929031">Grup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
index 66f4773..30119da 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Удалить</translation>
 <translation id="125153950246128346">Нажмите, чтобы перейти на другую вкладку</translation>
 <translation id="1657719826150349398">Переместить вкладку вниз</translation>
-<translation id="1778290789805128794">Переместить вкладку вверх</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> вкладка}one{<ph name="TABS_COUNT_MANY" /> вкладка}few{<ph name="TABS_COUNT_MANY" /> вкладки}many{<ph name="TABS_COUNT_MANY" /> вкладок}other{<ph name="TABS_COUNT_MANY" /> вкладки}}</translation>
 <translation id="2569352796411618312">Подсказка: вы давно не использовали некоторые вкладки (всего: <ph name="NUMBER_OF_TABS" />). Закрыть их?</translation>
 <translation id="257674075312929031">Группа.</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
index b925aac..7655aca 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ඉවත් කරන්න</translation>
 <translation id="125153950246128346">වෙනත් පටිත්තක් බැලීමට තට්ටු කරන්න</translation>
 <translation id="1657719826150349398">පටිත්ත පහළට ගෙන යන්න</translation>
-<translation id="1778290789805128794">පටිත්ත ඉහළට ගෙන යන්න</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> පටිත්තක්}one{පටිති <ph name="TABS_COUNT_MANY" /> ක්}other{පටිති <ph name="TABS_COUNT_MANY" /> ක්}}</translation>
 <translation id="2569352796411618312">යෝජනාව: ඔබේ පටිතිවලින් <ph name="NUMBER_OF_TABS" /> ක් මෑතදී භාවිත වී නැත. ඒවා වසන්නද?</translation>
 <translation id="257674075312929031">සමූහය</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
index 3cd6073..72f0c65 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Odstrániť</translation>
 <translation id="125153950246128346">Klepnutím zobrazíte ďalšiu kartu</translation>
 <translation id="1657719826150349398">Presunúť kartu nadol</translation>
-<translation id="1778290789805128794">Presunúť kartu nahor</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> karta}few{<ph name="TABS_COUNT_MANY" /> karty}many{<ph name="TABS_COUNT_MANY" /> tabs}other{<ph name="TABS_COUNT_MANY" /> kariet}}</translation>
 <translation id="2569352796411618312">Návrh: V poslednom čase ste nepoužili viacero kariet (<ph name="NUMBER_OF_TABS" />). Chcete ich zavrieť?</translation>
 <translation id="257674075312929031">Skupina</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
index 29bd1278..762ae72 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Odstrani</translation>
 <translation id="125153950246128346">Dotaknite se, če želite prikazati drug zavihek</translation>
 <translation id="1657719826150349398">Premakni zavihek navzdol</translation>
-<translation id="1778290789805128794">Premakni zavihek na vrh</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> zavihek}one{<ph name="TABS_COUNT_MANY" /> zavihek}two{<ph name="TABS_COUNT_MANY" /> zavihka}few{<ph name="TABS_COUNT_MANY" /> zavihki}other{<ph name="TABS_COUNT_MANY" /> zavihkov}}</translation>
 <translation id="2569352796411618312">Predlog: Toliko zavihkov nedavno niste uporabljali: <ph name="NUMBER_OF_TABS" />. Ali jih želite zapreti?</translation>
 <translation id="257674075312929031">Skupina</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
index d945c24..f73ae3e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Hiq</translation>
 <translation id="125153950246128346">Trokit për të parë një skedë tjetër</translation>
 <translation id="1657719826150349398">Lëviz skedën poshtë</translation>
-<translation id="1778290789805128794">Lëviz skedën në krye</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> skedë}other{<ph name="TABS_COUNT_MANY" /> skeda}}</translation>
 <translation id="2569352796411618312">Sugjerim: <ph name="NUMBER_OF_TABS" /> nga skedat e tua nuk janë përdorur së fundi. Do t'i mbyllësh ato?</translation>
 <translation id="257674075312929031">Grup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
index a443424..a565dd4 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Уклони</translation>
 <translation id="125153950246128346">Додирните да бисте видели неку другу картицу</translation>
 <translation id="1657719826150349398">Преместите картицу надоле</translation>
-<translation id="1778290789805128794">Преместите картицу на врх</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> картица}one{<ph name="TABS_COUNT_MANY" /> картица}few{<ph name="TABS_COUNT_MANY" /> картице}other{<ph name="TABS_COUNT_MANY" /> картица}}</translation>
 <translation id="2569352796411618312">Предлог: Имате више картица (<ph name="NUMBER_OF_TABS" />) које нисте користили у скорије време. Желите ли да их затворите?</translation>
 <translation id="257674075312929031">Група</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
index c4c76b9a..81290ef 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Ta bort</translation>
 <translation id="125153950246128346">Tryck för att visa en annan flik</translation>
 <translation id="1657719826150349398">Flytta fliken nedåt</translation>
-<translation id="1778290789805128794">Flytta fliken högst upp</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> flik}other{<ph name="TABS_COUNT_MANY" /> flikar}}</translation>
 <translation id="2569352796411618312">Förslag: <ph name="NUMBER_OF_TABS" /> av flikarna har inte använts på länge. Vill du stänga dem?</translation>
 <translation id="257674075312929031">Grupp</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
index 85304c7..5d017d27 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Ondoa</translation>
 <translation id="125153950246128346">Gusa ili uone kichupo kingine</translation>
 <translation id="1657719826150349398">Sogeza kichupo chini</translation>
-<translation id="1778290789805128794">Sogeza kichupo juu</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{Kichupo <ph name="TABS_COUNT_ONE" />}other{Vichupo <ph name="TABS_COUNT_MANY" />}}</translation>
 <translation id="2569352796411618312">Pendekezo: Hujatumia vichupo <ph name="NUMBER_OF_TABS" /> hivi majuzi. Ungependa tuvifunge?</translation>
 <translation id="257674075312929031">Kikundi</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
index 40d09fbf..1d925de 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">తీసివేయి</translation>
 <translation id="125153950246128346">మరొక ట్యాబ్‌ను చూడటానికి నొక్కండి</translation>
 <translation id="1657719826150349398">ట్యాబ్‌ని కిందికి తరలించు</translation>
-<translation id="1778290789805128794">ట్యాబ్‌ని పైకి తరలించు</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ట్యాబ్}other{<ph name="TABS_COUNT_MANY" /> ట్యాబ్‌లు}}</translation>
 <translation id="2569352796411618312">సూచన: మీ <ph name="NUMBER_OF_TABS" /> ట్యాబ్‌లను ఇటీవల ఉపయోగించలేదు. వాటిని మూసివేయాలా?</translation>
 <translation id="257674075312929031">సమూహం</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
index eaa5d5f..8552e7ed 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">นำออก</translation>
 <translation id="125153950246128346">แตะเพื่อดูแท็บอื่น</translation>
 <translation id="1657719826150349398">ย้ายแท็บลงล่าง</translation>
-<translation id="1778290789805128794">ย้ายแท็บขึ้นบน</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> แท็บ}other{<ph name="TABS_COUNT_MANY" /> แท็บ}}</translation>
 <translation id="2569352796411618312">คำแนะนำ: คุณไม่ได้ใช้แท็บ <ph name="NUMBER_OF_TABS" /> แท็บมาระยะหนึ่งแล้ว ปิดแท็บเหล่านั้นไหม</translation>
 <translation id="257674075312929031">กลุ่ม</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
index 4cb35e73..7c6b565f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Kaldır</translation>
 <translation id="125153950246128346">Başka bir sekmeyi görmek için dokunun</translation>
 <translation id="1657719826150349398">Sekmeyi aşağı taşı</translation>
-<translation id="1778290789805128794">Sekmeyi en üste taşı</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> sekme}other{<ph name="TABS_COUNT_MANY" /> sekme}}</translation>
 <translation id="2569352796411618312">Öneri: <ph name="NUMBER_OF_TABS" /> sekmeyi son zamanlarda hiç kullanmadınız. Bunlar kapatılsın mı?</translation>
 <translation id="257674075312929031">Grup</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
index a5598e1..b07b3a6 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Видалити</translation>
 <translation id="125153950246128346">Натисніть, щоб побачити іншу вкладку</translation>
 <translation id="1657719826150349398">Перемістити вкладку вниз</translation>
-<translation id="1778290789805128794">Перемістити вкладку вгору</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> вкладка}one{<ph name="TABS_COUNT_MANY" /> вкладка}few{<ph name="TABS_COUNT_MANY" /> вкладки}many{<ph name="TABS_COUNT_MANY" /> вкладок}other{<ph name="TABS_COUNT_MANY" /> вкладки}}</translation>
 <translation id="2569352796411618312">Пропозиція: ви давно не переходили на кілька вкладок (<ph name="NUMBER_OF_TABS" />). Закрити їх?</translation>
 <translation id="257674075312929031">Група</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
index 7fb8ce9..da2629bf 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">ہٹائیں</translation>
 <translation id="125153950246128346">دوسرا ٹیب دیکھنے کیلئے تھپتھپائیں</translation>
 <translation id="1657719826150349398">ٹیب کو نیچے منتقل کریں</translation>
-<translation id="1778290789805128794">ٹیب کو اوپر منتقل کریں</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ٹیب}other{<ph name="TABS_COUNT_MANY" /> ٹیبز}}</translation>
 <translation id="2569352796411618312">تجویز: آپ کے ٹیبز میں سے <ph name="NUMBER_OF_TABS" /> کا استعمال حال میں نہیں ہوا ہے۔ انہیں بند کریں؟</translation>
 <translation id="257674075312929031">گروپ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
index fb1f8416..3a3f65b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Olib tashlash</translation>
 <translation id="125153950246128346">Boshqa varaqni ochish uchun bosing</translation>
 <translation id="1657719826150349398">Varaqni pastga tushirish</translation>
-<translation id="1778290789805128794">Varaqni tepaga siljitish</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ta varaq}other{<ph name="TABS_COUNT_MANY" /> ta varaq}}</translation>
 <translation id="2569352796411618312">Bildirgi: <ph name="NUMBER_OF_TABS" /> ta varaq oxirgi vaqtlarda ishlatilmayapti. Ular yopilsinmi?</translation>
 <translation id="257674075312929031">Guruh</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
index 00f139c..3ba2eb8f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">删除</translation>
 <translation id="125153950246128346">点按即可查看另一标签页</translation>
 <translation id="1657719826150349398">下移标签页</translation>
-<translation id="1778290789805128794">上移标签页</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> 个标签页}other{<ph name="TABS_COUNT_MANY" /> 个标签页}}</translation>
 <translation id="2569352796411618312">建议:您有 <ph name="NUMBER_OF_TABS" /> 个标签页最近未被使用过。关闭它们?</translation>
 <translation id="257674075312929031">群组</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
index 231c73d..4c920c7 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">移除</translation>
 <translation id="125153950246128346">輕按即可查看另一個分頁</translation>
 <translation id="1657719826150349398">將分頁向下移</translation>
-<translation id="1778290789805128794">將分頁移至頂端</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> 個分頁}other{<ph name="TABS_COUNT_MANY" /> 個分頁}}</translation>
 <translation id="2569352796411618312">我有建議:你有 <ph name="NUMBER_OF_TABS" /> 個分頁最近冇用過,係咪要閂咗佢?</translation>
 <translation id="257674075312929031">群組</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
index 01d21cc..b0cd5b6 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">移除</translation>
 <translation id="125153950246128346">輕觸即可查看另一個分頁</translation>
 <translation id="1657719826150349398">將分頁向下移</translation>
-<translation id="1778290789805128794">將分頁移至頂端</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> 個分頁}other{<ph name="TABS_COUNT_MANY" /> 個分頁}}</translation>
 <translation id="2569352796411618312">建議:你有 <ph name="NUMBER_OF_TABS" /> 個分頁最近沒有使用過。要關閉這些分頁嗎?</translation>
 <translation id="257674075312929031">群組</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
index 4873bc6..ed0258cb 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
@@ -5,7 +5,6 @@
 <translation id="1181037720776840403">Susa</translation>
 <translation id="125153950246128346">Thepha ukuze ubone enye ithebhu</translation>
 <translation id="1657719826150349398">Yisa ithebhu phansi</translation>
-<translation id="1778290789805128794">Yisa ithebhu phezulu</translation>
 <translation id="1869137256605757565">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> ithebhu}one{<ph name="TABS_COUNT_MANY" /> amathebhu}other{<ph name="TABS_COUNT_MANY" /> amathebhu}}</translation>
 <translation id="2569352796411618312">Isiphakamiso: <ph name="NUMBER_OF_TABS" /> yamathebhu akho awakasetshenziswa kamuva nje. Wavale?</translation>
 <translation id="257674075312929031">Iqembu</translation>
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
index dd6a7dd..d43319f 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -21,19 +21,19 @@
 import static org.junit.Assert.assertTrue;
 
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher;
-import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createOverviewHideWatcher;
-import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabGroup;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstTabInDialog;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInDialog;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.isShowingPopupTabList;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.mergeAllNormalTabsToAGroup;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyShowingPopupTabList;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabStripFaviconCount;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount;
 
 import android.graphics.Rect;
 import android.support.test.espresso.Espresso;
 import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.contrib.RecyclerViewActions;
 import android.support.test.filters.MediumTest;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
@@ -41,7 +41,6 @@
 import android.widget.EditText;
 import android.widget.TextView;
 
-import org.hamcrest.Matcher;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -56,23 +55,15 @@
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.compositor.layouts.Layout;
 import org.chromium.chrome.browser.flags.FeatureUtilities;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
-import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.ChildrenCountAssertion;
 import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
 import org.chromium.chrome.tab_ui.R;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.UiRestriction;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /** End-to-end tests for TabGridDialog component. */
 @RunWith(ChromeJUnit4ClassRunner.class)
 // clang-format off
@@ -112,7 +103,7 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
         // Open dialog from tab switcher and verify dialog is showing correct content.
         openDialogFromTabSwitcherAndVerify(cta, 2);
@@ -126,7 +117,7 @@
         // Enter first tab page.
         assertTrue(cta.getLayoutManager().overviewVisible());
         clickFirstCardFromTabSwitcher(cta);
-        clickFirstTabFromDialog(cta);
+        clickFirstTabInDialog(cta);
         // Open dialog from tab strip and verify dialog is showing correct content.
         openDialogFromStripAndVerify(cta, 2);
 
@@ -144,7 +135,7 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
 
         // Open dialog and verify dialog is showing correct content.
@@ -164,7 +155,7 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
 
         // Open dialog and verify dialog is showing correct content.
@@ -183,7 +174,7 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
 
         // Add 400px top margin to the recyclerView.
@@ -233,7 +224,7 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
 
         // Open dialog and verify dialog is showing correct content.
@@ -265,13 +256,13 @@
         verifyTabSwitcherCardCount(cta, 2);
 
         // Create a tab group.
-        mergeAllTabsToAGroup(cta);
+        mergeAllNormalTabsToAGroup(cta);
         verifyTabSwitcherCardCount(cta, 1);
 
         // Enter first tab page.
         assertTrue(cta.getLayoutManager().overviewVisible());
         clickFirstCardFromTabSwitcher(cta);
-        clickFirstTabFromDialog(cta);
+        clickFirstTabInDialog(cta);
 
         // Open dialog from tab strip and verify dialog is showing correct content.
         openDialogFromStripAndVerify(cta, 2);
@@ -290,21 +281,6 @@
         openDialogFromStripAndVerify(cta, 2);
     }
 
-    private void mergeAllTabsToAGroup(ChromeTabbedActivity cta) {
-        List<Tab> tabGroup = new ArrayList<>();
-        TabModel tabModel = cta.getTabModelSelector().getModel(false);
-        for (int i = 0; i < tabModel.getCount(); i++) {
-            tabGroup.add(tabModel.getTabAt(i));
-        }
-        createTabGroup(cta, false, tabGroup);
-        assertTrue(cta.getTabModelSelector().getTabModelFilterProvider().getCurrentTabModelFilter()
-                           instanceof TabGroupModelFilter);
-        TabGroupModelFilter filter = (TabGroupModelFilter) cta.getTabModelSelector()
-                                             .getTabModelFilterProvider()
-                                             .getCurrentTabModelFilter();
-        assertEquals(1, filter.getCount());
-    }
-
     private void openDialogFromTabSwitcherAndVerify(ChromeTabbedActivity cta, int tabCount) {
         clickFirstCardFromTabSwitcher(cta);
         CriteriaHelper.pollInstrumentationThread(() -> isDialogShowing(cta));
@@ -318,9 +294,7 @@
     }
 
     private void verifyShowingDialog(ChromeTabbedActivity cta, int tabCount) {
-        onView(withId(R.id.tab_list_view))
-                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
-                .check(ChildrenCountAssertion.havingTabCount(tabCount));
+        verifyShowingPopupTabList(cta, tabCount);
 
         onView(allOf(withParent(withId(R.id.main_content)), withId(R.id.title)))
                 .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
@@ -337,25 +311,7 @@
     }
 
     private boolean isDialogShowing(ChromeTabbedActivity cta) {
-        boolean isShowing = true;
-        try {
-            onView(withId(R.id.tab_list_view))
-                    .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
-                    .check(matches(isDisplayed()));
-        } catch (NoMatchingRootException e) {
-            isShowing = false;
-        } catch (Exception e) {
-            assert false : "error when inspecting dialog recyclerView.";
-        }
-        return isShowing;
-    }
-
-    private void clickFirstTabFromDialog(ChromeTabbedActivity cta) {
-        OverviewModeBehaviorWatcher hideWatcher = createOverviewHideWatcher(cta);
-        onView(withId(R.id.tab_list_view))
-                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
-                .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
-        hideWatcher.waitForBehavior();
+        return isShowingPopupTabList(cta);
     }
 
     private void showDialogFromStrip(ChromeTabbedActivity cta) {
@@ -385,31 +341,6 @@
                 });
     }
 
-    private void closeFirstTabInDialog(ChromeTabbedActivity cta) {
-        onView(withId(R.id.tab_list_view))
-                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
-                .perform(new ViewAction() {
-                    @Override
-                    public Matcher<View> getConstraints() {
-                        return isDisplayed();
-                    }
-
-                    @Override
-                    public String getDescription() {
-                        return "close first tab";
-                    }
-
-                    @Override
-                    public void perform(UiController uiController, View view) {
-                        RecyclerView recyclerView = (RecyclerView) view;
-                        RecyclerView.ViewHolder viewHolder =
-                                recyclerView.findViewHolderForAdapterPosition(0);
-                        assert viewHolder != null;
-                        viewHolder.itemView.findViewById(R.id.action_button).performClick();
-                    }
-                });
-    }
-
     private boolean verifyUndoBarShowingAndClickUndo() {
         boolean isShowing = true;
         try {
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java
new file mode 100644
index 0000000..ea959c51
--- /dev/null
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java
@@ -0,0 +1,290 @@
+// 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.
+
+package org.chromium.chrome.browser.tasks.tab_management;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstTabInDialog;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInDialog;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.isShowingPopupTabList;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.mergeAllNormalTabsToAGroup;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.prepareTabsWithThumbnail;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.rotateDeviceToOrientation;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyShowingPopupTabList;
+import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount;
+
+import android.content.res.Configuration;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.contrib.RecyclerViewActions;
+import android.support.test.filters.MediumTest;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Restriction;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.compositor.layouts.Layout;
+import org.chromium.chrome.browser.flags.FeatureUtilities;
+import org.chromium.chrome.browser.fullscreen.FullscreenManagerTestUtils;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
+import org.chromium.chrome.tab_ui.R;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.net.test.EmbeddedTestServer;
+import org.chromium.ui.test.util.UiRestriction;
+
+import java.util.List;
+
+/** End-to-end tests for TabGroupPopupUi component. */
+@RunWith(ChromeJUnit4ClassRunner.class)
+// clang-format off
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+@Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_UI_IMPROVEMENTS_ANDROID})
+public class TabGroupPopupUiTest {
+    // clang-format on
+
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+
+    @Rule
+    public TestRule mProcessor = new Features.InstrumentationProcessor();
+
+    @Before
+    public void setUp() {
+        FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+        FeatureUtilities.setIsBottomToolbarEnabledForTesting(true);
+        FeatureUtilities.setDuetTabStripIntegrationAndroidEnabledForTesting(true);
+        mActivityTestRule.startMainActivityFromLauncher();
+        Layout layout = mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout();
+        assertTrue(layout instanceof StartSurfaceLayout);
+        CriteriaHelper.pollUiThread(mActivityTestRule.getActivity()
+                                            .getTabModelSelector()
+                                            .getTabModelFilterProvider()
+                                            .getCurrentTabModelFilter()::isTabModelRestored);
+    }
+
+    @Test
+    @MediumTest
+    public void testOnAnchorViewChanged() throws InterruptedException {
+        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+        // Tab strip should show automatically when entering tab group.
+        createTabGroupAndEnterTabPage(cta, 2, null);
+        CriteriaHelper.pollInstrumentationThread(() -> !isAnchoredOnTopToolbar(cta));
+        verifyShowingTabStrip(cta, 2);
+
+        // In portrait mode, tab strip should anchor on bottom toolbar; in landscape mode, bottom
+        // toolbar hides and tab strip should anchor on top toolbar.
+        rotateDeviceToOrientation(cta, Configuration.ORIENTATION_LANDSCAPE);
+        CriteriaHelper.pollInstrumentationThread(() -> isAnchoredOnTopToolbar(cta));
+        verifyShowingTabStrip(cta, 2);
+
+        rotateDeviceToOrientation(cta, Configuration.ORIENTATION_PORTRAIT);
+        CriteriaHelper.pollInstrumentationThread(() -> !isAnchoredOnTopToolbar(cta));
+        verifyShowingTabStrip(cta, 2);
+    }
+
+    @Test
+    @MediumTest
+    public void testTabStripShowHide() throws InterruptedException {
+        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+        // Try to trigger tab strip in a single tab page.
+        triggerTabStripAndVerify(cta, 0);
+
+        // Tab strip should show automatically when entering tab group.
+        createTabGroupAndEnterTabPage(cta, 2, null);
+        verifyShowingTabStrip(cta, 2);
+
+        // Dismiss tab strip by clicking the left button.
+        onView(withId(R.id.toolbar_left_button))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(click());
+        CriteriaHelper.pollInstrumentationThread(() -> !isTabStripShowing(cta));
+
+        // Re-show the tab strip.
+        triggerTabStripAndVerify(cta, 2);
+
+        // Tab strip should not show when overview mode is visible.
+        enterTabSwitcher(cta);
+        CriteriaHelper.pollInstrumentationThread(() -> !isTabStripShowing(cta));
+
+        // Re-verify that tab strip never shows in single tab.
+        clickFirstCardFromTabSwitcher(cta);
+        closeFirstTabInDialog(cta);
+        clickFirstTabInDialog(cta);
+        CriteriaHelper.pollInstrumentationThread(() -> !isTabStripShowing(cta));
+        triggerTabStripAndVerify(cta, 0);
+    }
+
+    @Test
+    @MediumTest
+    public void testTabStripUpdate() throws InterruptedException {
+        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+
+        // Tab strip should show automatically when entering tab group.
+        createTabGroupAndEnterTabPage(cta, 2, null);
+        verifyShowingTabStrip(cta, 2);
+
+        // Adding tabs should trigger tab strip update.
+        onView(withId(R.id.toolbar_right_button))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(click());
+        verifyShowingTabStrip(cta, 3);
+
+        onView(withId(R.id.toolbar_right_button))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(click());
+        verifyShowingTabStrip(cta, 4);
+
+        // Click on the current tab in strip to close, and the closure should trigger tab strip
+        // update.
+        onView(withId(R.id.tab_list_view))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(RecyclerViewActions.actionOnItemAtPosition(
+                        getCurrentTabIndexInGroup(cta), click()));
+        verifyShowingTabStrip(cta, 3);
+
+        onView(withId(R.id.tab_list_view))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(RecyclerViewActions.actionOnItemAtPosition(
+                        getCurrentTabIndexInGroup(cta), click()));
+        verifyShowingTabStrip(cta, 2);
+    }
+
+    @Test
+    @MediumTest
+    @CommandLineFlags.Add({ChromeSwitches.DISABLE_MINIMUM_SHOW_DURATION})
+    public void testTabStripChangeWithScrolling() throws InterruptedException {
+        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+        FullscreenManagerTestUtils.disableBrowserOverrides();
+
+        // Tab strip should show automatically when entering tab group.
+        EmbeddedTestServer testServer =
+                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
+        String url = testServer.getURL("/chrome/test/data/android/navigate/three.html");
+        createTabGroupAndEnterTabPage(cta, 2, url);
+        CriteriaHelper.pollInstrumentationThread(() -> isTabStripShowing(cta));
+
+        FullscreenManagerTestUtils.scrollBrowserControls(mActivityTestRule, false);
+
+        onView(withId(R.id.main_content))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .check((v, e) -> {
+                    View stripContainerView = (View) v.getParent().getParent();
+                    assertTrue(stripContainerView instanceof FrameLayout);
+                    assertEquals(0f, stripContainerView.getAlpha(), 0);
+                });
+
+        FullscreenManagerTestUtils.scrollBrowserControls(mActivityTestRule, true);
+
+        onView(withId(R.id.main_content))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .check((v, e) -> {
+                    View stripContainerView = (View) v.getParent().getParent();
+                    assertTrue(stripContainerView instanceof FrameLayout);
+                    assertEquals(1f, stripContainerView.getAlpha(), 0);
+                });
+    }
+
+    private void createTabGroupAndEnterTabPage(ChromeTabbedActivity cta, int tabCount, String url) {
+        if (url == null) {
+            createTabs(cta, false, tabCount);
+        } else {
+            prepareTabsWithThumbnail(mActivityTestRule, tabCount, 0, url);
+        }
+        enterTabSwitcher(cta);
+        verifyTabSwitcherCardCount(cta, tabCount);
+
+        mergeAllNormalTabsToAGroup(cta);
+        verifyTabSwitcherCardCount(cta, 1);
+        clickFirstCardFromTabSwitcher(cta);
+        clickFirstTabInDialog(cta);
+
+        assertFalse(cta.getLayoutManager().overviewVisible());
+    }
+
+    /**
+     * Try to show tab strip through long press the tab switcher button and verify the tab count in
+     * tab strip. If {@code count} is 0, verify that the strip is not showing.
+     * @param cta   The current running activity.
+     * @param count The count of tabs in tab strip. Could be 0.
+     */
+    private void triggerTabStripAndVerify(ChromeTabbedActivity cta, int count) {
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { cta.findViewById(R.id.tab_switcher_button).performLongClick(); });
+        if (count == 0) {
+            CriteriaHelper.pollInstrumentationThread(() -> !isTabStripShowing(cta));
+            return;
+        }
+        CriteriaHelper.pollInstrumentationThread(() -> isTabStripShowing(cta));
+        verifyShowingTabStrip(cta, count);
+    }
+
+    private boolean isAnchoredOnTopToolbar(ChromeTabbedActivity cta) {
+        boolean isTop = true;
+        try {
+            onView(withId(R.id.tab_list_view))
+                    .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                    .check((v, e) -> {
+                        int[] tabStripPosition = new int[2];
+                        int[] topToolbarPosition = new int[2];
+
+                        v.getLocationOnScreen(tabStripPosition);
+                        View topToolbarView = cta.findViewById(R.id.toolbar);
+                        topToolbarView.getLocationOnScreen(topToolbarPosition);
+
+                        // If strip is anchored on top toolbar, it should locate close to the top
+                        // toolbar.
+                        int anchorDistance = topToolbarView.getHeight();
+                        assertTrue(tabStripPosition[1] - topToolbarPosition[1] < anchorDistance);
+                    });
+        } catch (AssertionError e) {
+            isTop = false;
+        } catch (Exception e) {
+            assert false : "error when inspecting pop up tab list.";
+        }
+        return isTop;
+    }
+
+    private boolean isTabStripShowing(ChromeTabbedActivity cta) {
+        return isShowingPopupTabList(cta);
+    }
+
+    private void verifyShowingTabStrip(ChromeTabbedActivity cta, int tabCount) {
+        verifyShowingPopupTabList(cta, tabCount);
+    }
+
+    private int getCurrentTabIndexInGroup(ChromeTabbedActivity cta) {
+        Tab currentTab = cta.getTabModelSelector().getCurrentTab();
+        List<Tab> tabGroup = cta.getTabModelSelector()
+                                     .getTabModelFilterProvider()
+                                     .getCurrentTabModelFilter()
+                                     .getRelatedTabList(currentTab.getId());
+        return tabGroup.indexOf(currentTab);
+    }
+}
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
index ca29d334..1bad418 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -6,6 +6,7 @@
 
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
@@ -28,6 +29,7 @@
 import android.provider.Settings;
 import android.support.annotation.Nullable;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.NoMatchingRootException;
 import android.support.test.espresso.NoMatchingViewException;
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.ViewAction;
@@ -55,6 +57,7 @@
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -113,6 +116,115 @@
     }
 
     /**
+     * Click the first tab in tab grid dialog to open a tab page.
+     * @param cta  The current running activity.
+     */
+    static void clickFirstTabInDialog(ChromeTabbedActivity cta) {
+        clickNthTabInDialog(cta, 0);
+    }
+
+    /**
+     * Click the Nth tab in tab grid dialog to open a tab page.
+     * @param cta  The current running activity.
+     * @param index The index of the target tab.
+     */
+    static void clickNthTabInDialog(ChromeTabbedActivity cta, int index) {
+        OverviewModeBehaviorWatcher hideWatcher = createOverviewHideWatcher(cta);
+        onView(withId(R.id.tab_list_view))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(RecyclerViewActions.actionOnItemAtPosition(index, click()));
+        hideWatcher.waitForBehavior();
+    }
+
+    /**
+     * Close the first tab in tab gri dialog.
+     * @param cta  The current running activity.
+     */
+    static void closeFirstTabInDialog(ChromeTabbedActivity cta) {
+        closeNthTabInDialog(cta, 0);
+    }
+
+    /**
+     * Close the Nth tab in tab gri dialog.
+     * @param cta  The current running activity.
+     * @param index The index of the target tab to close.
+     */
+    static void closeNthTabInDialog(ChromeTabbedActivity cta, int index) {
+        onView(withId(R.id.tab_list_view))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .perform(new ViewAction() {
+                    @Override
+                    public Matcher<View> getConstraints() {
+                        return isDisplayed();
+                    }
+
+                    @Override
+                    public String getDescription() {
+                        return "close first tab";
+                    }
+
+                    @Override
+                    public void perform(UiController uiController, View view) {
+                        RecyclerView recyclerView = (RecyclerView) view;
+                        RecyclerView.ViewHolder viewHolder =
+                                recyclerView.findViewHolderForAdapterPosition(index);
+                        assert viewHolder != null;
+                        viewHolder.itemView.findViewById(R.id.action_button).performClick();
+                    }
+                });
+    }
+
+    /**
+     * Check whether there is a tab list showing in a {@link android.widget.PopupWindow}. This can
+     * be used for tab grid dialog and tab group popup UI.
+     * @param cta  The current running activity.
+     * @return Whether there is a tab list showing in a popup component.
+     */
+    static boolean isShowingPopupTabList(ChromeTabbedActivity cta) {
+        boolean isShowing = true;
+        try {
+            onView(withId(R.id.tab_list_view))
+                    .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                    .check(matches(isDisplayed()));
+        } catch (NoMatchingRootException e) {
+            isShowing = false;
+        } catch (Exception e) {
+            assert false : "error when inspecting pop up tab list.";
+        }
+        return isShowing;
+    }
+
+    /**
+     * Verify the number of tabs in the tab list showing in a popup component.
+     * @param cta   The current running activity.
+     * @param count The count of the tabs in the tab list.
+     */
+    static void verifyShowingPopupTabList(ChromeTabbedActivity cta, int count) {
+        onView(withId(R.id.tab_list_view))
+                .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
+                .check(ChildrenCountAssertion.havingTabCount(count));
+    }
+
+    /**
+     * Merge all normal tabs into a single tab group.
+     * @param cta   The current running activity.
+     */
+    static void mergeAllNormalTabsToAGroup(ChromeTabbedActivity cta) {
+        List<Tab> tabGroup = new ArrayList<>();
+        TabModel tabModel = cta.getTabModelSelector().getModel(false);
+        for (int i = 0; i < tabModel.getCount(); i++) {
+            tabGroup.add(tabModel.getTabAt(i));
+        }
+        createTabGroup(cta, false, tabGroup);
+        assertTrue(cta.getTabModelSelector().getTabModelFilterProvider().getCurrentTabModelFilter()
+                           instanceof TabGroupModelFilter);
+        TabGroupModelFilter filter = (TabGroupModelFilter) cta.getTabModelSelector()
+                                             .getTabModelFilterProvider()
+                                             .getCurrentTabModelFilter();
+        assertEquals(1, filter.getCount());
+    }
+
+    /**
      * Verify that current tab models hold correct number of tabs.
      * @param cta            The current running activity.
      * @param normalTabs     The correct number of normal tabs.
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni
index cba389af..91d1ce1 100644
--- a/chrome/android/features/tab_ui/tab_management_java_sources.gni
+++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -37,6 +37,7 @@
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemTest.java",
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridIphItemViewBinderTest.java",
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java",
+  "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java",
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiViewBinderTest.java",
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarViewBinderTest.java",
   "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinderTest.java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedAppLifecycle.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedAppLifecycle.java
index a12acfac..e1d7662 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedAppLifecycle.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedAppLifecycle.java
@@ -95,7 +95,7 @@
         }
 
         ApplicationStatus.registerStateListenerForAllActivities(this);
-        IdentityServicesProvider.getSigninManager().addSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().addSignInStateObserver(this);
     }
 
     /**
@@ -127,7 +127,7 @@
      * Unregisters listeners and cleans up any native resources held by FeedAppLifecycle.
      */
     public void destroy() {
-        IdentityServicesProvider.getSigninManager().removeSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().removeSignInStateObserver(this);
         ApplicationStatus.unregisterActivityStateListener(this);
         mLifecycleBridge.destroy();
         mLifecycleBridge = null;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
index 2145f10..520c88c 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -67,7 +67,7 @@
             FeedSurfaceCoordinator coordinator, @Nullable SnapScrollHelper snapScrollHelper) {
         mCoordinator = coordinator;
         mSnapScrollHelper = snapScrollHelper;
-        mSigninManager = IdentityServicesProvider.getSigninManager();
+        mSigninManager = IdentityServicesProvider.get().getSigninManager();
 
         mPrefChangeRegistrar = new PrefChangeRegistrar();
         mHasHeader = mCoordinator.getSectionHeaderView() != null;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java
index 08d8f2e..f591daf 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java
@@ -53,7 +53,7 @@
         // the associated FeedNewTabPage is destroyed.
         mTabObserver = new EmptyTabObserver() {
             @Override
-            public void onInteractabilityChanged(boolean isInteractable) {
+            public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
                 if (isInteractable) {
                     activate();
                 } else {
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageCardRenderTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageCardRenderTest.java
index a4fb38f6ee..a8408eb 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageCardRenderTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageCardRenderTest.java
@@ -34,8 +34,8 @@
 import org.chromium.chrome.browser.util.UrlConstants;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
 import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
@@ -63,8 +63,7 @@
     public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     @Rule
     public FeedDataInjectRule mFeedDataInjector = new FeedDataInjectRule(true);
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubjectTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubjectTest.java
index 2839ba1..105d97f2 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubjectTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubjectTest.java
@@ -18,7 +18,6 @@
 import com.google.common.truth.Truth;
 
 import org.junit.ComparisonFailure;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -97,7 +96,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 java.lang.NoClassDefFoundError: difflib/DiffUtils")
     public void wrongMessage() {
         expectFailure.whenTesting()
                 .about(runnables())
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImplTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImplTest.java
index cf0b9e3..6f574856 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImplTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImplTest.java
@@ -626,8 +626,7 @@
     public void testHandleResponse() throws Exception {
         mRequestManager.triggerRefresh(RequestReason.HOST_REQUESTED, mConsumer);
 
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // assertThat(fakeProtocolAdapter.getLastResponse()).isEqualToDefaultInstance();
+        assertThat(mFakeProtocolAdapter.getLastResponse()).isEqualTo(Response.getDefaultInstance());
         assertThat(mConsumer.isCalled()).isTrue();
         assertThat(mConsumedResult.isSuccessful()).isTrue();
     }
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/UtilsTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/UtilsTest.java
index c1b0e3d4..0b24eab6 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/UtilsTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/UtilsTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.feed.library.feedrequestmanager.internal;
 
-import org.junit.Ignore;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
@@ -15,36 +15,34 @@
 /** Tests of the {@link Utils}. */
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@Ignore("TODO(crbug.com/1024945): this test needs rewritten without LiteProtoTruth.")
 public class UtilsTest {
     @Test
     public void fillVersionsFromString_allValid() {
         Version.Builder builder = Version.newBuilder();
         Utils.fillVersionsFromString(builder, "1.2.3.4");
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // LiteProtoTruth.assertThat(builder.build())
-        //         .isEqualTo(Version.newBuilder()
-        //                            .setMajor(1)
-        //                            .setMinor(2)
-        //                            .setBuild(3)
-        //                            .setRevision(4)
-        //                            .build());
+        Assert.assertEquals(1, builder.getMajor());
+        Assert.assertEquals(2, builder.getMinor());
+        Assert.assertEquals(3, builder.getBuild());
+        Assert.assertEquals(4, builder.getRevision());
     }
 
     @Test
     public void fillVersionsFromString_ignoresExtraStrings() {
         Version.Builder builder = Version.newBuilder();
         Utils.fillVersionsFromString(builder, "1.2.3b5");
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // LiteProtoTruth.assertThat(builder.build())
-        //         .isEqualTo(Version.newBuilder().setMajor(1).setMinor(2).setBuild(3).build());
+        Assert.assertEquals(1, builder.getMajor());
+        Assert.assertEquals(2, builder.getMinor());
+        Assert.assertEquals(3, builder.getBuild());
+        Assert.assertFalse(builder.hasRevision());
     }
 
     @Test
     public void fillVersionsFromString_emptyVersion() {
         Version.Builder builder = Version.newBuilder();
         Utils.fillVersionsFromString(builder, "");
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // LiteProtoTruth.assertThat(builder.build()).isEqualToDefaultInstance();
+        Assert.assertFalse(builder.hasMajor());
+        Assert.assertFalse(builder.hasMinor());
+        Assert.assertFalse(builder.hasBuild());
+        Assert.assertFalse(builder.hasRevision());
     }
 }
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClientTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClientTest.java
index 971ab576..2f1d1ae 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClientTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClientTest.java
@@ -186,8 +186,7 @@
         });
 
         verify(mProtocolAdapter).createModel(mResponseCaptor.capture());
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // LiteProtoTruth.assertThat(responseCaptor.getValue()).isEqualTo(response);
+        assertThat(mResponseCaptor.getValue()).isEqualTo(response);
     }
 
     @Test
@@ -217,8 +216,7 @@
         });
 
         verify(mProtocolAdapter).createModel(mResponseCaptor.capture());
-        // TODO(crbug.com/1024945): Find alternative to LiteProtoTruth.
-        // LiteProtoTruth.assertThat(responseCaptor.getValue()).isEqualToDefaultInstance();
+        assertThat(mResponseCaptor.getValue()).isEqualTo(Response.getDefaultInstance());
     }
 
     private FakeTaskQueue getTaskQueue() {
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterTest.java
index e43a562c..b63a85e 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterTest.java
@@ -597,8 +597,7 @@
         assertThat(mAdapter.getView().getContentDescription().toString()).isEqualTo("Accessible!");
         final AccessibilityNodeInfo nodeInfo = AccessibilityNodeInfo.obtain();
         mAdapter.getView().onInitializeAccessibilityNodeInfo(nodeInfo);
-        // TODO(crbug.com/1024945): This test fails with NPE.
-        // assertThat(nodeInfo.getCollectionItemInfo().isHeading()).isTrue();
+        assertThat(nodeInfo.isHeading()).isTrue();
     }
 
     @Test
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallbackTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallbackTest.java
index 5988449..6948b8e 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallbackTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallbackTest.java
@@ -26,7 +26,6 @@
 import android.widget.ImageView.ScaleType;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -42,7 +41,8 @@
 @org.robolectric.annotation.Config(sdk = 27, manifest = org.robolectric.annotation.Config.NONE)
 public class LoadImageCallbackTest {
     private static final long FADE_IMAGE_THRESHOLD_MS = 682L;
-    private static final Integer NO_OVERLAY_COLOR = 0;
+    // null is a special value indicating no overlay.
+    private static final Integer NO_OVERLAY_COLOR = null;
     private static final boolean FADE_IMAGE = true;
     private static final boolean NO_FADE_IMAGE = false;
 
@@ -74,7 +74,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 Test fails, needs debugging")
     public void testInitialDrawable_fromImageView() {
         ImageView imageView = new ImageView(mContext);
         imageView.setImageDrawable(mInitialDrawable);
@@ -112,7 +111,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 Test fails, needs debugging")
     public void testQuickLoad_doesntFade_fadingDisabled() {
         ImageView imageView = new ImageView(mContext);
 
@@ -126,7 +124,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 Test fails, needs debugging")
     public void testQuickLoad_doesntFade_loadsBeforeTimeout() {
         ImageView imageView = new ImageView(mContext);
 
@@ -140,7 +137,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 Test fails, needs debugging")
     public void testDelayedTask() {
         ImageView imageView = new ImageView(mContext);
         LoadImageCallback callback = new LoadImageCallback(imageView, ScaleType.CENTER,
@@ -182,7 +178,6 @@
     }
 
     @Test
-    @Ignore("crbug.com/1024945 Test fails, needs debugging")
     public void testSetsOverlayColor_null() {
         ImageView imageView = new ImageView(mContext);
         LoadImageCallback callback = new LoadImageCallback(imageView, ScaleType.CENTER,
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImplTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImplTest.java
index 4c53afd..268f8cd7 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImplTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImplTest.java
@@ -20,7 +20,6 @@
 import android.widget.LinearLayout;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -58,7 +57,6 @@
 /** Tests of the {@link PietManagerImpl}. */
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@Ignore("crbug.com/1024945 Test does not work")
 public class PietManagerImplTest {
     @Mock
     private ActionHandler mActionHandler;
diff --git a/chrome/android/java/res/drawable-hdpi/sharing_more.png b/chrome/android/java/res/drawable-hdpi/sharing_more.png
new file mode 100644
index 0000000..c5bbf410
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/sharing_more.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/sharing_more.png b/chrome/android/java/res/drawable-mdpi/sharing_more.png
new file mode 100644
index 0000000..26c7a91
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/sharing_more.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/sharing_more.png b/chrome/android/java/res/drawable-xhdpi/sharing_more.png
new file mode 100644
index 0000000..12975d2
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/sharing_more.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/sharing_more.png b/chrome/android/java/res/drawable-xxhdpi/sharing_more.png
new file mode 100644
index 0000000..b552f6c
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/sharing_more.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/sharing_more.png b/chrome/android/java/res/drawable-xxxhdpi/sharing_more.png
new file mode 100644
index 0000000..f5da5e1
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/sharing_more.png
Binary files differ
diff --git a/chrome/android/java/res/drawable/ic_play_circle_24dp_white.xml b/chrome/android/java/res/drawable/ic_play_circle_24dp_white.xml
new file mode 100644
index 0000000..85f54e9
--- /dev/null
+++ b/chrome/android/java/res/drawable/ic_play_circle_24dp_white.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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. -->
+
+<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="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="@color/white_alpha_70"
+        android:pathData="M 12,2 C 6.475,2 2,6.475 2,12 2,17.525 6.475,22 12,22 17.525,22 22,17.525
+            22,12 22,6.475 17.525,2 12,2 z M 9.9999998,16.5 v -9 L 16,12 9.9999998,16.5 z" />
+</vector>
diff --git a/chrome/android/java/res/drawable/ic_play_circle_filled_blue.xml b/chrome/android/java/res/drawable/ic_play_circle_filled_blue.xml
deleted file mode 100644
index 2d84bb5..0000000
--- a/chrome/android/java/res/drawable/ic_play_circle_filled_blue.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-
-<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="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M0 0h24v24H0V0z" />
-    <path
-        android:fillColor="@color/default_icon_color_blue"
-        android:strokeWidth="1"
-        android:pathData="M12 20c4.41 0 8-3.59 8-8s-3.59-8-8-8-8 3.59-8 8 3.59 8 8 8zM10 7.5l6 4.5-6 4.5v-9z" />
-    <path
-        android:fillColor="#ffffff"
-        android:pathData="M12 22c5.52 0 10-4.48 10-10S17.52 2 12 2 2 6.48 2 12s4.48 10 10 10zm0-18c4.41 0 8 3.59 8 8s-3.59 8-8 8-8-3.59-8-8 3.59-8 8-8zm-2 3.5v9l6-4.5z" />
-</vector>
diff --git a/chrome/android/java/res/layout/incognito_description_layout.xml b/chrome/android/java/res/layout/incognito_description_layout.xml
index 56fb678..8eda233e6 100644
--- a/chrome/android/java/res/layout/incognito_description_layout.xml
+++ b/chrome/android/java/res/layout/incognito_description_layout.xml
@@ -20,7 +20,7 @@
         android:layout_height="wrap_content"
         tools:ignore="ContentDescription"
         android:src="@drawable/incognito_splash"
-        app:tint="@color/default_icon_color_white" />
+        app:tint="@color/ntp_incognito_icon_color" />
 
     <TextView
         android:id="@+id/new_tab_incognito_title"
diff --git a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml
index d6598b4..5ab09b3 100644
--- a/chrome/android/java/res/layout/photo_picker_bitmap_view.xml
+++ b/chrome/android/java/res/layout/photo_picker_bitmap_view.xml
@@ -34,27 +34,32 @@
             tools:ignore="ContentDescription"
             android:visibility="gone" />
 
-        <TextView
-            android:id="@+id/video_duration"
+        <LinearLayout
+            android:id="@+id/video_controls_small"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="3dp"
-            android:layout_marginEnd="6dp"
+            android:gravity="center_vertical"
             android:layout_gravity="end"
-            style="@style/TextAppearance.WhiteBody"/>
-    </FrameLayout>
+            android:visibility="gone">
 
-    <ImageView
-        android:id="@+id/play_video"
-        android:layout_width="26dp"
-        android:layout_height="26dp"
-        android:layout_marginStart="2dp"
-        android:layout_marginBottom="2dp"
-        android:layout_marginEnd="2dp"
-        android:contentDescription="@string/accessibility_play_video"
-        android:layout_gravity="bottom|end"
-        android:visibility="gone"
-        app:srcCompat="@drawable/ic_play_circle_filled_blue" />
+            <TextView
+                android:id="@+id/video_duration"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="3dp"
+                android:layout_marginEnd="3dp"
+                style="@style/TextAppearance.WhiteBody"/>
+
+            <ImageView
+                android:id="@+id/small_play_button"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_marginTop="3dp"
+                android:layout_marginEnd="6dp"
+                android:contentDescription="@string/accessibility_play_video"
+                app:srcCompat="@drawable/ic_play_circle_24dp_white" />
+        </LinearLayout>
+    </FrameLayout>
 
     <ImageView
         android:id="@+id/selected"
diff --git a/chrome/android/java/res/mipmap-hdpi/app_icon.png b/chrome/android/java/res/mipmap-hdpi/app_icon.png
deleted file mode 100644
index b6af9f5..0000000
--- a/chrome/android/java/res/mipmap-hdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/mipmap-mdpi/app_icon.png b/chrome/android/java/res/mipmap-mdpi/app_icon.png
deleted file mode 100644
index 32cac71..0000000
--- a/chrome/android/java/res/mipmap-mdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/mipmap-xhdpi/app_icon.png b/chrome/android/java/res/mipmap-xhdpi/app_icon.png
deleted file mode 100644
index 56eeb6f..0000000
--- a/chrome/android/java/res/mipmap-xhdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/mipmap-xxhdpi/app_icon.png b/chrome/android/java/res/mipmap-xxhdpi/app_icon.png
deleted file mode 100644
index 6deb0e4..0000000
--- a/chrome/android/java/res/mipmap-xxhdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/mipmap-xxxhdpi/app_icon.png b/chrome/android/java/res/mipmap-xxxhdpi/app_icon.png
deleted file mode 100644
index 3224102..0000000
--- a/chrome/android/java/res/mipmap-xxxhdpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index e03978c..9bf3099 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -781,11 +781,19 @@
         // #onPageLoadFinished() and #onCrash(). If we are not actively loading a tab (e.g.
         // in Android N multi-instance, which is created by re-parenting an existing tab),
         // ensure onDeferredStartup() gets called by calling postDeferredStartupIfNeeded() here.
-        if (mDeferredStartupQueued || getActivityTab() == null || !getActivityTab().isLoading()) {
+        if (mDeferredStartupQueued || shouldPostDeferredStartupForReparentedTab()) {
             postDeferredStartupIfNeeded();
         }
     }
 
+    /**
+     * Returns whether deferred startup should be run if we are not actively loading a tab (e.g.
+     * in Android N multi-instance, which is created by re-parenting an existing tab).
+     */
+    public boolean shouldPostDeferredStartupForReparentedTab() {
+        return getActivityTab() == null || !getActivityTab().isLoading();
+    }
+
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
index ca391ab0..55abc52 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
@@ -21,12 +21,11 @@
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
-import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
-import org.chromium.chrome.browser.firstrun.FirstRunUtils;
 import org.chromium.chrome.browser.init.AsyncInitTaskRunner;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.settings.privacy.PrivacyPreferencesManager;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ChromeSigninController;
@@ -48,7 +47,7 @@
 /**
  * Backup agent for Chrome, using Android key/value backup.
  */
-
+@SuppressWarnings("UseSharedPreferencesManagerFromChromeCheck")
 public class ChromeBackupAgent extends BackupAgent {
     private static final String ANDROID_DEFAULT_PREFIX = "AndroidDefault.";
     private static final String NATIVE_PREF_PREFIX = "native.";
@@ -90,9 +89,10 @@
     // List of preferences that should be restored unchanged.
     static final String[] BACKUP_ANDROID_BOOL_PREFS = {
             DataReductionProxySettings.DATA_REDUCTION_ENABLED_PREF,
-            FirstRunUtils.CACHED_TOS_ACCEPTED_PREF, FirstRunStatus.FIRST_RUN_FLOW_COMPLETE,
-            FirstRunStatus.LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE,
-            FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP,
+            ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED_PREF,
+            ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE,
+            ChromePreferenceKeys.FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE,
+            ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP,
             PrivacyPreferencesManager.PREF_METRICS_REPORTING,
     };
 
@@ -382,8 +382,7 @@
         // Because FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_COMPLETE is not restored Chrome
         // will sign in the user on first run to the account in FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME
         // if any. If the rest of FRE has been completed this will happen silently.
-        editor.putString(
-                FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, restoredUserName);
+        editor.putString(ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, restoredUserName);
         editor.apply();
 
         // The silent first run will change things, so there is no point in trying to prevent
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java
index f6caa61..82e8971 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -289,43 +289,42 @@
                             ChromeSwitches.ENABLE_VR_SHELL_DEV));
         }
 
-        if (menuGroup == MenuGroup.OVERVIEW_MODE_MENU) {
-            if (isIncognito) {
-                // Hide normal close all tabs item.
-                menu.findItem(R.id.close_all_tabs_menu_id).setVisible(false);
-                // Enable close incognito tabs only if there are incognito tabs.
-                menu.findItem(R.id.close_all_incognito_tabs_menu_id).setEnabled(true);
-            } else {
-                // Hide close incognito tabs item.
-                menu.findItem(R.id.close_all_incognito_tabs_menu_id).setVisible(false);
-                // Enable close all tabs if there are normal tabs or incognito tabs.
-                menu.findItem(R.id.close_all_tabs_menu_id)
-                        .setEnabled(mTabModelSelector.getTotalTabCount() > 0);
-            }
-            if (!FeatureUtilities.isTabGroupsAndroidUiImprovementsEnabled()
-                    || DeviceClassManager.enableAccessibilityLayout()) {
-                menu.findItem(R.id.menu_group_tabs).setVisible(false);
-            } else {
-                boolean shouldEnabled = mTabModelSelector.getTabModelFilterProvider()
-                                                .getCurrentTabModelFilter()
-                                                .getTabsWithNoOtherRelatedTabs()
-                                                .size()
-                        > 1;
-                menu.findItem(R.id.menu_group_tabs).setEnabled(shouldEnabled);
-            }
-        }
-
         // We have to iterate all menu items since same menu item ID may be associated with more
         // than one menu items.
+        boolean isMenuGroupTabsVisible = FeatureUtilities.isTabGroupsAndroidUiImprovementsEnabled()
+                && !DeviceClassManager.enableAccessibilityLayout();
+        boolean isMenuGroupTabsEnabled = mTabModelSelector.getTabModelFilterProvider()
+                                                 .getCurrentTabModelFilter()
+                                                 .getTabsWithNoOtherRelatedTabs()
+                                                 .size()
+                > 1;
+        boolean hasTabs = mTabModelSelector.getTotalTabCount() > 0;
+        boolean hasIncognitoTabs = mTabModelSelector.getModel(true).getCount() > 0;
         for (int i = 0; i < menu.size(); ++i) {
             MenuItem item = menu.getItem(i);
+            int itemGroupId = item.getGroupId();
+            if (!(menuGroup == MenuGroup.START_SURFACE_MODE_MENU
+                                && itemGroupId == R.id.START_SURFACE_MODE_MENU
+                        || menuGroup == MenuGroup.OVERVIEW_MODE_MENU
+                                && itemGroupId == R.id.OVERVIEW_MODE_MENU
+                        || menuGroup == MenuGroup.PAGE_MENU && itemGroupId == R.id.PAGE_MENU)) {
+                continue;
+            }
+
             if (item.getItemId() == R.id.recent_tabs_menu_id) {
-                if ((menuGroup == MenuGroup.START_SURFACE_MODE_MENU
-                            && item.getGroupId() == R.id.START_SURFACE_MODE_MENU)
-                        || (menuGroup == MenuGroup.PAGE_MENU
-                                && item.getGroupId() == R.id.PAGE_MENU)) {
-                    item.setVisible(!isIncognito);
-                }
+                item.setVisible(!isIncognito);
+            }
+            if (item.getItemId() == R.id.menu_group_tabs) {
+                item.setVisible(isMenuGroupTabsVisible);
+                item.setEnabled(isMenuGroupTabsEnabled);
+            }
+            if (item.getItemId() == R.id.close_all_tabs_menu_id) {
+                item.setVisible(!isIncognito);
+                item.setEnabled(hasTabs);
+            }
+            if (item.getItemId() == R.id.close_all_incognito_tabs_menu_id) {
+                item.setVisible(isIncognito);
+                item.setEnabled(hasIncognitoTabs);
             }
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
index c716de6..94dfa80 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java
@@ -91,7 +91,7 @@
             mSigninPromoController = null;
         }
 
-        mSignInManager = IdentityServicesProvider.getSigninManager();
+        mSignInManager = IdentityServicesProvider.get().getSigninManager();
         mSignInManager.addSignInStateObserver(this);
 
         mPromoState = calculatePromoState();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerHandler.java
index 1ad1081..086fd47c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerHandler.java
@@ -65,7 +65,7 @@
     }
 
     @Override
-    public void onInteractabilityChanged(boolean interactable) {
+    public void onInteractabilityChanged(Tab tab, boolean interactable) {
         if (interactable && mShouldRemoveThumbnail && mThumbnailTab != null) {
             mTabContentManager.removeTabThumbnail(mThumbnailTab.getId());
             mShouldRemoveThumbnail = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index 840a0bf..d4025d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -14,6 +14,7 @@
 import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
+import org.chromium.chrome.browser.customtabs.content.TabCreationMode;
 import org.chromium.chrome.browser.customtabs.dependency_injection.BaseCustomTabActivityComponent;
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
 import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
@@ -80,6 +81,19 @@
     }
 
     @Override
+    public boolean shouldPostDeferredStartupForReparentedTab() {
+        if (!super.shouldPostDeferredStartupForReparentedTab()) return false;
+
+        // Check {@link CustomTabActivityTabProvider#getInitialTabCreationMode()} because the
+        // tab has not yet started loading in the common case due to ordering of
+        // {@link ChromeActivity#onStartWithNative()} and
+        // {@link CustomTabActivityTabController#onFinishNativeInitialization()}.
+        @TabCreationMode
+        int mode = mTabProvider.getInitialTabCreationMode();
+        return (mode == TabCreationMode.HIDDEN || mode == TabCreationMode.EARLY);
+    }
+
+    @Override
     protected boolean handleBackPressed() {
         return mNavigationController.navigateOnBack();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index 99a181a..c1564ea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -42,7 +42,6 @@
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
 import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler;
 import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler.IntentIgnoringCriterion;
-import org.chromium.chrome.browser.customtabs.content.TabCreationMode;
 import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityComponent;
 import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityModule;
 import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleCoordinator;
@@ -273,16 +272,6 @@
     }
 
     @Override
-    public void onStartWithNative() {
-        super.onStartWithNative();
-        @TabCreationMode int mode = mTabProvider.getInitialTabCreationMode();
-        boolean earlyCreatedTabIsReady =
-                (mode == TabCreationMode.HIDDEN || mode == TabCreationMode.EARLY)
-                && !mTabProvider.getTab().isLoading();
-        if (earlyCreatedTabIsReady) postDeferredStartupIfNeeded();
-    }
-
-    @Override
     public void createContextualSearchTab(String searchUrl) {
         if (getActivityTab() == null) return;
         getActivityTab().loadUrl(new LoadUrlParams(searchUrl));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java
index 00ac7d5..ef0e2ee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java
@@ -59,7 +59,7 @@
         }
 
         @Override
-        public void onInteractabilityChanged(boolean interactable) {
+        public void onInteractabilityChanged(Tab tab, boolean interactable) {
             // Force a layout update if the tab is now in the foreground.
             maybeUpdateLayout();
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index b5a045f..fe6f2916f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -99,7 +99,7 @@
 
     @VisibleForTesting
     protected boolean isSyncAllowed() {
-        SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         return FirstRunUtils.canAllowSync() && !signinManager.isSigninDisabledByPolicy()
                 && signinManager.isSigninSupported();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
index 4b9358c..7edc69ce 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
@@ -12,9 +12,10 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.SyncFirstSetupCompleteSource;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.settings.SettingsLauncher;
 import org.chromium.chrome.browser.settings.sync.SyncAndServicesPreferences;
 import org.chromium.chrome.browser.signin.IdentityServicesProvider;
@@ -39,15 +40,6 @@
  * FirstRunSignInProcessor.start(activity).
  */
 public final class FirstRunSignInProcessor {
-    /**
-     * SharedPreferences preference names to keep the state of the First Run Experience.
-     */
-    private static final String FIRST_RUN_FLOW_SIGNIN_COMPLETE = "first_run_signin_complete";
-
-    // Needed by ChromeBackupAgent
-    public static final String FIRST_RUN_FLOW_SIGNIN_SETUP = "first_run_signin_setup";
-    public static final String FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME =
-            "first_run_signin_account_name";
 
     /**
      * Initiates the automatic sign-in process in background.
@@ -55,7 +47,7 @@
      * @param activity The context for the FRE parameters processor.
      */
     public static void start(final Activity activity) {
-        SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         signinManager.onFirstRunCheckDone();
 
         // Skip signin if the first run flow is not complete. Examples of cases where the user
@@ -123,8 +115,8 @@
      */
     @VisibleForTesting
     public static boolean getFirstRunFlowSignInComplete() {
-        return ContextUtils.getAppSharedPreferences()
-                .getBoolean(FIRST_RUN_FLOW_SIGNIN_COMPLETE, false);
+        return SharedPreferencesManager.getInstance().readBoolean(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_COMPLETE, false);
     }
 
     /**
@@ -133,18 +125,16 @@
      */
     @VisibleForTesting
     public static void setFirstRunFlowSignInComplete(boolean isComplete) {
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putBoolean(FIRST_RUN_FLOW_SIGNIN_COMPLETE, isComplete)
-                .apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_COMPLETE, isComplete);
     }
 
     /**
      * @return The account name selected during the First Run Experience, or null if none.
      */
     private static String getFirstRunFlowSignInAccountName() {
-        return ContextUtils.getAppSharedPreferences()
-                .getString(FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, null);
+        return SharedPreferencesManager.getInstance().readString(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, null);
     }
 
     /**
@@ -152,18 +142,16 @@
      * @param accountName The account name, or null.
      */
     private static void setFirstRunFlowSignInAccountName(String accountName) {
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putString(FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, accountName)
-                .apply();
+        SharedPreferencesManager.getInstance().writeString(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, accountName);
     }
 
     /**
      * @return Whether the user selected to see the settings once signed in after FRE.
      */
     private static boolean getFirstRunFlowSignInSetup() {
-        return ContextUtils.getAppSharedPreferences().getBoolean(
-                FIRST_RUN_FLOW_SIGNIN_SETUP, false);
+        return SharedPreferencesManager.getInstance().readBoolean(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, false);
     }
 
     /**
@@ -171,10 +159,8 @@
      * @param isComplete Whether the user selected to see the settings once signed in.
      */
     private static void setFirstRunFlowSignInSetup(boolean isComplete) {
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putBoolean(FIRST_RUN_FLOW_SIGNIN_SETUP, isComplete)
-                .apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, isComplete);
     }
 
     /**
@@ -193,7 +179,7 @@
      * Allows the user to sign-in if there are no pending FRE sign-in requests.
      */
     public static void updateSigninManagerFirstRunCheckDone() {
-        SigninManager manager = IdentityServicesProvider.getSigninManager();
+        SigninManager manager = IdentityServicesProvider.get().getSigninManager();
         if (manager.isSignInAllowed()) return;
         if (!FirstRunStatus.getFirstRunFlowComplete()) return;
         if (!getFirstRunFlowSignInComplete()) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
index de414095..1bcfe5b1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
@@ -5,29 +5,22 @@
 package org.chromium.chrome.browser.firstrun;
 
 import org.chromium.base.CommandLine;
-import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
 /**
  * Gets and sets preferences related to the status of the first run experience.
  */
 public class FirstRunStatus {
 
-    // Needed by ChromeBackupAgent
-    public static final String FIRST_RUN_FLOW_COMPLETE = "first_run_flow";
-    public static final String LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE = "lightweight_first_run_flow";
-
-    private static final String SKIP_WELCOME_PAGE = "skip_welcome_page";
-
     /**
      * Sets the "main First Run Experience flow complete" preference.
      * @param isComplete Whether the main First Run Experience flow is complete
      */
     public static void setFirstRunFlowComplete(boolean isComplete) {
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putBoolean(FIRST_RUN_FLOW_COMPLETE, isComplete)
-                .apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, isComplete);
     }
 
     /**
@@ -36,7 +29,8 @@
      * includes ToS and Sign In pages if necessary.
      */
     public static boolean getFirstRunFlowComplete() {
-        if (ContextUtils.getAppSharedPreferences().getBoolean(FIRST_RUN_FLOW_COMPLETE, false)) {
+        if (SharedPreferencesManager.getInstance().readBoolean(
+                    ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, false)) {
             return true;
         }
         return CommandLine.getInstance().hasSwitch(
@@ -48,14 +42,16 @@
      * @param isSkip Whether the welcome page should be skpped
     */
     public static void setSkipWelcomePage(boolean isSkip) {
-        ContextUtils.getAppSharedPreferences().edit().putBoolean(SKIP_WELCOME_PAGE, isSkip).apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_SKIP_WELCOME_PAGE, isSkip);
     }
 
     /**
     * Checks whether the welcome page should be skipped from the main First Run Experience.
     */
     public static boolean shouldSkipWelcomePage() {
-        return ContextUtils.getAppSharedPreferences().getBoolean(SKIP_WELCOME_PAGE, false);
+        return SharedPreferencesManager.getInstance().readBoolean(
+                ChromePreferenceKeys.FIRST_RUN_SKIP_WELCOME_PAGE, false);
     }
 
     /**
@@ -63,17 +59,15 @@
      * @param isComplete Whether the lightweight First Run Experience flow is complete
      */
     public static void setLightweightFirstRunFlowComplete(boolean isComplete) {
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putBoolean(LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, isComplete)
-                .apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE, isComplete);
     }
 
     /**
      * Returns whether the "lightweight First Run Experience flow" is complete.
      */
     public static boolean getLightweightFirstRunFlowComplete() {
-        return ContextUtils.getAppSharedPreferences().getBoolean(
-                LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, false);
+        return SharedPreferencesManager.getInstance().readBoolean(
+                ChromePreferenceKeys.FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE, false);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
index 14c6eb6d..3986ac8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
@@ -6,7 +6,6 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.os.UserManager;
 
@@ -15,11 +14,12 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.browser.metrics.UmaSessionStats;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.components.signin.AccountManagerFacade;
 
 /** Provides first run related utility functions. */
 public class FirstRunUtils {
-    public static final String CACHED_TOS_ACCEPTED_PREF = "first_run_tos_accepted";
     private static Boolean sHasGoogleAccountAuthenticator;
 
     /**
@@ -27,20 +27,22 @@
      * Must be called after native initialization.
      */
     public static void cacheFirstRunPrefs() {
-        SharedPreferences javaPrefs = ContextUtils.getAppSharedPreferences();
+        SharedPreferencesManager javaPrefs = SharedPreferencesManager.getInstance();
         // Set both Java and native prefs if any of the three indicators indicate ToS has been
         // accepted. This needed because:
         //   - Old versions only set native pref, so this syncs Java pref.
         //   - Backup & restore does not restore native pref, so this needs to update it.
         //   - checkAnyUserHasSeenToS() may be true which needs to sync its state to the prefs.
-        boolean javaPrefValue = javaPrefs.getBoolean(CACHED_TOS_ACCEPTED_PREF, false);
+        boolean javaPrefValue = javaPrefs.readBoolean(
+                ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED_PREF, false);
         boolean nativePrefValue = isFirstRunEulaAccepted();
         boolean userHasSeenTos =
                 ToSAckedReceiver.checkAnyUserHasSeenToS();
         boolean isFirstRunComplete = FirstRunStatus.getFirstRunFlowComplete();
         if (javaPrefValue || nativePrefValue || userHasSeenTos || isFirstRunComplete) {
             if (!javaPrefValue) {
-                javaPrefs.edit().putBoolean(CACHED_TOS_ACCEPTED_PREF, true).apply();
+                javaPrefs.writeBoolean(
+                        ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED_PREF, true);
             }
             if (!nativePrefValue) {
                 setEulaAccepted();
@@ -54,7 +56,8 @@
     public static boolean didAcceptTermsOfService() {
         // Note: Does not check FirstRunUtils.isFirstRunEulaAccepted() because this may be called
         // before native is initialized.
-        return ContextUtils.getAppSharedPreferences().getBoolean(CACHED_TOS_ACCEPTED_PREF, false)
+        return SharedPreferencesManager.getInstance().readBoolean(
+                       ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED_PREF, false)
                 || ToSAckedReceiver.checkAnyUserHasSeenToS();
     }
 
@@ -64,10 +67,8 @@
      */
     public static void acceptTermsOfService(boolean allowCrashUpload) {
         UmaSessionStats.changeMetricsReportingConsent(allowCrashUpload);
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putBoolean(CACHED_TOS_ACCEPTED_PREF, true)
-                .apply();
+        SharedPreferencesManager.getInstance().writeBoolean(
+                ChromePreferenceKeys.FIRST_RUN_CACHED_TOS_ACCEPTED_PREF, true);
         setEulaAccepted();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
index 0016fd3..82df840 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
@@ -66,7 +66,7 @@
      * This is used to enforce the environment for Android EDU and child accounts.
      */
     private static void processForcedSignIn(@Nullable final Runnable onComplete) {
-        final SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        final SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         // By definition we have finished all the checks for first run.
         signinManager.onFirstRunCheckDone();
         if (!FirstRunUtils.canAllowSync() || !signinManager.isSignInAllowed()) {
@@ -105,7 +105,7 @@
     // TODO(bauerb): Once external dependencies reliably use policy to force sign-in,
     // consider removing the child account / EDU checks.
     public static void checkCanSignIn(final ChromeActivity activity) {
-        if (IdentityServicesProvider.getSigninManager().isForceSigninEnabled()) {
+        if (IdentityServicesProvider.get().getSigninManager().isForceSigninEnabled()) {
             ExternalAuthUtils.getInstance().canUseGooglePlayServices(
                     new UserRecoverableErrorHandler.ModalDialog(activity, false));
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
index efdbeb6..af10ad4e2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
@@ -290,11 +290,16 @@
             }
 
             @Override
-            public void onInteractabilityChanged(boolean interactable) {
-                if (interactable) {
-                    Runnable enterFullscreen = getEnterFullscreenRunnable(getTab());
-                    if (enterFullscreen != null) enterFullscreen.run();
-                }
+            public void onInteractabilityChanged(Tab tab, boolean interactable) {
+                Tab currentTab = getTab();
+                if (!interactable || tab != currentTab) return;
+                Runnable enterFullscreen = getEnterFullscreenRunnable(currentTab);
+                if (enterFullscreen != null) enterFullscreen.run();
+
+                TabBrowserControlsOffsetHelper offsetHelper =
+                        TabBrowserControlsOffsetHelper.get(currentTab);
+                onOffsetsChanged(offsetHelper.topControlsOffset(),
+                        offsetHelper.bottomControlsOffset(), offsetHelper.contentOffset());
             }
 
             @Override
@@ -310,7 +315,7 @@
             @Override
             public void onBrowserControlsOffsetChanged(
                     Tab tab, int topControlsOffset, int bottomControlsOffset, int contentOffset) {
-                if (tab == getTab()) {
+                if (tab == getTab() && tab.isUserInteractable()) {
                     onOffsetsChanged(topControlsOffset, bottomControlsOffset, contentOffset);
                 }
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index 573474dfd..ffbb8a33 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -193,7 +193,7 @@
             }});
 
         // 9. Listen to changes in sign in state.
-        IdentityServicesProvider.getSigninManager().addSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().addSignInStateObserver(this);
 
         // 10. Create PrefChangeRegistrar to receive notifications on preference changes.
         mPrefChangeRegistrar = new PrefChangeRegistrar();
@@ -292,7 +292,7 @@
         mHistoryAdapter.onDestroyed();
         mLargeIconBridge.destroy();
         mLargeIconBridge = null;
-        IdentityServicesProvider.getSigninManager().removeSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().removeSignInStateObserver(this);
         mPrefChangeRegistrar.destroy();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
index 6930688..f8a2d4d2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
@@ -101,7 +101,7 @@
             }
 
             @Override
-            public void onInteractabilityChanged(boolean isInteractable) {
+            public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
                 mDelegate.onSurveyInfoBarTabInteractabilityChanged(isInteractable);
             }
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
index 05a64fc..f81009488 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
@@ -27,7 +27,7 @@
     /** The observer to dismiss all dialogs when the attached tab is not interactable. */
     private final TabObserver mTabObserver = new EmptyTabObserver() {
         @Override
-        public void onInteractabilityChanged(boolean isInteractable) {
+        public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
             updateSuspensionState();
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPrompt.java
new file mode 100644
index 0000000..6803c29
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPrompt.java
@@ -0,0 +1,116 @@
+// 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.
+
+package org.chromium.chrome.browser.nfc;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Build;
+import android.provider.Settings;
+import android.support.v4.widget.TextViewCompat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.task.PostTask;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
+import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.modaldialog.DialogDismissalCause;
+import org.chromium.ui.modaldialog.ModalDialogManager;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * Implements a modal dialog that prompts the user about turning on the NFC adapter on the system
+ * level.
+ */
+public class NfcSystemLevelPrompt implements ModalDialogProperties.Controller {
+    private ModalDialogManager mModalDialogManager;
+    private WindowAndroid mWindowAndroid;
+    private Runnable mCallback;
+
+    /**
+     * Triggers a prompt to ask the user to turn on the system NFC setting on their device.
+     *
+     * <p>The prompt will be triggered within the specified window.
+     *
+     * @param window The current window to display the prompt into.
+     * @param callback The callback to be called when dialog is closed.
+     */
+    public void show(WindowAndroid window, Runnable callback) {
+        ChromeActivity chromeActivity = (ChromeActivity) window.getActivity().get();
+        if (chromeActivity == null) {
+            PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.run());
+            return;
+        }
+        show(window, chromeActivity.getModalDialogManager(), callback);
+    }
+
+    @VisibleForTesting
+    protected void show(
+            WindowAndroid window, ModalDialogManager modalDialogManager, Runnable callback) {
+        Activity activity = window.getActivity().get();
+        LayoutInflater inflater = LayoutInflater.from(activity);
+        View customView = inflater.inflate(R.layout.permission_dialog, null);
+
+        TextView messageTextView = customView.findViewById(R.id.text);
+        messageTextView.setText(R.string.nfc_disabled_on_device_message);
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                messageTextView, R.drawable.settings_nfc, 0, 0, 0);
+
+        Resources resources = activity.getResources();
+        PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
+                                      .with(ModalDialogProperties.CONTROLLER, this)
+                                      .with(ModalDialogProperties.CUSTOM_VIEW, customView)
+                                      .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources,
+                                              R.string.nfc_prompt_turn_on)
+                                      .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources,
+                                              R.string.no_thanks)
+                                      .with(ModalDialogProperties.CONTENT_DESCRIPTION, resources,
+                                              R.string.nfc_disabled_on_device_message)
+                                      .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
+                                      .build();
+
+        mWindowAndroid = window;
+        mCallback = callback;
+        mModalDialogManager = modalDialogManager;
+        mModalDialogManager.showDialog(model, ModalDialogManager.ModalDialogType.TAB);
+    }
+
+    @Override
+    public void onClick(PropertyModel model, int buttonType) {
+        if (buttonType == ModalDialogProperties.ButtonType.NEGATIVE) {
+            mModalDialogManager.dismissDialog(model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED);
+        } else {
+            String nfcAction = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+                    ? Settings.Panel.ACTION_NFC
+                    : Settings.ACTION_NFC_SETTINGS;
+            Intent intent = new Intent(nfcAction);
+            try {
+                mWindowAndroid.showIntent(intent, new WindowAndroid.IntentCallback() {
+                    @Override
+                    public void onIntentCompleted(
+                            WindowAndroid window, int resultCode, Intent data) {
+                        mModalDialogManager.dismissDialog(
+                                model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
+                    }
+                }, null);
+            } catch (android.content.ActivityNotFoundException ex) {
+                mModalDialogManager.dismissDialog(
+                        model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
+            }
+        }
+    }
+
+    @Override
+    public void onDismiss(PropertyModel model, int dismissalCause) {
+        if (mCallback != null) mCallback.run();
+        mCallback = null;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
index ea3645ae..be77dcd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -101,7 +101,7 @@
         mRecentlyClosedTabManager = sRecentlyClosedTabManagerForTests != null
                 ? sRecentlyClosedTabManagerForTests
                 : new RecentlyClosedBridge(profile);
-        mSignInManager = IdentityServicesProvider.getSigninManager();
+        mSignInManager = IdentityServicesProvider.get().getSigninManager();
         mContext = context;
 
         int imageSize = context.getResources().getDimensionPixelSize(R.dimen.user_picture_size);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
index c5abd919..02aa5ec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -83,7 +83,7 @@
             UiConfig uiConfig, OfflinePageBridge offlinePageBridge,
             ContextMenuManager contextMenuManager) {
         this(uiDelegate, aboveTheFoldView, uiConfig, offlinePageBridge, contextMenuManager,
-                IdentityServicesProvider.getSigninManager());
+                IdentityServicesProvider.get().getSigninManager());
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
index 440426e..0e5d205 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -50,7 +50,7 @@
     private final SigninManager mSigninManager;
 
     public SectionList(SuggestionsUiDelegate uiDelegate, OfflinePageBridge offlinePageBridge) {
-        this(uiDelegate, offlinePageBridge, IdentityServicesProvider.getSigninManager());
+        this(uiDelegate, offlinePageBridge, IdentityServicesProvider.get().getSigninManager());
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java
index 6407260..95c1e74 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PermissionParamsListBuilder.java
@@ -20,6 +20,7 @@
 import org.chromium.chrome.browser.ContentSettingsType;
 import org.chromium.chrome.browser.browserservices.Origin;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager;
+import org.chromium.chrome.browser.settings.NfcSystemLevelSetting;
 import org.chromium.chrome.browser.settings.website.ContentSettingValues;
 import org.chromium.chrome.browser.settings.website.ContentSettingsResources;
 import org.chromium.chrome.browser.settings.website.WebsitePreferenceBridge;
@@ -91,6 +92,11 @@
                     && !locationUtils.isSystemLocationSettingEnabled()) {
                 permissionParams.warningTextResource = R.string.page_info_android_location_blocked;
                 intentOverride = locationUtils.getSystemLocationSettingsIntent();
+            } else if (permission.type == ContentSettingsType.NFC
+                    && !NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled()) {
+                permissionParams.warningTextResource =
+                        R.string.page_info_android_permission_blocked;
+                intentOverride = NfcSystemLevelSetting.getNfcSystemLevelSettingIntent();
             } else if (shouldShowNotificationsDisabledWarning(permission)) {
                 permissionParams.warningTextResource =
                         R.string.page_info_android_permission_blocked;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java
index 8977e0a..e2cc3d8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java
@@ -19,6 +19,7 @@
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
@@ -70,10 +71,13 @@
     // The aspect ratio of the image (>1.0=portrait, <1.0=landscape).
     private float mRatio = -1;
 
+    // The container for the small version of the video UI (duration and small play button).
+    private ViewGroup mVideoControlsSmall;
+
     // For video tiles, this lists the duration of the video. Blank for other types.
     private TextView mVideoDuration;
 
-    // The Play button in the bottom right corner. Only shown for videos.
+    // The Play button in the top right corner. Only shown for videos.
     private ImageView mPlayButton;
 
     // The little shader in the top left corner (provides backdrop for selection ring on
@@ -125,8 +129,9 @@
         mSpecialTileLabel = findViewById(R.id.special_tile_label);
 
         // Specific UI controls for video support.
+        mVideoControlsSmall = findViewById(R.id.video_controls_small);
         mVideoDuration = findViewById(R.id.video_duration);
-        mPlayButton = findViewById(R.id.play_video);
+        mPlayButton = findViewById(R.id.small_play_button);
         mPlayButton.setOnClickListener(this);
     }
 
@@ -298,10 +303,10 @@
         }
         mIconView.startAnimation(animation);
 
-        ObjectAnimator videoDurationX =
-                ObjectAnimator.ofFloat(mVideoDuration, View.TRANSLATION_X, videoDurationOffsetX);
-        ObjectAnimator videoDurationY =
-                ObjectAnimator.ofFloat(mVideoDuration, View.TRANSLATION_Y, videoDurationOffsetY);
+        ObjectAnimator videoDurationX = ObjectAnimator.ofFloat(
+                mVideoControlsSmall, View.TRANSLATION_X, videoDurationOffsetX);
+        ObjectAnimator videoDurationY = ObjectAnimator.ofFloat(
+                mVideoControlsSmall, View.TRANSLATION_Y, videoDurationOffsetY);
         AnimatorSet animatorSet = new AnimatorSet();
         animatorSet.playTogether(videoDurationX, videoDurationY);
         animatorSet.setDuration(animate ? ANIMATION_DURATION : 0);
@@ -408,7 +413,8 @@
             final AnimationDrawable animationDrawable = new AnimationDrawable();
             for (int i = 0; i < thumbnails.size(); ++i) {
                 animationDrawable.addFrame(
-                        new BitmapDrawable(thumbnails.get(i)), IMAGE_FRAME_DISPLAY);
+                        new BitmapDrawable(mContext.getResources(), thumbnails.get(i)),
+                        IMAGE_FRAME_DISPLAY);
             }
             animationDrawable.setOneShot(false);
             mIconView.setImageDrawable(animationDrawable);
@@ -443,6 +449,7 @@
         mBitmapDetails = null;
         mIconView.setImageBitmap(null);
         mVideoDuration.setText("");
+        mVideoControlsSmall.setVisibility(View.GONE);
         mUnselectedView.setVisibility(View.GONE);
         mSelectedView.setVisibility(View.GONE);
         mScrim.setVisibility(View.GONE);
@@ -483,7 +490,7 @@
                 && mCategoryView.isMultiSelectAllowed();
         mUnselectedView.setVisibility(showUnselectedToggle ? View.VISIBLE : View.GONE);
         mScrim.setVisibility(showUnselectedToggle ? View.VISIBLE : View.GONE);
-        mPlayButton.setVisibility(
+        mVideoControlsSmall.setVisibility(
                 mImageLoaded && mBitmapDetails.type() == PickerBitmap.TileTypes.VIDEO ? View.VISIBLE
                                                                                       : View.GONE);
         if (!special) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
index cb82a719..44b2d418 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
@@ -62,8 +62,9 @@
             public void finishNativeInitialization() {
                 PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
                     // TODO(bsazonov): Check whether invalidateAccountSeedStatus is needed here.
-                    IdentityServicesProvider.getAccountTrackerService().invalidateAccountSeedStatus(
-                            false /* don't refresh right now */);
+                    IdentityServicesProvider.get()
+                            .getAccountTrackerService()
+                            .invalidateAccountSeedStatus(false /* don't refresh right now */);
                     SigninHelper.get().validateAccountSettings(true);
                 });
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
index f0c4a65..1e0d5dc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/GoogleServicesManager.java
@@ -76,7 +76,7 @@
             // the native side is signed out if the Java side doesn't have a currently signed in
             // user.
             // TODO(bsazonov): Move this to SigninManager.
-            SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+            SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
             if (!mChromeSigninController.isSignedIn()
                     && signinManager.getIdentityManager().hasPrimaryAccount()) {
                 Log.w(TAG, "Signed in state got out of sync, forcing native sign out");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainPreferences.java
index 9383d3f..e6154b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainPreferences.java
@@ -96,7 +96,7 @@
     @Override
     public void onStart() {
         super.onStart();
-        SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         if (signinManager.isSigninSupported()) {
             signinManager.addSignInStateObserver(this);
             mSignInPreference.registerForUpdates();
@@ -110,7 +110,7 @@
     @Override
     public void onStop() {
         super.onStop();
-        SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         if (signinManager.isSigninSupported()) {
             signinManager.removeSignInStateObserver(this);
             mSignInPreference.unregisterForUpdates();
@@ -199,7 +199,7 @@
     }
 
     private void updatePreferences() {
-        if (IdentityServicesProvider.getSigninManager().isSigninSupported()) {
+        if (IdentityServicesProvider.get().getSigninManager().isSigninSupported()) {
             addPreferenceIfAbsent(PREF_SIGN_IN);
         } else {
             removePreferenceIfPresent(PREF_SIGN_IN);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/NfcSystemLevelSetting.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/NfcSystemLevelSetting.java
new file mode 100644
index 0000000..389be72
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/NfcSystemLevelSetting.java
@@ -0,0 +1,93 @@
+// 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.
+
+package org.chromium.chrome.browser.settings;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.nfc.NfcAdapter;
+import android.os.Process;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.task.PostTask;
+import org.chromium.chrome.browser.nfc.NfcSystemLevelPrompt;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * Provides methods for querying NFC sytem-level setting on Android.
+ *
+ * This class should be used only on the UI thread.
+ */
+public class NfcSystemLevelSetting {
+    private static Boolean sSystemNfcSettingForTesting;
+
+    @CalledByNative
+    private static boolean isNfcAccessPossible() {
+        Context context = ContextUtils.getApplicationContext();
+        int permission =
+                context.checkPermission(Manifest.permission.NFC, Process.myPid(), Process.myUid());
+        if (permission != PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+
+        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
+        return nfcAdapter != null;
+    }
+
+    @CalledByNative
+    public static boolean isNfcSystemLevelSettingEnabled() {
+        if (sSystemNfcSettingForTesting != null) {
+            return sSystemNfcSettingForTesting;
+        }
+
+        if (!isNfcAccessPossible()) return false;
+
+        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(ContextUtils.getApplicationContext());
+        return nfcAdapter.isEnabled();
+    }
+
+    @CalledByNative
+    private static void promptToEnableNfcSystemLevelSetting(
+            WebContents webContents, final long nativeCallback) {
+        WindowAndroid window = webContents.getTopLevelNativeWindow();
+        if (window == null) {
+            // Consuming code may not expect a sync callback to happen.
+            PostTask.postTask(UiThreadTaskTraits.DEFAULT,
+                    ()
+                            -> NfcSystemLevelSettingJni.get().onNfcSystemLevelPromptCompleted(
+                                    nativeCallback));
+            return;
+        }
+
+        NfcSystemLevelPrompt prompt = new NfcSystemLevelPrompt();
+        prompt.show(window,
+                ()
+                        -> NfcSystemLevelSettingJni.get().onNfcSystemLevelPromptCompleted(
+                                nativeCallback));
+    }
+
+    public static Intent getNfcSystemLevelSettingIntent() {
+        return new Intent(Settings.ACTION_NFC_SETTINGS);
+    }
+
+    /** Disable/enable Android NFC setting for testing use only. */
+    @VisibleForTesting
+    public static void setNfcSettingForTesting(Boolean enabled) {
+        sSystemNfcSettingForTesting = enabled;
+    }
+
+    @NativeMethods
+    interface Natives {
+        void onNfcSystemLevelPromptCompleted(long callback);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java
index b193f04..7318f31 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java
@@ -149,7 +149,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        IdentityServicesProvider.getSigninManager().addSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().addSignInStateObserver(this);
         mProfileDataCache.addObserver(this);
         mProfileDataCache.update(AccountManagerFacade.get().tryGetGoogleAccountNames());
         update();
@@ -158,7 +158,7 @@
     @Override
     public void onPause() {
         super.onPause();
-        IdentityServicesProvider.getSigninManager().removeSignInStateObserver(this);
+        IdentityServicesProvider.get().getSigninManager().removeSignInStateObserver(this);
         mProfileDataCache.removeObserver(this);
     }
 
@@ -380,7 +380,7 @@
         if (!ChromeSigninController.get().isSignedIn()) return;
 
         final DialogFragment clearDataProgressDialog = new ClearDataProgressDialog();
-        IdentityServicesProvider.getSigninManager().signOut(
+        IdentityServicesProvider.get().getSigninManager().signOut(
                 SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, new SigninManager.SignOutCallback() {
                     @Override
                     public void preWipeData() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SignInPreference.java
index 1f2fe2868..2254b8c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SignInPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SignInPreference.java
@@ -88,7 +88,7 @@
      */
     public void registerForUpdates() {
         AccountManagerFacade.get().addObserver(this);
-        IdentityServicesProvider.getSigninManager().addSignInAllowedObserver(this);
+        IdentityServicesProvider.get().getSigninManager().addSignInAllowedObserver(this);
         mProfileDataCache.addObserver(this);
         FirstRunSignInProcessor.updateSigninManagerFirstRunCheckDone();
         AndroidSyncSettings.get().registerObserver(this);
@@ -107,7 +107,7 @@
      */
     public void unregisterForUpdates() {
         AccountManagerFacade.get().removeObserver(this);
-        IdentityServicesProvider.getSigninManager().removeSignInAllowedObserver(this);
+        IdentityServicesProvider.get().getSigninManager().removeSignInAllowedObserver(this);
         mProfileDataCache.removeObserver(this);
         AndroidSyncSettings.get().unregisterObserver(this);
         ProfileSyncService syncService = ProfileSyncService.get();
@@ -156,7 +156,7 @@
 
     /** Updates the title, summary, and image based on the current sign-in state. */
     private void update() {
-        if (IdentityServicesProvider.getSigninManager().isSigninDisabledByPolicy()) {
+        if (IdentityServicesProvider.get().getSigninManager().isSigninDisabledByPolicy()) {
             setupSigninDisabled();
             return;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SyncAndServicesPreferences.java
index 67be385..5608e62 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SyncAndServicesPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/SyncAndServicesPreferences.java
@@ -569,10 +569,10 @@
         if (mCurrentSyncError == SyncError.OTHER_ERRORS) {
             final Account account = ChromeSigninController.get().getSignedInUser();
             // TODO(https://crbug.com/873116): Pass the correct reason for the signout.
-            IdentityServicesProvider.getSigninManager().signOut(
+            IdentityServicesProvider.get().getSigninManager().signOut(
                     SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS,
                     ()
-                            -> IdentityServicesProvider.getSigninManager().signIn(
+                            -> IdentityServicesProvider.get().getSigninManager().signIn(
                                     SigninAccessPoint.SYNC_ERROR_CARD, account, null),
                     false);
             return;
@@ -746,7 +746,7 @@
 
     private void cancelSync() {
         RecordUserAction.record("Signin_Signin_CancelAdvancedSyncSettings");
-        IdentityServicesProvider.getSigninManager().signOut(
+        IdentityServicesProvider.get().getSigninManager().signOut(
                 SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS);
         getActivity().finish();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/NfcCategory.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/NfcCategory.java
new file mode 100644
index 0000000..f77f961
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/NfcCategory.java
@@ -0,0 +1,38 @@
+// 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.
+
+package org.chromium.chrome.browser.settings.website;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.settings.NfcSystemLevelSetting;
+
+/**
+ * A class for dealing with the NFC category.
+ */
+public class NfcCategory extends SiteSettingsCategory {
+    public NfcCategory() {
+        // As NFC is not a per-app permission, passing an empty string means the NFC permission is
+        // always enabled for Chrome.
+        super(Type.NFC, "" /* androidPermission*/);
+    }
+
+    @Override
+    protected boolean enabledGlobally() {
+        return NfcSystemLevelSetting.isNfcSystemLevelSettingEnabled();
+    }
+
+    @Override
+    protected Intent getIntentToEnableOsGlobalPermission(Context context) {
+        return NfcSystemLevelSetting.getNfcSystemLevelSettingIntent();
+    }
+
+    @Override
+    protected String getMessageForEnablingOsGlobalPermission(Activity activity) {
+        return activity.getResources().getString(R.string.android_nfc_off_globally);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleCategoryPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleCategoryPreferences.java
index bf73f212..323f2e3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleCategoryPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleCategoryPreferences.java
@@ -941,9 +941,11 @@
         mCategory.configurePermissionIsOffPreferences(
                 osWarning, osWarningExtra, getActivity(), true);
         if (osWarning.getTitle() != null) {
+            osWarning.setKey(SingleWebsitePreferences.PREF_OS_PERMISSIONS_WARNING);
             screen.addPreference(osWarning);
         }
         if (osWarningExtra.getTitle() != null) {
+            osWarningExtra.setKey(SingleWebsitePreferences.PREF_OS_PERMISSIONS_WARNING_EXTRA);
             screen.addPreference(osWarningExtra);
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleWebsitePreferences.java
index 7093674..8894069 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleWebsitePreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SingleWebsitePreferences.java
@@ -656,6 +656,8 @@
             return SiteSettingsCategory.createFromType(SiteSettingsCategory.Type.MICROPHONE);
         } else if (showWarningFor(SiteSettingsCategory.Type.NOTIFICATIONS)) {
             return SiteSettingsCategory.createFromType(SiteSettingsCategory.Type.NOTIFICATIONS);
+        } else if (showWarningFor(SiteSettingsCategory.Type.NFC)) {
+            return SiteSettingsCategory.createFromType(SiteSettingsCategory.Type.NFC);
         }
         return null;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SiteSettingsCategory.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SiteSettingsCategory.java
index 8568b1b..f8763d9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SiteSettingsCategory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/website/SiteSettingsCategory.java
@@ -95,6 +95,7 @@
      */
     public static SiteSettingsCategory createFromType(@Type int type) {
         if (type == Type.DEVICE_LOCATION) return new LocationCategory();
+        if (type == Type.NFC) return new NfcCategory();
         if (type == Type.NOTIFICATIONS) return new NotificationCategory();
 
         final String permission;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
index 34e843d7..bbd7c00 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
@@ -261,12 +261,8 @@
                         new ShareSheetCoordinator(controller, tabProvider, tabCreator);
                 // TODO(crbug/1009124): open custom share sheet.
                 coordinator.showShareSheet(params);
-            } else if (ShareHelper.TargetChosenReceiver.isSupported()) {
-                // On L+ open system share sheet.
-                ShareHelper.makeIntentAndShare(params, null);
             } else {
-                // On K and below open custom share dialog.
-                ShareHelper.showShareDialog(params);
+                ShareHelper.showDefaultShareUi(params);
             }
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
index f6a13fb..dc4bcc8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -560,6 +560,21 @@
         }
     }
 
+    /**
+     * Show the default share sheet. On L+ this is the Android system share sheet on K and below
+     * this is a custom share dialog.
+     * @param params The share parameters.
+     */
+    static void showDefaultShareUi(ShareParams params) {
+        if (TargetChosenReceiver.isSupported()) {
+            // On L+ open system share sheet.
+            makeIntentAndShare(params, null);
+        } else {
+            // On K and below open custom share dialog.
+            showShareDialog(params);
+        }
+    }
+
     static void makeIntentAndShare(ShareParams params, @Nullable ComponentName component) {
         Intent intent = getShareLinkIntent(params);
         intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetBottomSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetBottomSheetContent.java
index f2e7224d..c91396a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetBottomSheetContent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetBottomSheetContent.java
@@ -1,18 +1,29 @@
 // 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.
-
+//
 package org.chromium.chrome.browser.share;
 
 import android.content.Context;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageView;
+import android.widget.TextView;
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContent;
+import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
+import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
+
+import java.util.ArrayList;
 
 /**
  * Bottom sheet content to display a 2-row custom share sheet.
@@ -21,6 +32,7 @@
     private Context mContext;
     private ViewGroup mToolbarView;
     private ViewGroup mContentView;
+    private static final int SHARE_SHEET_ITEM = 0;
 
     /**
      * Creates a ShareSheetBottomSheetContent (custom share sheet) opened from the given activity.
@@ -38,6 +50,50 @@
                 R.layout.share_sheet_content, null);
     }
 
+    /*
+     * Creates a new share sheet view with two rows based on the provided PropertyModels.
+     *
+     * @param activity The activity the share sheet belongs to.
+     * @param topRowModels The PropertyModels used to build the top row.
+     * @param bottomRowModels The PropertyModels used to build the bottom row.
+     */
+    public void createRecyclerViews(
+            ArrayList<PropertyModel> topRowModels, ArrayList<PropertyModel> bottomRowModels) {
+        populateView(
+                topRowModels, this.getContentView().findViewById(R.id.share_sheet_chrome_apps));
+        populateView(
+                bottomRowModels, this.getContentView().findViewById(R.id.share_sheet_other_apps));
+    }
+
+    private void populateView(ArrayList<PropertyModel> models, RecyclerView view) {
+        ModelList modelList = new ModelList();
+        for (PropertyModel model : models) {
+            modelList.add(new ListItem(SHARE_SHEET_ITEM, model));
+        }
+        SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(modelList);
+        adapter.registerType(SHARE_SHEET_ITEM, () -> {
+            return (ViewGroup) LayoutInflater.from(mContext).inflate(
+                    R.layout.share_sheet_item, (ViewGroup) view, false);
+        }, ShareSheetBottomSheetContent::bindShareItem);
+        view.setAdapter(adapter);
+        LinearLayoutManager layoutManager =
+                new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
+        view.setLayoutManager(layoutManager);
+    }
+
+    private static void bindShareItem(
+            PropertyModel model, ViewGroup parent, PropertyKey propertyKey) {
+        if (ShareSheetItemViewProperties.ICON.equals(propertyKey)) {
+            ImageView view = (ImageView) parent.findViewById(R.id.icon);
+            view.setImageDrawable(model.get(ShareSheetItemViewProperties.ICON));
+        } else if (ShareSheetItemViewProperties.LABEL.equals(propertyKey)) {
+            TextView view = (TextView) parent.findViewById(R.id.text);
+            view.setText(model.get(ShareSheetItemViewProperties.LABEL));
+        } else if (ShareSheetItemViewProperties.CLICK_LISTENER.equals(propertyKey)) {
+            parent.setOnClickListener(model.get(ShareSheetItemViewProperties.CLICK_LISTENER));
+        }
+    }
+
     @Override
     public View getContentView() {
         return mContentView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java
index d1ab465..27672f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java
@@ -5,34 +5,32 @@
 package org.chromium.chrome.browser.share;
 
 import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.support.v7.content.res.AppCompatResources;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.view.View.OnClickListener;
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ActivityTabProvider;
 import org.chromium.chrome.browser.send_tab_to_self.SendTabToSelfShareActivity;
 import org.chromium.chrome.browser.share.qrcode.QrCodeCoordinator;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
-import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
-import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
+import org.chromium.ui.widget.Toast;
+
+import java.util.ArrayList;
 
 /**
  * Coordinator for displaying the share sheet.
  */
 public class ShareSheetCoordinator {
-    private static final int SHARE_SHEET_ITEM = 0;
-
     private final BottomSheetController mBottomSheetController;
     private final ActivityTabProvider mActivityTabProvider;
     private final TabCreatorManager.TabCreator mTabCreator;
@@ -58,31 +56,37 @@
 
         ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity);
 
+        ArrayList<PropertyModel> chromeFeatures = createTopRowPropertyModels(bottomSheet, activity);
+        ArrayList<PropertyModel> thirdPartyApps =
+                createBottomRowPropertyModels(bottomSheet, activity, params);
+
+        bottomSheet.createRecyclerViews(chromeFeatures, thirdPartyApps);
+
+        mBottomSheetController.requestShowContent(bottomSheet, true);
+    }
+
+    private ArrayList<PropertyModel> createTopRowPropertyModels(
+            ShareSheetBottomSheetContent bottomSheet, Activity activity) {
+        ArrayList<PropertyModel> models = new ArrayList<>();
         // QR Codes
         PropertyModel qrcodePropertyModel =
-                new PropertyModel.Builder(ShareSheetItemViewProperties.ALL_KEYS)
-                        .with(ShareSheetItemViewProperties.ICON,
-                                AppCompatResources.getDrawable(activity, R.drawable.qr_code))
-                        .with(ShareSheetItemViewProperties.LABEL,
-                                activity.getResources().getString(
-                                        R.string.qr_code_share_icon_label))
-                        .with(ShareSheetItemViewProperties.CLICK_LISTENER,
-                                (currentContext) -> {
-                                    QrCodeCoordinator qrCodeCoordinator =
-                                            new QrCodeCoordinator(activity, this::createNewTab);
-                                    qrCodeCoordinator.show();
-                                })
-                        .build();
+                createPropertyModel(AppCompatResources.getDrawable(activity, R.drawable.qr_code),
+                        activity.getResources().getString(R.string.qr_code_share_icon_label),
+                        (currentActivity) -> {
+                            mBottomSheetController.hideContent(bottomSheet, true);
+                            QrCodeCoordinator qrCodeCoordinator =
+                                    new QrCodeCoordinator(activity, this::createNewTab);
+                            qrCodeCoordinator.show();
+                        });
+        models.add(qrcodePropertyModel);
 
         // Send Tab To Self
-        PropertyModel sttsPropertyModel =
-                new PropertyModel.Builder(ShareSheetItemViewProperties.ALL_KEYS)
-                        .with(ShareSheetItemViewProperties.ICON,
-                                AppCompatResources.getDrawable(activity, R.drawable.send_tab))
-                        .with(ShareSheetItemViewProperties.LABEL,
+        PropertyModel
+                sttsPropertyModel =
+                        createPropertyModel(
+                                AppCompatResources.getDrawable(activity, R.drawable.send_tab),
                                 activity.getResources().getString(
-                                        R.string.send_tab_to_self_share_activity_title))
-                        .with(ShareSheetItemViewProperties.CLICK_LISTENER,
+                                        R.string.send_tab_to_self_share_activity_title),
                                 (shareParams) -> {
                                     mBottomSheetController.hideContent(bottomSheet, true);
                                     SendTabToSelfShareActivity.actionHandler(activity,
@@ -91,39 +95,56 @@
                                                     .getNavigationController()
                                                     .getVisibleEntry(),
                                             mBottomSheetController);
-                                })
-                        .build();
+                                });
+        models.add(sttsPropertyModel);
 
-        ModelList modelList = new ModelList();
-        modelList.add(new ListItem(SHARE_SHEET_ITEM, qrcodePropertyModel));
-        modelList.add(new ListItem(SHARE_SHEET_ITEM, sttsPropertyModel));
-        SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(modelList);
-        RecyclerView rcView =
-                bottomSheet.getContentView().findViewById(R.id.share_sheet_chrome_apps);
-        adapter.registerType(SHARE_SHEET_ITEM, () -> {
-            return (ViewGroup) LayoutInflater.from(activity).inflate(
-                    R.layout.share_sheet_item, (ViewGroup) rcView, false);
-        }, ShareSheetCoordinator::bindShareItem);
+        // Copy URL
+        PropertyModel copyPropertyModel = createPropertyModel(
+                AppCompatResources.getDrawable(activity, R.drawable.ic_content_copy_black),
+                activity.getResources().getString(R.string.sharing_copy_url), (params) -> {
+                    mBottomSheetController.hideContent(bottomSheet, true);
+                    Tab tab = mActivityTabProvider.get();
+                    NavigationEntry entry =
+                            tab.getWebContents().getNavigationController().getVisibleEntry();
+                    ClipboardManager clipboard =
+                            (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
+                    ClipData clip = ClipData.newPlainText(entry.getTitle(), entry.getUrl());
+                    clipboard.setPrimaryClip(clip);
 
-        LinearLayoutManager layoutManager =
-                new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false);
-        rcView.setLayoutManager(layoutManager);
-        rcView.setAdapter(adapter);
+                    Toast toast =
+                            Toast.makeText(activity, R.string.link_copied, Toast.LENGTH_SHORT);
+                    toast.show();
+                });
+        models.add(copyPropertyModel);
 
-        mBottomSheetController.requestShowContent(bottomSheet, true);
+        return models;
     }
 
-    private static void bindShareItem(
-            PropertyModel model, ViewGroup parent, PropertyKey propertyKey) {
-        if (ShareSheetItemViewProperties.ICON.equals(propertyKey)) {
-            ImageView view = (ImageView) parent.findViewById(R.id.icon);
-            view.setImageDrawable(model.get(ShareSheetItemViewProperties.ICON));
-        } else if (ShareSheetItemViewProperties.LABEL.equals(propertyKey)) {
-            TextView view = (TextView) parent.findViewById(R.id.text);
-            view.setText(model.get(ShareSheetItemViewProperties.LABEL));
-        } else if (ShareSheetItemViewProperties.CLICK_LISTENER.equals(propertyKey)) {
-            parent.setOnClickListener(model.get(ShareSheetItemViewProperties.CLICK_LISTENER));
-        }
+    private ArrayList<PropertyModel> createBottomRowPropertyModels(
+            ShareSheetBottomSheetContent bottomSheet, Activity activity, ShareParams params) {
+        ArrayList<PropertyModel> models = new ArrayList<>();
+        // More...
+        PropertyModel morePropertyModel = createPropertyModel(
+                AppCompatResources.getDrawable(activity, R.drawable.sharing_more),
+                activity.getResources().getString(R.string.sharing_more_icon_label),
+                (shareParams) -> {
+                    mBottomSheetController.hideContent(bottomSheet, true);
+                    ShareHelper.showDefaultShareUi(params);
+                });
+        models.add(morePropertyModel);
+
+        return models;
+    }
+
+    private PropertyModel createPropertyModel(
+            Drawable icon, String label, OnClickListener listener) {
+        PropertyModel propertyModel =
+                new PropertyModel.Builder(ShareSheetItemViewProperties.ALL_KEYS)
+                        .with(ShareSheetItemViewProperties.ICON, icon)
+                        .with(ShareSheetItemViewProperties.LABEL, label)
+                        .with(ShareSheetItemViewProperties.CLICK_LISTENER, listener)
+                        .build();
+        return propertyModel;
     }
 
     private void createNewTab(String url) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
index 5770c36..141ddff 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
@@ -109,7 +109,7 @@
         mKeepSeparateOption.setRadioButtonGroup(radioGroup);
 
         // If the account is managed, disallow merging information.
-        if (IdentityServicesProvider.getSigninManager().getManagementDomain() != null) {
+        if (IdentityServicesProvider.get().getSigninManager().getManagementDomain() != null) {
             mKeepSeparateOption.setChecked(true);
             mConfirmImportOption.setOnClickListener(
                     view -> ManagedPreferencesUtils.showManagedByAdministratorToast(getActivity()));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
index 216b6ed..dbaf305 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
@@ -162,7 +162,7 @@
     }
 
     private void requestNewAccountManagementStatus() {
-        IdentityServicesProvider.getSigninManager().isAccountManaged(
+        IdentityServicesProvider.get().getSigninManager().isAccountManaged(
                 mNewAccountName, this::setIsNewAccountManaged);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
index 4991c99..be86935 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java
@@ -35,7 +35,7 @@
     }
 
     /** Getter for {@link IdentityManager} instance. */
-    private IdentityManager getIdentityManagerInternal() {
+    public IdentityManager getIdentityManager() {
         ThreadUtils.assertOnUiThread();
         IdentityManager result =
                 IdentityServicesProviderJni.get().getIdentityManager(Profile.getLastUsedProfile());
@@ -44,7 +44,7 @@
     }
 
     /** Getter for {@link AccountTrackerService} instance. */
-    private AccountTrackerService getAccountTrackerServiceInternal() {
+    public AccountTrackerService getAccountTrackerService() {
         ThreadUtils.assertOnUiThread();
         AccountTrackerService result = IdentityServicesProviderJni.get().getAccountTrackerService(
                 Profile.getLastUsedProfile());
@@ -53,8 +53,7 @@
     }
 
     /** Getter for {@link SigninManager} instance. */
-    @VisibleForTesting
-    SigninManager getSigninManagerInternal() {
+    public SigninManager getSigninManager() {
         ThreadUtils.assertOnUiThread();
         SigninManager result =
                 IdentityServicesProviderJni.get().getSigninManager(Profile.getLastUsedProfile());
@@ -62,21 +61,6 @@
         return result;
     }
 
-    /** Getter for {@link IdentityManager} instance. */
-    public static IdentityManager getIdentityManager() {
-        return get().getIdentityManagerInternal();
-    }
-
-    /** Getter for {@link AccountTrackerService} instance. */
-    public static AccountTrackerService getAccountTrackerService() {
-        return get().getAccountTrackerServiceInternal();
-    }
-
-    /** Getter for {@link SigninManager} instance. */
-    public static SigninManager getSigninManager() {
-        return get().getSigninManagerInternal();
-    }
-
     @NativeMethods
     interface Natives {
         IdentityManager getIdentityManager(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
index 515345d..d56cef8f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
@@ -78,8 +78,9 @@
             ThreadUtils.assertOnUiThread();
             if (sPendingProfileDownloads == null) {
                 sPendingProfileDownloads = new PendingProfileDownloads();
-                IdentityServicesProvider.getAccountTrackerService().addSystemAccountsSeededListener(
-                        sPendingProfileDownloads);
+                IdentityServicesProvider.get()
+                        .getAccountTrackerService()
+                        .addSystemAccountsSeededListener(sPendingProfileDownloads);
             }
             return sPendingProfileDownloads;
         }
@@ -123,7 +124,9 @@
             Context context, String accountId, int imageSidePixels, boolean isPreSignin) {
         ThreadUtils.assertOnUiThread();
         Profile profile = Profile.getLastUsedProfile().getOriginalProfile();
-        if (!IdentityServicesProvider.getAccountTrackerService().checkAndSeedSystemAccounts()) {
+        if (!IdentityServicesProvider.get()
+                        .getAccountTrackerService()
+                        .checkAndSeedSystemAccounts()) {
             PendingProfileDownloads.get(context).pendProfileDownload(
                     profile, accountId, imageSidePixels);
             return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
index 8443582..7a1835e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
@@ -64,7 +64,7 @@
             mGaiaServiceType = getArguments().getInt(
                     SHOW_GAIA_SERVICE_TYPE_EXTRA, mGaiaServiceType);
         }
-        String domain = IdentityServicesProvider.getSigninManager().getManagementDomain();
+        String domain = IdentityServicesProvider.get().getSigninManager().getManagementDomain();
         if (domain != null) {
             return createDialogForManagedAccount(domain);
         }
@@ -102,7 +102,7 @@
             SigninUtils.logEvent(ProfileAccountManagementMetrics.SIGNOUT_SIGNOUT, mGaiaServiceType);
 
             mSignOutClicked = true;
-            if (IdentityServicesProvider.getSigninManager().getManagementDomain() == null) {
+            if (IdentityServicesProvider.get().getSigninManager().getManagementDomain() == null) {
                 RecordHistogram.recordBooleanHistogram(
                         "Signin.UserRequestedWipeDataOnSignout", mWipeUserData.isChecked());
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
index f14d8325..c886d429 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -136,7 +136,7 @@
             callback.run();
             return;
         }
-        IdentityServicesProvider.getSigninManager().signIn(
+        IdentityServicesProvider.get().getSigninManager().signIn(
                 mSigninAccessPoint, account, new SigninManager.SignInCallback() {
                     @Override
                     public void onSignInComplete() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
index 4506457..53682fe9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
@@ -413,7 +413,7 @@
         // as this is needed for the previous account check.
         final long seedingStartTime = SystemClock.elapsedRealtime();
         final AccountTrackerService accountTrackerService =
-                IdentityServicesProvider.getAccountTrackerService();
+                IdentityServicesProvider.get().getAccountTrackerService();
         if (accountTrackerService.checkAndSeedSystemAccounts()) {
             recordAccountTrackerServiceSeedingTime(seedingStartTime);
             runStateMachineAndSignin(settingsClicked);
@@ -661,7 +661,8 @@
                 && mGooglePlayServicesUpdateErrorHandler.isShowing()) {
             return;
         }
-        boolean cancelable = !IdentityServicesProvider.getSigninManager().isForceSigninEnabled();
+        boolean cancelable =
+                !IdentityServicesProvider.get().getSigninManager().isForceSigninEnabled();
         mGooglePlayServicesUpdateErrorHandler =
                 new UserRecoverableErrorHandler.ModalDialog(getActivity(), cancelable);
         mGooglePlayServicesUpdateErrorHandler.handleError(getActivity(), gmsErrorCode);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
index 5bd3c58..e0a47c1b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -113,8 +113,8 @@
 
     private SigninHelper() {
         mProfileSyncService = ProfileSyncService.get();
-        mSigninManager = IdentityServicesProvider.getSigninManager();
-        mAccountTrackerService = IdentityServicesProvider.getAccountTrackerService();
+        mSigninManager = IdentityServicesProvider.get().getSigninManager();
+        mAccountTrackerService = IdentityServicesProvider.get().getAccountTrackerService();
         mChromeSigninController = ChromeSigninController.get();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
index e267434..2719073 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -126,7 +126,7 @@
      */
     public static boolean startSigninActivityIfAllowed(
             Context context, @SigninAccessPoint int accessPoint) {
-        SigninManager signinManager = IdentityServicesProvider.getSigninManager();
+        SigninManager signinManager = IdentityServicesProvider.get().getSigninManager();
         if (signinManager.isSignInAllowed()) {
             SigninActivityLauncher.get().launchActivity(context, accessPoint);
             return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
index b094500a..ece9010 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -230,7 +230,7 @@
     private TabObserver createTabObserver(Tab tab, String siteId) {
         return new EmptyTabObserver() {
             @Override
-            public void onInteractabilityChanged(boolean isInteractable) {
+            public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
                 showInfoBarIfApplicable(tab, siteId, this);
             }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
index 1ed535f..1b002ed 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
@@ -92,7 +92,7 @@
             }
         });
 
-        IdentityServicesProvider.getSigninManager().addSignInStateObserver(
+        IdentityServicesProvider.get().getSigninManager().addSignInStateObserver(
                 new SigninManager.SignInStateObserver() {
                     @Override
                     public void onSignedIn() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java
index 966c3b7..5326fe6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java
@@ -130,7 +130,7 @@
     public void onActivityAttachmentChanged(Tab tab, boolean isAttached) {}
 
     @Override
-    public void onInteractabilityChanged(boolean isInteractable) {}
+    public void onInteractabilityChanged(Tab tab, boolean isInteractable) {}
 
     @Override
     public void onRendererResponsiveStateChanged(Tab tab, boolean isResponsive) {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
index 4fd3776f3..2edaca5f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
@@ -92,10 +92,22 @@
 
             @Override
             public void onDidFinishNavigation(Tab tab, NavigationHandle navigationHandle) {
+                if (!navigationHandle.isInMainFrame()) return;
+
                 // At this point, we might have switched renderer processes, so push the existing
                 // constraints to the new renderer (has the potential to be slightly spammy, but
                 // the renderer has logic to suppress duplicate calls).
-                if (navigationHandle.isInMainFrame()) updateEnabledState();
+
+                @BrowserControlsState
+                int constraints = getConstraints();
+                if (constraints == BrowserControlsState.SHOWN && navigationHandle.hasCommitted()
+                        && TabBrowserControlsOffsetHelper.get(tab).topControlsOffset() == 0) {
+                    // If the browser controls were already fully visible on the previous page, then
+                    // avoid an animation to keep the controls from jumping around.
+                    update(BrowserControlsState.SHOWN, false);
+                } else {
+                    updateEnabledState();
+                }
             }
         });
         if (mTab.isInitialized() && !TabImpl.isDetached(mTab)) updateVisibilityDelegate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
index fdaca4b..3d744c49 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -1401,7 +1401,9 @@
         if (currentState == mInteractableState) return;
 
         mInteractableState = currentState;
-        for (TabObserver observer : mObservers) observer.onInteractabilityChanged(currentState);
+        for (TabObserver observer : mObservers) {
+            observer.onInteractabilityChanged(this, currentState);
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabObserver.java
index 7d1ee9e..b07c1b2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabObserver.java
@@ -299,9 +299,10 @@
 
     /**
      * A notification when tab changes whether or not it is interactable and is accepting input.
+     * @param tab The notifying {@link Tab}.
      * @param isInteractable Whether or not the tab is interactable.
      */
-    void onInteractabilityChanged(boolean isInteractable);
+    void onInteractabilityChanged(Tab tab, boolean isInteractable);
 
     /**
      * Called when renderer changes its state about being responsive to requests.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java
index 598c4da8..2c80d3e2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/IdentityDiscController.java
@@ -93,7 +93,7 @@
         mActivityLifecycleDispatcher.unregister(this);
         mActivityLifecycleDispatcher = null;
 
-        mSigninManager = IdentityServicesProvider.getSigninManager();
+        mSigninManager = IdentityServicesProvider.get().getSigninManager();
         mSigninManager.addSignInStateObserver(this);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java
index 589376f..10a08e71 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.toolbar.bottom;
 
+import android.graphics.Color;
 import android.support.v7.app.AppCompatActivity;
 import android.view.View;
 
@@ -13,6 +14,7 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ThemeColorProvider;
 import org.chromium.chrome.browser.ThemeColorProvider.ThemeColorObserver;
 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
@@ -26,15 +28,15 @@
  * toolbar, and updating the model accordingly.
  */
 class BrowsingModeBottomToolbarMediator implements ThemeColorObserver {
-    /** The amount of time to show the Duet help bubble for. */
-    private static final int DUET_IPH_BUBBLE_SHOW_DURATION_MS = 10000;
-
     /** The transparency fraction of the IPH bubble. */
     private static final float DUET_IPH_BUBBLE_ALPHA_FRACTION = 0.9f;
 
     /** The transparency fraction of the IPH background. */
     private static final float DUET_IPH_BACKGROUND_ALPHA_FRACTION = 0.3f;
 
+    /** The dismissable parameter name of the IPH. */
+    static final String DUET_IPH_TAP_TO_DISMISS_PARAM_NAME = "duet_iph_tap_to_dismiss_enabled";
+
     /** The model for the browsing mode bottom toolbar that holds all of its state. */
     private final BrowsingModeBottomToolbarModel mModel;
 
@@ -68,7 +70,9 @@
      */
     void showIPH(@FeatureConstants String feature, ChromeActivity activity, View anchor,
             Tracker tracker, Runnable completeRunnable) {
-        if (!tracker.shouldTriggerHelpUI(feature) || !anchor.isEnabled()) return;
+        if (!tracker.shouldTriggerHelpUI(feature) || !anchor.isShown() || !anchor.isEnabled()) {
+            return;
+        }
         int innerBackgroundColor =
                 ApiCompatibilityUtils.getColor(anchor.getResources(), R.color.modern_primary_color);
         int baseBubbleColor =
@@ -100,13 +104,25 @@
             default:
                 assert false : "Unsupported FeatureConstants: " + feature;
         }
+
+        // Default value for whether to able to dismiss the IPH for duet is true.
+        boolean tapToDismiss = true;
+        if (ChromeFeatureList.isInitialized()) {
+            tapToDismiss = ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                    feature, DUET_IPH_TAP_TO_DISMISS_PARAM_NAME, true);
+        }
+
+        if (tapToDismiss) {
+            // When users can dismiss the IPH, the outer background should be total transparent.
+            finalScrimColor = Color.TRANSPARENT;
+        }
+
         FeatureHighlightProvider.getInstance().buildForView(activity, anchor, titleId,
                 FeatureHighlightProvider.TextAlignment.CENTER, R.style.TextAppearance_WhiteTitle1,
                 descId, FeatureHighlightProvider.TextAlignment.CENTER,
                 R.style.TextAppearance_WhiteBody, innerBackgroundColor, finalOuterColor,
-                finalScrimColor, DUET_IPH_BUBBLE_SHOW_DURATION_MS, completeRunnable);
-
-        anchor.postDelayed(() -> tracker.dismissed(feature), DUET_IPH_BUBBLE_SHOW_DURATION_MS);
+                finalScrimColor, FeatureHighlightProvider.NO_TIMEOUT, tapToDismiss,
+                completeRunnable);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/FeatureHighlightProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/FeatureHighlightProvider.java
index fe94346..a576069 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/FeatureHighlightProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/FeatureHighlightProvider.java
@@ -31,6 +31,9 @@
         int END = 2;
     }
 
+    /** The value for IPH timeout if the IPH will not timeout. */
+    public static final long NO_TIMEOUT = -1;
+
     /** Static handle to the sole highlight provider. */
     private static FeatureHighlightProvider sInstance;
 
@@ -65,6 +68,29 @@
             Runnable completeRunnable) {}
 
     /**
+     * Build and show a feature highlight bubble for a particular view.
+     * @param activity An activity to attach the highlight to.
+     * @param view The view to focus.
+     * @param headTextId The text shown in the header section of the bubble.
+     * @param headAlignment Alignment of the head text.
+     * @param headStyle Style of the head text size and color.
+     * @param bodyTextId The text shown in the body section of the bubble.
+     * @param bodyAlignment Alignment of the body text.
+     * @param bodyStyle Style of the body text size and color.
+     * @param pulseColor The inner color of the bubble.
+     * @param outerColor The outer color of the bubble.
+     * @param scrimColor The color of the out side of feature highlight.
+     * @param timeoutMs The amount of time in ms before the bubble disappears.
+     * @param tapToDismiss The feature highlight bubble can be dismissiable.
+     * @param completeRunnable The Runnable to be called if the user tab on the view.
+     */
+    public void buildForView(AppCompatActivity activity, View view, @StringRes int headTextId,
+            @TextAlignment int headAlignment, @StyleRes int headStyle, @StringRes int bodyTextId,
+            @TextAlignment int bodyAlignment, @StyleRes int bodyStyle, @ColorInt int pulseColor,
+            @ColorInt int outerColor, @ColorInt int scrimColor, long timeoutMs,
+            Boolean tapToDismiss, Runnable completeRunnable) {}
+
+    /**
      * Dismiss the feature highlight bubble for a particular view.
      * @param activity An activity to attach the IPH to.
      */
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL.png.sha1
deleted file mode 100644
index 7e36da65..0000000
--- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5d36736598e01f51e1896d108fdc33e326cff806
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabObserverTest.java
index 2bc3242..7c40dbf 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabObserverTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabObserverTest.java
@@ -40,7 +40,7 @@
         private CallbackHelper mInteractabilityHelper = new CallbackHelper();
 
         @Override
-        public void onInteractabilityChanged(boolean isInteractable) {
+        public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
             mInteractabilityHelper.notifyCalled();
         }
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OWNERS
index de0c9ec..4e1c69c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OWNERS
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OWNERS
@@ -1 +1 @@
-file://chrome/android/java/src/org/chromium/chrome/browser/appmenu/OWNERS
+file://chrome/browser/ui/android/appmenu/OWNERS
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OverviewAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OverviewAppMenuTest.java
new file mode 100644
index 0000000..143cd9c
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/OverviewAppMenuTest.java
@@ -0,0 +1,297 @@
+// 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.
+
+package org.chromium.chrome.browser.appmenu;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.Restriction;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.flags.FeatureUtilities;
+import org.chromium.chrome.browser.ui.appmenu.AppMenuTestSupport;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.UiRestriction;
+
+/**
+ * Tests overview mode app menu popup.
+ *
+ * TODO(crbug.com/1031958): Add more required tests.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public class OverviewAppMenuTest {
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+
+    @Before
+    public void setUp() {
+        mActivityTestRule.startMainActivityFromLauncher();
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { mActivityTestRule.getActivity().getLayoutManager().showOverview(true); });
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testAllMenuItemsWithoutStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(false);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            int itemGroupId = item.getGroupId();
+            if (itemGroupId == R.id.OVERVIEW_MODE_MENU) {
+                int itemId = item.getItemId();
+                assertTrue(itemId == R.id.new_tab_menu_id
+                        || itemId == R.id.new_incognito_tab_menu_id
+                        || itemId == R.id.close_all_tabs_menu_id
+                        || itemId == R.id.close_all_incognito_tabs_menu_id
+                        || itemId == R.id.menu_group_tabs || itemId == R.id.preferences_id);
+                if (itemId == R.id.close_all_incognito_tabs_menu_id) {
+                    assertFalse(item.isVisible());
+                } else {
+                    assertTrue(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(6));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testIncognitoAllMenuItemsWithoutStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mActivityTestRule.getActivity().getTabModelSelector().selectModel(true);
+            FeatureUtilities.setStartSurfaceEnabledForTesting(false);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            int itemGroupId = item.getGroupId();
+            if (itemGroupId == R.id.OVERVIEW_MODE_MENU) {
+                int itemId = item.getItemId();
+                assertTrue(itemId == R.id.new_tab_menu_id
+                        || itemId == R.id.new_incognito_tab_menu_id
+                        || itemId == R.id.close_all_tabs_menu_id
+                        || itemId == R.id.close_all_incognito_tabs_menu_id
+                        || itemId == R.id.menu_group_tabs || itemId == R.id.preferences_id);
+                if (itemId == R.id.close_all_tabs_menu_id) {
+                    assertFalse(item.isVisible());
+                } else {
+                    assertTrue(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(6));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testAllMenuItemsWithStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(true);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            int itemGroupId = item.getGroupId();
+            if (itemGroupId == R.id.START_SURFACE_MODE_MENU) {
+                int itemId = item.getItemId();
+                assertTrue(itemId == R.id.new_tab_menu_id
+                        || itemId == R.id.new_incognito_tab_menu_id
+                        || itemId == R.id.all_bookmarks_menu_id
+                        || itemId == R.id.recent_tabs_menu_id || itemId == R.id.open_history_menu_id
+                        || itemId == R.id.downloads_menu_id || itemId == R.id.close_all_tabs_menu_id
+                        || itemId == R.id.close_all_incognito_tabs_menu_id
+                        || itemId == R.id.menu_group_tabs || itemId == R.id.preferences_id);
+                if (itemId == R.id.close_all_incognito_tabs_menu_id) {
+                    assertFalse(item.isVisible());
+                } else {
+                    assertTrue(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(10));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testIncognitoAllMenuItemsWithStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mActivityTestRule.getActivity().getTabModelSelector().selectModel(true);
+            FeatureUtilities.setStartSurfaceEnabledForTesting(true);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            int itemGroupId = item.getGroupId();
+            if (itemGroupId == R.id.START_SURFACE_MODE_MENU) {
+                int itemId = item.getItemId();
+                assertTrue(itemId == R.id.new_tab_menu_id
+                        || itemId == R.id.new_incognito_tab_menu_id
+                        || itemId == R.id.all_bookmarks_menu_id
+                        || itemId == R.id.recent_tabs_menu_id || itemId == R.id.open_history_menu_id
+                        || itemId == R.id.downloads_menu_id || itemId == R.id.close_all_tabs_menu_id
+                        || itemId == R.id.close_all_incognito_tabs_menu_id
+                        || itemId == R.id.menu_group_tabs || itemId == R.id.preferences_id);
+                if (itemId == R.id.close_all_tabs_menu_id || itemId == R.id.recent_tabs_menu_id) {
+                    assertFalse(item.isVisible());
+                } else {
+                    assertTrue(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(10));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testGroupTabsIsDisabled() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(false);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(false);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            if (item.getItemId() == R.id.menu_group_tabs) {
+                assertFalse(item.isVisible());
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(2));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testGroupTabsIsEnabled() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(false);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            if (item.getItemId() == R.id.menu_group_tabs) {
+                int itemGroupId = item.getGroupId();
+                if (itemGroupId == R.id.OVERVIEW_MODE_MENU) {
+                    assertTrue(item.isVisible());
+                }
+                if (itemGroupId == R.id.START_SURFACE_MODE_MENU) {
+                    assertFalse(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(2));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testGroupTabsIsDisabledWithStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(true);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(false);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            if (item.getItemId() == R.id.menu_group_tabs) {
+                assertFalse(item.isVisible());
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(2));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
+    public void testGroupTabsIsEnabledWithStartSurface() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            FeatureUtilities.setStartSurfaceEnabledForTesting(true);
+            FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(
+                    mActivityTestRule.getAppMenuCoordinator(), null, false, false);
+        });
+
+        int checkedMenuItems = 0;
+        Menu menu = mActivityTestRule.getMenu();
+        for (int i = 0; i < menu.size(); ++i) {
+            MenuItem item = menu.getItem(i);
+            if (item.getItemId() == R.id.menu_group_tabs) {
+                int itemGroupId = item.getGroupId();
+                if (itemGroupId == R.id.OVERVIEW_MODE_MENU) {
+                    assertFalse(item.isVisible());
+                }
+                if (itemGroupId == R.id.START_SURFACE_MODE_MENU) {
+                    assertTrue(item.isVisible());
+                }
+                checkedMenuItems++;
+            }
+        }
+        assertThat(checkedMenuItems, equalTo(2));
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java
index ca6a4ae..c158fe0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkReorderTest.java
@@ -32,7 +32,7 @@
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.BookmarkPromoHeader.PromoState;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.ui.widget.listmenu.ListMenuButton;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar.ViewType;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
@@ -45,6 +45,7 @@
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.browser.test.util.TouchCommon;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -74,7 +75,7 @@
     @Override
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
@@ -1030,4 +1031,4 @@
     protected void searchBookmarks(final String query) {
         TestThreadUtils.runOnUiThreadBlocking(() -> getReorderAdapter().search(query));
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
index 4137ff1..9fbccb7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -41,7 +41,7 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
 import org.chromium.chrome.browser.tab.TabImpl;
 import org.chromium.chrome.browser.util.UrlConstants;
@@ -50,9 +50,9 @@
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.util.ActivityUtils;
 import org.chromium.chrome.test.util.BookmarkTestUtil;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.MenuUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
 import org.chromium.components.bookmarks.BookmarkId;
@@ -63,6 +63,7 @@
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.browser.test.util.TouchCommon;
 import org.chromium.net.test.EmbeddedTestServer;
+import org.chromium.ui.test.util.NightModeTestUtils;
 import org.chromium.ui.test.util.UiRestriction;
 
 import java.util.ArrayList;
@@ -85,7 +86,7 @@
             new ChromeActivityTestRule<>(ChromeActivity.class);
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     protected static final String TEST_PAGE_URL_GOOGLE = "/chrome/test/data/android/google.html";
     protected static final String TEST_PAGE_TITLE_GOOGLE = "The Google";
@@ -105,12 +106,12 @@
 
     @BeforeClass
     public static void setUpBeforeActivityLaunched() {
-        NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
+        ChromeNightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
     }
 
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
@@ -161,7 +162,7 @@
 
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
-        NightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
+        ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
     }
 
     protected void openBookmarkManager() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuRenderTest.java
index 699b634..388c513 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuRenderTest.java
@@ -22,15 +22,15 @@
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.contextmenu.RevampedContextMenuCoordinator.ListItemType;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.ModelListAdapter;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.io.IOException;
 import java.util.List;
@@ -46,7 +46,7 @@
             new NightModeTestUtils.NightModeParams().getParameters();
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private ModelListAdapter mAdapter;
     private ModelList mListItems;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 8a5c9a1d..cf3cca41 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -73,6 +73,7 @@
 import org.chromium.chrome.browser.gsa.GSAContextDisplaySelection;
 import org.chromium.chrome.browser.locale.LocaleManager;
 import org.chromium.chrome.browser.omnibox.UrlBar;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
@@ -1002,10 +1003,11 @@
     private void resetCounters() {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-            boolean freStatus = prefs.getBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, false);
+            boolean freStatus =
+                    prefs.getBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, false);
             prefs.edit()
                     .clear()
-                    .putBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, freStatus)
+                    .putBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, freStatus)
                     .apply();
         });
     }
@@ -2895,7 +2897,17 @@
     @Feature({"ContextualSearch"})
     public void testDictionaryDefinitions() throws InterruptedException, TimeoutException {
         runDictionaryCardTest(CardTag.CT_DEFINITION);
-        closePanel();
+    }
+
+    /**
+     * Tests that the flow for showing dictionary definitions works, and that tapping in the
+     * bar just opens the panel instead of taking some action.
+     */
+    @Test
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    public void testContextualDictionaryDefinitions()
+            throws InterruptedException, TimeoutException {
         runDictionaryCardTest(CardTag.CT_CONTEXTUAL_DEFINITION);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java
new file mode 100644
index 0000000..cc614f7
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java
@@ -0,0 +1,201 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.customtabs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.ActivityState;
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
+import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
+import org.chromium.base.test.params.ParameterSet;
+import org.chromium.base.test.params.ParameterizedRunner;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.DeferredStartupHandler;
+import org.chromium.chrome.browser.browserservices.TrustedWebActivityTestUtil;
+import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
+import org.chromium.chrome.browser.customtabs.content.TabCreationMode;
+import org.chromium.chrome.browser.customtabs.dependency_injection.BaseCustomTabActivityComponent;
+import org.chromium.chrome.browser.flags.ActivityType;
+import org.chromium.chrome.browser.lifecycle.InflationObserver;
+import org.chromium.chrome.browser.tab.EmptyTabObserver;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabObserver;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorBase;
+import org.chromium.chrome.browser.webapps.WebappActivityTestRule;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Tests that when DeferredStartupHandler#queueDeferredTasksOnIdleHandler() is run that the
+ * activity's tab has finished loading.
+ */
+@RunWith(ParameterizedRunner.class)
+@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public class CustomTabDeferredStartupTest {
+    static class PageLoadFinishedTabObserver extends EmptyTabObserver {
+        private boolean mIsPageLoadFinished;
+
+        @Override
+        public void onPageLoadFinished(Tab tab, String url) {
+            mIsPageLoadFinished = true;
+        }
+
+        public boolean isPageLoadFinished() {
+            return mIsPageLoadFinished;
+        }
+    }
+
+    static class InitialTabCreationObserver extends CustomTabActivityTabProvider.Observer {
+        private TabObserver mObserver;
+
+        public InitialTabCreationObserver(TabObserver observer) {
+            mObserver = observer;
+        }
+
+        @Override
+        public void onInitialTabCreated(@NonNull Tab tab, @TabCreationMode int mode) {
+            tab.addObserver(mObserver);
+        }
+    }
+
+    static class NewTabObserver extends EmptyTabModelSelectorObserver
+            implements ApplicationStatus.ActivityStateListener, InflationObserver {
+        private BaseCustomTabActivity mActivity;
+        private TabObserver mObserver;
+
+        public NewTabObserver(TabObserver observer) {
+            mObserver = observer;
+        }
+
+        @Override
+        public void onNewTabCreated(Tab tab) {
+            tab.addObserver(mObserver);
+        }
+
+        @Override
+        public void onActivityStateChange(Activity activity, @ActivityState int newState) {
+            if (newState == ActivityState.CREATED && activity instanceof BaseCustomTabActivity
+                    && mActivity == null) {
+                mActivity = (BaseCustomTabActivity) activity;
+                mActivity.getLifecycleDispatcher().register(this);
+            }
+        }
+
+        @Override
+        public void onPreInflationStartup() {
+            BaseCustomTabActivityComponent baseCustomTabActivityComponent =
+                    (BaseCustomTabActivityComponent) mActivity.getComponent();
+            baseCustomTabActivityComponent.resolveTabProvider().addObserver(
+                    new InitialTabCreationObserver(mObserver));
+        }
+
+        @Override
+        public void onPostInflationStartup() {}
+    }
+
+    static class PageIsLoadedDeferredStartupHandler extends DeferredStartupHandler {
+        public PageIsLoadedDeferredStartupHandler(
+                PageLoadFinishedTabObserver observer, CallbackHelper helper) {
+            mObserver = observer;
+            mHelper = helper;
+        }
+
+        @Override
+        public void queueDeferredTasksOnIdleHandler() {
+            Assert.assertTrue("Page is yet to finish loading.", mObserver.isPageLoadFinished());
+
+            mHelper.notifyCalled();
+
+            super.queueDeferredTasksOnIdleHandler();
+        }
+
+        private CallbackHelper mHelper;
+        private PageLoadFinishedTabObserver mObserver;
+    }
+
+    @ClassParameter
+    public static List<ParameterSet> sClassParams = Arrays.asList(
+            new ParameterSet().value(ActivityType.WEBAPP).name("Webapp"),
+            new ParameterSet().value(ActivityType.CUSTOM_TAB).name("CustomTab"),
+            new ParameterSet().value(ActivityType.TRUSTED_WEB_ACTIVITY).name("TrustedWebActivity"));
+
+    private @ActivityType int mActivityType;
+
+    @Rule
+    public final ChromeActivityTestRule mActivityTestRule;
+
+    public CustomTabDeferredStartupTest(@ActivityType int activityType) {
+        mActivityType = activityType;
+        mActivityTestRule = (activityType == ActivityType.WEBAPP) ? new WebappActivityTestRule()
+                                                                  : new CustomTabActivityTestRule();
+    }
+
+    private void launchActivity() throws TimeoutException {
+        if (mActivityType == ActivityType.WEBAPP) {
+            launchWebapp((WebappActivityTestRule) mActivityTestRule);
+            return;
+        }
+
+        CustomTabActivityTestRule customTabActivityTestRule =
+                (CustomTabActivityTestRule) mActivityTestRule;
+        if (mActivityType == ActivityType.CUSTOM_TAB) {
+            launchCct(customTabActivityTestRule);
+            return;
+        }
+        launchTwa(customTabActivityTestRule);
+    }
+
+    private void launchWebapp(WebappActivityTestRule activityTestRule) {
+        activityTestRule.startWebappActivity();
+    }
+
+    private void launchCct(CustomTabActivityTestRule activityTestRule) {
+        activityTestRule.startCustomTabActivityWithIntent(
+                CustomTabsTestUtils.createMinimalCustomTabIntent(
+                        InstrumentationRegistry.getTargetContext(), "about:blank"));
+    }
+
+    private void launchTwa(CustomTabActivityTestRule activityTestRule) throws TimeoutException {
+        String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
+        Intent intent = TrustedWebActivityTestUtil.createTrustedWebActivityIntent("about:blank");
+        TrustedWebActivityTestUtil.spoofVerification(packageName, "about:blank");
+        TrustedWebActivityTestUtil.createSession(intent, packageName);
+        activityTestRule.startCustomTabActivityWithIntent(intent);
+    }
+
+    @Test
+    @LargeTest
+    public void testPageIsLoadedOnDeferredStartup() throws Exception {
+        PageLoadFinishedTabObserver tabObserver = new PageLoadFinishedTabObserver();
+        NewTabObserver newTabObserver = new NewTabObserver(tabObserver);
+        TabModelSelectorBase.setObserverForTests(newTabObserver);
+        ApplicationStatus.registerStateListenerForAllActivities(newTabObserver);
+        CallbackHelper helper = new CallbackHelper();
+        PageIsLoadedDeferredStartupHandler handler =
+                new PageIsLoadedDeferredStartupHandler(tabObserver, helper);
+        DeferredStartupHandler.setInstanceForTests(handler);
+        launchActivity();
+        helper.waitForCallback(0);
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java
index 9e35070a..2c0aecb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionAvailabilityWebappTest.java
@@ -15,6 +15,7 @@
 import org.junit.runner.RunWith;
 
 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.chrome.browser.ChromeActivity;
@@ -45,6 +46,7 @@
     @Test
     @MediumTest
     @Feature({"DirectActions"})
+    @DisabledTest(message = "crbug.com/1033006")
     public void testCoreDirectActionInWebappActivity() throws Exception {
         mWebAppActivityTestRule.startWebappActivity();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionsInActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionsInActivityTest.java
index 5778dc8..1b57512 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionsInActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/directactions/DirectActionsInActivityTest.java
@@ -21,6 +21,7 @@
 
 import org.chromium.base.Callback;
 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.MetricsUtils.HistogramDelta;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
@@ -63,6 +64,7 @@
     @Test
     @MediumTest
     @Feature({"DirectActions"})
+    @DisabledTest(message = "crbug.com/1034712")
     public void testDirectActionsDisabled() throws Exception {
         // disableDirectActions() makes AppHooks.createDirectActionCoordinator return null. This
         // should mean that direct actions are not available.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java
index bc59f29b..633a8aa 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java
@@ -35,16 +35,17 @@
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.util.UrlConstants;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.util.ArrayList;
 
@@ -83,8 +84,7 @@
             new ChromeActivityTestRule<>(ChromeActivity.class);
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private Tab mTab;
     private RecyclerView mRecyclerView;
@@ -92,12 +92,12 @@
 
     @BeforeClass
     public static void setUpBeforeActivityLaunched() {
-        NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
+        ChromeNightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
     }
 
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
@@ -122,7 +122,7 @@
 
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
-        NightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
+        ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
     }
 
     private int getFirstVisiblePosition() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
index 51b2514..98db331d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -557,9 +557,9 @@
         // user setting will be reset.
         final Account account = SigninTestUtil.addTestAccount();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            IdentityServicesProvider.getSigninManager().onFirstRunCheckDone();
-            IdentityServicesProvider.getSigninManager().addSignInStateObserver(mTestObserver);
-            IdentityServicesProvider.getSigninManager().signIn(
+            IdentityServicesProvider.get().getSigninManager().onFirstRunCheckDone();
+            IdentityServicesProvider.get().getSigninManager().addSignInStateObserver(mTestObserver);
+            IdentityServicesProvider.get().getSigninManager().signIn(
                     SigninAccessPoint.UNKNOWN, account, null);
         });
 
@@ -615,7 +615,7 @@
         int currentCallCount = mTestObserver.onSigninStateChangedCallback.getCallCount();
         TestThreadUtils.runOnUiThreadBlocking(
                 ()
-                        -> IdentityServicesProvider.getSigninManager().signOut(
+                        -> IdentityServicesProvider.get().getSigninManager().signOut(
                                 SignoutReason.SIGNOUT_TEST));
         mTestObserver.onSigninStateChangedCallback.waitForCallback(currentCallCount, 1);
         Assert.assertNull(SigninTestUtil.getCurrentAccount());
@@ -623,7 +623,8 @@
         // Remove observer
         TestThreadUtils.runOnUiThreadBlocking(
                 ()
-                        -> IdentityServicesProvider.getSigninManager().removeSignInStateObserver(
-                                mTestObserver));
+                        -> IdentityServicesProvider.get()
+                                   .getSigninManager()
+                                   .removeSignInStateObserver(mTestObserver));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java
index daca58f..7ffdf384 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewRenderTest.java
@@ -29,10 +29,7 @@
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils.NightModeParams;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.components.browser_ui.modaldialog.ModalDialogTestUtils;
 import org.chromium.components.browser_ui.modaldialog.ModalDialogView;
 import org.chromium.components.browser_ui.modaldialog.test.R;
@@ -41,6 +38,8 @@
 import org.chromium.ui.modaldialog.ModalDialogProperties;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
+import org.chromium.ui.test.util.NightModeTestUtils;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -53,7 +52,8 @@
 @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
 public class ModalDialogViewRenderTest extends DummyUiActivityTestCase {
     @ParameterAnnotations.ClassParameter
-    private static List<ParameterSet> sClassParams = new NightModeParams().getParameters();
+    private static List<ParameterSet> sClassParams =
+            new NightModeTestUtils.NightModeParams().getParameters();
 
     private final @ColorInt int mFakeBgColor;
 
@@ -91,7 +91,7 @@
             mContentView = new FrameLayout(activity);
             mModalDialogView =
                     (ModalDialogView) LayoutInflater.from(new ContextThemeWrapper(activity, style))
-                            .inflate(org.chromium.chrome.R.layout.modal_dialog_view, null);
+                            .inflate(R.layout.modal_dialog_view, null);
             mModalDialogView.setBackgroundColor(mFakeBgColor);
             activity.setContentView(mContentView);
             mContentView.addView(mModalDialogView, MATCH_PARENT, WRAP_CONTENT);
@@ -108,13 +108,10 @@
     @MediumTest
     @Feature({"ModalDialog", "RenderTest"})
     public void testRender_TitleAndTitleIcon() throws IOException {
-        setUpViews(org.chromium.chrome.R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
-        final Drawable icon =
-                UiUtils.getTintedDrawable(getActivity(), org.chromium.chrome.R.drawable.ic_add,
-                        org.chromium.chrome.R.color.default_icon_color);
-        createModel(mModelBuilder
-                            .with(ModalDialogProperties.TITLE, mResources,
-                                    org.chromium.chrome.R.string.title)
+        setUpViews(R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
+        final Drawable icon = UiUtils.getTintedDrawable(
+                getActivity(), R.drawable.ic_add, R.color.default_icon_color);
+        createModel(mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title)
                             .with(ModalDialogProperties.TITLE_ICON, icon));
         mRenderTestRule.render(mModalDialogView, "title_and_title_icon");
     }
@@ -123,17 +120,15 @@
     @MediumTest
     @Feature({"ModalDialog", "RenderTest"})
     public void testRender_TitleAndMessage() throws IOException {
-        setUpViews(org.chromium.chrome.R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
-        createModel(mModelBuilder
-                            .with(ModalDialogProperties.TITLE, mResources,
-                                    org.chromium.chrome.R.string.title)
-                            .with(ModalDialogProperties.MESSAGE,
-                                    TextUtils.join("\n", Collections.nCopies(100, "Message")))
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.ok)
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true)
-                            .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.cancel));
+        setUpViews(R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
+        createModel(
+                mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title)
+                        .with(ModalDialogProperties.MESSAGE,
+                                TextUtils.join("\n", Collections.nCopies(100, "Message")))
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources, R.string.ok)
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true)
+                        .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, mResources,
+                                R.string.cancel));
         mRenderTestRule.render(mModalDialogView, "title_and_message");
     }
 
@@ -141,17 +136,15 @@
     @MediumTest
     @Feature({"ModalDialog", "RenderTest"})
     public void testRender_FilledPrimaryButton() throws IOException {
-        setUpViews(org.chromium.chrome.R.style.Theme_Chromium_ModalDialog_FilledPrimaryButton);
-        createModel(mModelBuilder
-                            .with(ModalDialogProperties.TITLE, mResources,
-                                    org.chromium.chrome.R.string.title)
-                            .with(ModalDialogProperties.MESSAGE,
-                                    TextUtils.join("\n", Collections.nCopies(100, "Message")))
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.ok)
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true)
-                            .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.cancel));
+        setUpViews(R.style.Theme_Chromium_ModalDialog_FilledPrimaryButton);
+        createModel(
+                mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title)
+                        .with(ModalDialogProperties.MESSAGE,
+                                TextUtils.join("\n", Collections.nCopies(100, "Message")))
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources, R.string.ok)
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true)
+                        .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, mResources,
+                                R.string.cancel));
         mRenderTestRule.render(mModalDialogView, "filled_primary_button");
     }
 
@@ -159,15 +152,13 @@
     @MediumTest
     @Feature({"ModalDialog", "RenderTest"})
     public void testRender_ScrollableTitle() throws IOException {
-        setUpViews(org.chromium.chrome.R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
-        createModel(mModelBuilder
-                            .with(ModalDialogProperties.TITLE, mResources,
-                                    org.chromium.chrome.R.string.title)
-                            .with(ModalDialogProperties.TITLE_SCROLLABLE, true)
-                            .with(ModalDialogProperties.MESSAGE,
-                                    TextUtils.join("\n", Collections.nCopies(100, "Message")))
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.ok));
+        setUpViews(R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
+        createModel(
+                mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title)
+                        .with(ModalDialogProperties.TITLE_SCROLLABLE, true)
+                        .with(ModalDialogProperties.MESSAGE,
+                                TextUtils.join("\n", Collections.nCopies(100, "Message")))
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources, R.string.ok));
         mRenderTestRule.render(mModalDialogView, "scrollable_title");
     }
 
@@ -175,18 +166,16 @@
     @MediumTest
     @Feature({"ModalDialog", "RenderTest"})
     public void testRender_CustomView() throws IOException {
-        setUpViews(org.chromium.chrome.R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
+        setUpViews(R.style.Theme_Chromium_ModalDialog_TextPrimaryButton);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mCustomTextView1.setText(
                     TextUtils.join("\n", Collections.nCopies(100, "Custom Message")));
             mCustomScrollView.addView(mCustomTextView1);
         });
-        createModel(mModelBuilder
-                            .with(ModalDialogProperties.TITLE, mResources,
-                                    org.chromium.chrome.R.string.title)
-                            .with(ModalDialogProperties.CUSTOM_VIEW, mCustomScrollView)
-                            .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources,
-                                    org.chromium.chrome.R.string.ok));
+        createModel(
+                mModelBuilder.with(ModalDialogProperties.TITLE, mResources, R.string.title)
+                        .with(ModalDialogProperties.CUSTOM_VIEW, mCustomScrollView)
+                        .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mResources, R.string.ok));
         mRenderTestRule.render(mModalDialogView, "custom_view");
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/TabModalPresenterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/TabModalPresenterTest.java
index 54079073..c707120 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/TabModalPresenterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/TabModalPresenterTest.java
@@ -47,6 +47,7 @@
 import org.chromium.chrome.browser.omnibox.UrlBar;
 import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
@@ -81,7 +82,7 @@
         }
 
         @Override
-        public void onInteractabilityChanged(boolean isInteractable) {
+        public void onInteractabilityChanged(Tab tab, boolean isInteractable) {
             onTabInteractabilityChangedCallback.notifyCalled();
         }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/ChromeNightModeTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/ChromeNightModeTestUtils.java
new file mode 100644
index 0000000..bd9c007
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/ChromeNightModeTestUtils.java
@@ -0,0 +1,45 @@
+// 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.
+
+package org.chromium.chrome.browser.night_mode;
+
+import org.chromium.chrome.browser.flags.FeatureUtilities;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+import org.chromium.chrome.browser.settings.themes.ThemeType;
+
+/**
+ * Helper methods to be used in tests to specify night mode state. See also {@link
+ * org.chromium.ui.test.util.NightModeTestUtils}.
+ */
+public class ChromeNightModeTestUtils {
+    /**
+     * Sets up initial states for night mode before
+     * {@link org.chromium.chrome.browser.ChromeActivity} is launched.
+     */
+    public static void setUpNightModeBeforeChromeActivityLaunched() {
+        FeatureUtilities.setNightModeAvailableForTesting(true);
+        NightModeUtils.setNightModeSupportedForTesting(true);
+    }
+
+    /**
+     * Sets up the night mode state for {@link org.chromium.chrome.browser.ChromeActivity}.
+     * @param nightModeEnabled Whether night mode should be enabled.
+     */
+    public static void setUpNightModeForChromeActivity(boolean nightModeEnabled) {
+        SharedPreferencesManager.getInstance().writeInt(ChromePreferenceKeys.UI_THEME_SETTING_KEY,
+                nightModeEnabled ? ThemeType.DARK : ThemeType.LIGHT);
+    }
+
+    /**
+     * Resets the night mode state after {@link org.chromium.chrome.browser.ChromeActivity} is
+     * destroyed.
+     */
+    public static void tearDownNightModeAfterChromeActivityDestroyed() {
+        FeatureUtilities.setNightModeAvailableForTesting(null);
+        NightModeUtils.setNightModeSupportedForTesting(null);
+        GlobalNightModeStateProviderHolder.resetInstanceForTesting();
+        SharedPreferencesManager.getInstance().removeKey(ChromePreferenceKeys.UI_THEME_SETTING_KEY);
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
deleted file mode 100644
index 7b90265..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.night_mode;
-
-import android.support.v7.app.AppCompatDelegate;
-
-import org.chromium.base.test.params.ParameterProvider;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.chrome.browser.flags.FeatureUtilities;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.settings.themes.ThemeType;
-import org.chromium.ui.test.util.DummyUiActivity;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Helper methods to be used in tests to specify night mode state.
- */
-public class NightModeTestUtils {
-    /**
-     * {@link ParameterProvider} used for parameterized test that provides the night mode state.
-     */
-    public static class NightModeParams implements ParameterProvider {
-        private static List<ParameterSet> sNightModeParams =
-                Arrays.asList(new ParameterSet().value(false).name("NightModeDisabled"),
-                        new ParameterSet().value(true).name("NightModeEnabled"));
-
-        @Override
-        public List<ParameterSet> getParameters() {
-            return sNightModeParams;
-        }
-    }
-
-    /**
-     * Sets up the night mode state for {@link DummyUiActivity}.
-     * @param nightModeEnabled Whether night mode should be enabled.
-     */
-    public static void setUpNightModeForDummyUiActivity(boolean nightModeEnabled) {
-        AppCompatDelegate.setDefaultNightMode(nightModeEnabled ? AppCompatDelegate.MODE_NIGHT_YES
-                                                               : AppCompatDelegate.MODE_NIGHT_NO);
-    }
-
-    /**
-     * Resets the night mode state for {@link DummyUiActivity}.
-     */
-    public static void tearDownNightModeForDummyUiActivity() {
-        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
-    }
-
-    /**
-     * Sets up initial states for night mode before
-     * {@link org.chromium.chrome.browser.ChromeActivity} is launched.
-     */
-    public static void setUpNightModeBeforeChromeActivityLaunched() {
-        FeatureUtilities.setNightModeAvailableForTesting(true);
-        NightModeUtils.setNightModeSupportedForTesting(true);
-    }
-
-    /**
-     * Sets up the night mode state for {@link org.chromium.chrome.browser.ChromeActivity}.
-     * @param nightModeEnabled Whether night mode should be enabled.
-     */
-    public static void setUpNightModeForChromeActivity(boolean nightModeEnabled) {
-        SharedPreferencesManager.getInstance().writeInt(ChromePreferenceKeys.UI_THEME_SETTING_KEY,
-                nightModeEnabled ? ThemeType.DARK : ThemeType.LIGHT);
-    }
-
-    /**
-     * Resets the night mode state after {@link org.chromium.chrome.browser.ChromeActivity} is
-     * destroyed.
-     */
-    public static void tearDownNightModeAfterChromeActivityDestroyed() {
-        FeatureUtilities.setNightModeAvailableForTesting(null);
-        NightModeUtils.setNightModeSupportedForTesting(null);
-        GlobalNightModeStateProviderHolder.resetInstanceForTesting();
-        SharedPreferencesManager.getInstance().removeKey(ChromePreferenceKeys.UI_THEME_SETTING_KEY);
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
index 66c0d7f6..aa4903a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -69,10 +69,10 @@
 import org.chromium.chrome.browser.widget.ScrimView;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
 import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
@@ -119,8 +119,7 @@
     public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     /** Parameter provider for enabling/disabling "Interest Feed Content Suggestions". */
     public static class InterestFeedParams implements ParameterProvider {
@@ -201,7 +200,7 @@
     @Feature({"NewTabPage", "RenderTest"})
     public void testRender() throws IOException {
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        RenderTestRule.sanitize(mNtp.getView());
+        ChromeRenderTestRule.sanitize(mNtp.getView());
         mRenderTestRule.render(mTileGridLayout, "most_visited");
         mRenderTestRule.render(mFakebox, "fakebox");
         mRenderTestRule.render(mNtp.getView().getRootView(), "new_tab_page");
@@ -219,7 +218,7 @@
         ScrimView scrimView = mActivityTestRule.getActivity().getScrim();
         scrimView.disableAnimationForTesting(true);
         onView(withId(R.id.search_box)).perform(click());
-        RenderTestRule.sanitize(mNtp.getView().getRootView());
+        ChromeRenderTestRule.sanitize(mNtp.getView().getRootView());
         mRenderTestRule.render(mNtp.getView().getRootView(), "focus_fake_box");
         scrimView.disableAnimationForTesting(false);
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
index 488196a..826f74c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -44,7 +44,7 @@
 import org.chromium.chrome.browser.favicon.IconType;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
 import org.chromium.chrome.browser.native_page.ContextMenuManager;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.ntp.cards.PersonalizedPromoViewHolder;
 import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo;
@@ -66,7 +66,7 @@
 import org.chromium.chrome.browser.widget.ThumbnailProvider;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.browser.compositor.layouts.DisableChromeAnimations;
 import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
@@ -75,6 +75,7 @@
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.NetworkChangeNotifier;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -96,7 +97,7 @@
             new ChromeActivityTestRule<>(ChromeActivity.class);
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     @Rule
     public TestRule mDisableChromeAnimations = new DisableChromeAnimations();
@@ -120,12 +121,12 @@
 
     @BeforeClass
     public static void setUpBeforeActivityLaunched() {
-        NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
+        ChromeNightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
     }
 
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
@@ -173,7 +174,7 @@
 
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
-        NightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
+        ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewRenderTest.java
index a937a91..5188f3e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewRenderTest.java
@@ -23,7 +23,7 @@
 import org.chromium.chrome.browser.toolbar.LocationBarModel;
 import org.chromium.chrome.browser.ui.widget.CompositeTouchDelegate;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
@@ -34,8 +34,7 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 public class StatusViewRenderTest extends DummyUiActivityTestCase {
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private StatusView mStatusView;
     private PropertyModel mStatusModel;
@@ -115,4 +114,4 @@
 
         mRenderTestRule.render(mStatusView, "status_view_verbose_padding_with_dse_icon");
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
index 3f4cf30..ea17fd9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
@@ -27,13 +27,14 @@
 import org.chromium.chrome.browser.autofill.CardType;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.MainActivityStartCallback;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
+import org.chromium.ui.test.util.NightModeTestUtils;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.util.concurrent.TimeoutException;
 
@@ -58,12 +59,12 @@
 
     @BeforeClass
     public static void setUpBeforeActivityLaunched() {
-        NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
+        ChromeNightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
     }
 
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
@@ -74,7 +75,7 @@
 
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
-        NightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
+        ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
     }
 
     @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
index df1f75b..fcc15060e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
@@ -28,9 +28,10 @@
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.MainActivityStartCallback;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.util.concurrent.TimeoutException;
 
@@ -152,7 +153,7 @@
         mPaymentRequestTestRule.getKeyboardDelegate().hideKeyboard(
                 mPaymentRequestTestRule.getEditorDialogView());
 
-        RenderTestRule.sanitize(mPaymentRequestTestRule.getEditorDialogView());
+        ChromeRenderTestRule.sanitize(mPaymentRequestTestRule.getEditorDialogView());
         mRenderTestRule.render(mPaymentRequestTestRule.getEditorDialogView(),
                 "retry_with_shipping_address_errors");
 
@@ -199,7 +200,7 @@
         mPaymentRequestTestRule.getKeyboardDelegate().hideKeyboard(
                 mPaymentRequestTestRule.getEditorDialogView());
 
-        RenderTestRule.sanitize(mPaymentRequestTestRule.getEditorDialogView());
+        ChromeRenderTestRule.sanitize(mPaymentRequestTestRule.getEditorDialogView());
         mRenderTestRule.render(
                 mPaymentRequestTestRule.getEditorDialogView(), "retry_with_payer_errors");
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java
index c538657..cd6815a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java
@@ -19,11 +19,11 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
+import org.chromium.ui.test.util.RenderTestRule;
 
 /** Tests for the microtransaction view binder. */
 @RunWith(ChromeJUnit4ClassRunner.class)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/SiteSettingsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/SiteSettingsPreferencesTest.java
index 66862f9..b409c6c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/SiteSettingsPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/website/SiteSettingsPreferencesTest.java
@@ -35,6 +35,7 @@
 import org.chromium.chrome.browser.settings.ChromeBaseCheckBoxPreference;
 import org.chromium.chrome.browser.settings.ChromeSwitchPreference;
 import org.chromium.chrome.browser.settings.LocationSettings;
+import org.chromium.chrome.browser.settings.NfcSystemLevelSetting;
 import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -521,6 +522,9 @@
     @EnableFeatures("QuietNotificationPrompts")
     @DisabledTest(message = "Flaky. crbug.com/1030218")
     public void testOnlyExpectedPreferencesShown() {
+        LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
+        NfcSystemLevelSetting.setNfcSettingForTesting(true);
+
         // If you add a category in the SiteSettings UI, please add a test for it below.
         Assert.assertEquals(19, SiteSettingsCategory.Type.NUM_ENTRIES);
 
@@ -528,6 +532,8 @@
         String[] binaryToggle = new String[] {"binary_toggle"};
         String[] binaryToggleWithException = new String[] {"binary_toggle", "add_exception"};
         String[] binaryToggleWithAllowed = new String[] {"binary_toggle", "allowed_group"};
+        String[] binaryToggleWithOsWarningExtra =
+                new String[] {"binary_toggle", "os_permissions_warning_extra"};
         String[] cookie = new String[] {"binary_toggle", "third_party_cookies", "add_exception"};
         String[] protectedMedia = new String[] {"tri_state_toggle", "protected_content_learn_more"};
         String[] notifications_enabled;
@@ -603,12 +609,16 @@
             checkPreferencesForCategory(key, values.second);
         }
 
-        // Location is not the only system-managed permission, but having one test for a
-        // system-managed permission has been shown to catch stray permissons appearing where they
-        // should not.
+        // Disable system location setting and check for the right preferences.
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(false);
-        checkPreferencesForCategory(SiteSettingsCategory.Type.DEVICE_LOCATION, binaryToggle);
+        checkPreferencesForCategory(
+                SiteSettingsCategory.Type.DEVICE_LOCATION, binaryToggleWithOsWarningExtra);
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
+
+        // Disable system nfc setting and check for the right preferences.
+        NfcSystemLevelSetting.setNfcSettingForTesting(false);
+        checkPreferencesForCategory(SiteSettingsCategory.Type.NFC, binaryToggleWithOsWarningExtra);
+        NfcSystemLevelSetting.setNfcSettingForTesting(null);
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java
index 54a9f5e..c84fcfeb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java
@@ -78,8 +78,9 @@
             seedAccountTrackerService();
 
             // Get a reference to the service.
-            mIdentityMutator = IdentityServicesProvider.getSigninManager().getIdentityMutator();
-            mIdentityManager = IdentityServicesProvider.getIdentityManager();
+            mIdentityMutator =
+                    IdentityServicesProvider.get().getSigninManager().getIdentityMutator();
+            mIdentityManager = IdentityServicesProvider.get().getIdentityManager();
         });
     }
 
@@ -122,7 +123,7 @@
         AccountIdProvider provider = AccountIdProvider.getInstance();
         String[] accountNames = {mTestAccount1.getName(), mTestAccount2.getName()};
         String[] accountIds = {mTestAccount1.getGaiaId(), mTestAccount2.getGaiaId()};
-        IdentityServicesProvider.getAccountTrackerService().syncForceRefreshForTest(
+        IdentityServicesProvider.get().getAccountTrackerService().syncForceRefreshForTest(
                 accountIds, accountNames);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ProfileDataCacheRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ProfileDataCacheRenderTest.java
index f8bb3955..abe81ec 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ProfileDataCacheRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ProfileDataCacheRenderTest.java
@@ -30,7 +30,7 @@
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.test.util.FakeProfileDataSource;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -60,8 +60,7 @@
     }
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private FrameLayout mContentView;
     private ImageView mImageView;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java
index 5cbaa1d1..e0a1079 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java
@@ -29,7 +29,7 @@
 import org.chromium.chrome.browser.sync.SyncTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ActivityUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
@@ -49,7 +49,7 @@
     public final SyncTestRule mSyncTestRule = new SyncTestRule();
 
     @Rule
-    public final RenderTestRule mRenderTestRule = new RenderTestRule();
+    public final ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     @Test
     @LargeTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
index 8edc4d2..5b9f9815 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninTest.java
@@ -233,7 +233,7 @@
 
             // Start observing the SigninManager.
             mTestSignInObserver = new TestSignInObserver();
-            mSigninManager = IdentityServicesProvider.getSigninManager();
+            mSigninManager = IdentityServicesProvider.get().getSigninManager();
             mSigninManager.addSignInStateObserver(mTestSignInObserver);
 
             // Get these handles in the UI thread.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java
index 9719f0a..55d6f0e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGridLayoutTest.java
@@ -43,7 +43,7 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.GlobalDiscardableReferencePool;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
+import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback;
 import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
@@ -57,8 +57,8 @@
 import org.chromium.chrome.browser.util.ViewUtils;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.offlinepages.FakeOfflinePageBridge;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
@@ -69,6 +69,7 @@
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.test.EmbeddedTestServerRule;
 import org.chromium.ui.modelutil.ListObservable;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -93,7 +94,7 @@
     public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule();
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private static final String[] FAKE_MOST_VISITED_URLS = new String[] {
             "/chrome/test/data/android/navigate/one.html",
@@ -114,18 +115,18 @@
 
     @BeforeClass
     public static void setUpBeforeActivityLaunched() {
-        NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
+        ChromeNightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched();
     }
 
     @ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)
     public void setupNightMode(boolean nightModeEnabled) {
-        NightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
+        ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled);
         mRenderTestRule.setNightModeEnabled(nightModeEnabled);
     }
 
     @AfterClass
     public static void tearDownAfterActivityDestroyed() {
-        NightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
+        ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed();
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
index a36f9132..272b217 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
@@ -84,7 +84,9 @@
                 new Criteria("Timed out checking that hasPrimaryAccount() == true") {
                     @Override
                     public boolean isSatisfied() {
-                        return IdentityServicesProvider.getIdentityManager().hasPrimaryAccount();
+                        return IdentityServicesProvider.get()
+                                .getIdentityManager()
+                                .hasPrimaryAccount();
                     }
                 },
                 SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
@@ -98,7 +100,9 @@
                 new Criteria("Timed out checking that hasPrimaryAccount() == false") {
                     @Override
                     public boolean isSatisfied() {
-                        return !IdentityServicesProvider.getIdentityManager().hasPrimaryAccount();
+                        return !IdentityServicesProvider.get()
+                                        .getIdentityManager()
+                                        .hasPrimaryAccount();
                     }
                 },
                 SyncTestUtil.TIMEOUT_MS, SyncTestUtil.INTERVAL_MS);
@@ -136,7 +140,7 @@
             String[] accountNames = {oldAccount.name, newAccount.name};
             String[] accountIds = {
                     provider.getAccountId(accountNames[0]), provider.getAccountId(accountNames[1])};
-            IdentityServicesProvider.getAccountTrackerService().syncForceRefreshForTest(
+            IdentityServicesProvider.get().getAccountTrackerService().syncForceRefreshForTest(
                     accountIds, accountNames);
 
             // Starts the rename process. Normally, this is triggered by the broadcast
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
index b944d79d1..72e5ab6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -179,7 +179,7 @@
     public void signOut() throws InterruptedException {
         final Semaphore s = new Semaphore(0);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            IdentityServicesProvider.getSigninManager().signOut(
+            IdentityServicesProvider.get().getSigninManager().signOut(
                     SignoutReason.SIGNOUT_TEST, s::release, false);
         });
         Assert.assertTrue(s.tryAcquire(SyncTestUtil.TIMEOUT_MS, TimeUnit.MILLISECONDS));
@@ -338,7 +338,7 @@
 
     private void signinAndEnableSyncInternal(final Account account, boolean setFirstSetupComplete) {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            IdentityServicesProvider.getSigninManager().signIn(
+            IdentityServicesProvider.get().getSigninManager().signIn(
                     SigninAccessPoint.UNKNOWN, account, new SigninManager.SignInCallback() {
                         @Override
                         public void onSignInComplete() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
index 30932bcd..68b2cffb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
@@ -32,7 +32,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ApplicationTestUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -56,7 +56,7 @@
     private String mUrl;
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     @Before
     public void setUp() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherActionMenuRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherActionMenuRenderTest.java
index 399a362..b9f34971 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherActionMenuRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherActionMenuRenderTest.java
@@ -22,12 +22,12 @@
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
 import org.chromium.chrome.browser.ui.widget.listmenu.ListMenuButton;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.io.IOException;
 import java.util.List;
@@ -43,8 +43,7 @@
             new NightModeTestUtils.NightModeParams().getParameters();
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private View mView;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
index 2d832c02..be11819f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
@@ -33,8 +33,8 @@
 import org.chromium.chrome.browser.vr.util.RenderTestUtils;
 import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
index fda1d46..a8ab734 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
@@ -34,8 +34,8 @@
 import org.chromium.chrome.browser.vr.util.VrShellDelegateUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.net.test.ServerCertificate;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 import java.util.concurrent.TimeoutException;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java
index 1427ab8..a8de66b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java
@@ -45,12 +45,12 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.test.util.ClickUtils;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.DOMUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserWebInputEditingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserWebInputEditingTest.java
index 6d07aa35..4da7a58 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserWebInputEditingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserWebInputEditingTest.java
@@ -33,9 +33,9 @@
 import org.chromium.chrome.browser.vr.util.RenderTestUtils;
 import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.test.util.DOMUtils;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 import java.util.HashMap;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/jsdialog/VrBrowserJavaScriptModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/jsdialog/VrBrowserJavaScriptModalDialogTest.java
index 99720d4..9322c3c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/jsdialog/VrBrowserJavaScriptModalDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/jsdialog/VrBrowserJavaScriptModalDialogTest.java
@@ -29,8 +29,8 @@
 import org.chromium.chrome.browser.vr.util.RenderTestUtils;
 import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.content_public.browser.test.util.JavaScriptUtils;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.IOException;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
index 7a229ed..a5cd086 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
@@ -11,7 +11,7 @@
 import org.junit.Assert;
 
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.ui.test.util.RenderTestRule;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkActivityTest.java
index d669b568..ee56bf4a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkActivityTest.java
@@ -222,9 +222,11 @@
 
         waitForActivityState(webApkActivity, ActivityState.STOPPED);
 
-        TabWebContentsDelegateAndroid tabDelegate =
-                TabTestUtils.getTabWebContentsDelegate(webApkActivity.getActivityTab());
-        tabDelegate.activateContents();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            TabWebContentsDelegateAndroid tabDelegate =
+                    TabTestUtils.getTabWebContentsDelegate(webApkActivity.getActivityTab());
+            tabDelegate.activateContents();
+        });
 
         // WebApkActivity should have been brought back to the foreground.
         ChromeActivityTestRule.waitFor(WebApkActivity.class);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupTest.java
deleted file mode 100644
index 2aa02e19..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.webapps;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.DeferredStartupHandler;
-import org.chromium.chrome.browser.tab.EmptyTabObserver;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorBase;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-
-/**
- * Tests that when WebappActivity#onDeferredStartup() is run, the activity tab has finished loading.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class WebappDeferredStartupTest {
-    static class PageLoadFinishedTabObserver extends EmptyTabObserver {
-        private boolean mIsPageLoadFinished;
-
-        @Override
-        public void onPageLoadFinished(Tab tab, String url) {
-            mIsPageLoadFinished = true;
-        }
-
-        public boolean isPageLoadFinished() {
-            return mIsPageLoadFinished;
-        }
-    }
-
-    static class NewTabCreatedTabModelSelectorObserver extends EmptyTabModelSelectorObserver {
-        public NewTabCreatedTabModelSelectorObserver(PageLoadFinishedTabObserver observer) {
-            mObserver = observer;
-        }
-
-        @Override
-        public void onNewTabCreated(Tab tab) {
-            tab.addObserver(mObserver);
-        }
-
-        private PageLoadFinishedTabObserver mObserver;
-    }
-
-    static class PageIsLoadedDeferredStartupHandler extends DeferredStartupHandler {
-        public PageIsLoadedDeferredStartupHandler(PageLoadFinishedTabObserver observer,
-                CallbackHelper helper) {
-            mObserver = observer;
-            mHelper = helper;
-        }
-
-        @Override
-        public void queueDeferredTasksOnIdleHandler() {
-            Assert.assertTrue("Page is yet to finish loading.", mObserver.isPageLoadFinished());
-
-            mHelper.notifyCalled();
-        }
-
-        private CallbackHelper mHelper;
-        private PageLoadFinishedTabObserver mObserver;
-    }
-
-    @Rule
-    public final WebappActivityTestRule mActivityTestRule = new WebappActivityTestRule();
-
-    @Test
-    @SmallTest
-    @Feature({"Webapps"})
-    public void testPageIsLoadedOnDeferredStartup() throws Exception {
-        PageLoadFinishedTabObserver tabObserver = new PageLoadFinishedTabObserver();
-        TabModelSelectorBase
-                .setObserverForTests(new NewTabCreatedTabModelSelectorObserver(tabObserver));
-        CallbackHelper helper = new CallbackHelper();
-        PageIsLoadedDeferredStartupHandler handler = new PageIsLoadedDeferredStartupHandler(
-                tabObserver, helper);
-        DeferredStartupHandler.setInstanceForTests(handler);
-        mActivityTestRule.startWebappActivity();
-        helper.waitForCallback(0);
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ChromeTextInputLayoutRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ChromeTextInputLayoutRenderTest.java
index 9a96137c..9a3a565 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ChromeTextInputLayoutRenderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ChromeTextInputLayoutRenderTest.java
@@ -22,12 +22,12 @@
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.night_mode.NightModeTestUtils;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
+import org.chromium.ui.test.util.NightModeTestUtils;
 
 import java.io.IOException;
 import java.util.List;
@@ -43,7 +43,7 @@
             new NightModeTestUtils.NightModeParams().getParameters();
 
     @Rule
-    public RenderTestRule mRenderTestRule = new RenderTestRule();
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     private static final String LABEL = "Label";
     private static final String TEXT = "Chrome's own TextInputLayout";
@@ -78,7 +78,7 @@
                     new ContextThemeWrapper(activity, R.style.Theme_Chromium_Settings));
             mInputLayout.addView(mEditText);
             mInputLayout.setHint(LABEL);
-            RenderTestRule.sanitize(mEditText);
+            ChromeRenderTestRule.sanitize(mEditText);
         });
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
index a885546..1a21a14 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
@@ -44,10 +44,10 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
-import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.init.AsyncInitTaskRunner;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.components.signin.ChromeSigninController;
 import org.chromium.content_public.common.ContentProcessInfo;
 
@@ -97,8 +97,8 @@
 
     private void setUpTestPrefs(SharedPreferences prefs) {
         SharedPreferences.Editor editor = prefs.edit();
-        editor.putBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, true);
-        editor.putBoolean(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, false);
+        editor.putBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, true);
+        editor.putBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, false);
         editor.putString(ChromeSigninController.SIGNED_IN_ACCOUNT_KEY, "user1");
         editor.apply();
     }
@@ -157,11 +157,12 @@
         // Check that the right things were written to the backup
         verify(backupData).writeEntityHeader("native.pref1", 1);
         verify(backupData)
-                .writeEntityHeader("AndroidDefault." + FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, 1);
+                .writeEntityHeader(
+                        "AndroidDefault." + ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, 1);
         verify(backupData, times(2)).writeEntityData(new byte[] {1}, 1);
         verify(backupData)
                 .writeEntityHeader(
-                        "AndroidDefault." + FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, 1);
+                        "AndroidDefault." + ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, 1);
         verify(backupData).writeEntityData(new byte[] {0}, 1);
         byte[] unameBytes = ApiCompatibilityUtils.getBytesUtf8("user1");
         verify(backupData)
@@ -176,9 +177,10 @@
         ArrayList<String> names = (ArrayList<String>) newStateStream.readObject();
         assertThat(names.size(), equalTo(4));
         assertThat(names, hasItem("native.pref1"));
-        assertThat(names, hasItem("AndroidDefault." + FirstRunStatus.FIRST_RUN_FLOW_COMPLETE));
+        assertThat(
+                names, hasItem("AndroidDefault." + ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE));
         assertThat(names,
-                hasItem("AndroidDefault." + FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP));
+                hasItem("AndroidDefault." + ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP));
         assertThat(
                 names, hasItem("AndroidDefault." + ChromeSigninController.SIGNED_IN_ACCOUNT_KEY));
         ArrayList<byte[]> values = (ArrayList<byte[]>) newStateStream.readObject();
@@ -290,7 +292,7 @@
 
         // Change some data.
         SharedPreferences.Editor editor = prefs.edit();
-        editor.putBoolean(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, true);
+        editor.putBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, true);
         editor.apply();
 
         // Do a second backup.
@@ -363,7 +365,8 @@
         BackupDataInput backupData = mock(BackupDataInput.class);
 
         final String[] keys = {"native.pref1", "native.pref2",
-                "AndroidDefault." + FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, "AndroidDefault.junk",
+                "AndroidDefault." + ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE,
+                "AndroidDefault.junk",
                 "AndroidDefault." + ChromeSigninController.SIGNED_IN_ACCOUNT_KEY};
         byte[] unameBytes = ApiCompatibilityUtils.getBytesUtf8("user1");
         final byte[][] values = {{0}, {1}, {1}, {23, 42}, unameBytes};
@@ -428,7 +431,7 @@
         // Do a restore.
         mAgent.onRestore(backupData, 0, newState);
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        assertTrue(prefs.getBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, false));
+        assertTrue(prefs.getBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, false));
         assertFalse(prefs.contains("junk"));
         verify(mChromeBackupAgentJniMock)
                 .setBoolBackupPrefs(
@@ -461,7 +464,7 @@
         // Do a restore.
         mAgent.onRestore(backupData, 0, newState);
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        assertFalse(prefs.contains(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE));
+        assertFalse(prefs.contains(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE));
         verify(mChromeBackupAgentJniMock, never())
                 .setBoolBackupPrefs(eq(mAgent), any(String[].class), any(boolean[].class));
         verify(mTaskRunner)
@@ -491,7 +494,7 @@
         // Do a restore.
         mAgent.onRestore(backupData, 0, newState);
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        assertFalse(prefs.contains(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE));
+        assertFalse(prefs.contains(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE));
 
         // Test that the status of the restore has been recorded.
         assertThat(ChromeBackupAgent.getRestoreStatus(),
@@ -516,7 +519,7 @@
         // Do a restore.
         mAgent.onRestore(backupData, 0, newState);
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        assertTrue(prefs.contains(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE));
+        assertTrue(prefs.contains(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE));
 
         // Test that the status of the restore has been recorded.
         assertThat(ChromeBackupAgent.getRestoreStatus(),
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
index 8e5d7f8b..b5ee29de 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
@@ -160,7 +160,7 @@
         verify(mTab).addObserver(mTabObserverCaptor.capture());
         reset(mTab);
 
-        mTabObserverCaptor.getValue().onInteractabilityChanged(true);
+        mTabObserverCaptor.getValue().onInteractabilityChanged(mTab, true);
         verify(mTab).getActivity();
     }
 
@@ -173,7 +173,7 @@
         verify(mTab).addObserver(mTabObserverCaptor.capture());
         reset(mTab);
 
-        mTabObserverCaptor.getValue().onInteractabilityChanged(false);
+        mTabObserverCaptor.getValue().onInteractabilityChanged(mTab, false);
         verify(mTab).getActivity();
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java
index e40317b3..dbecab7 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java
@@ -139,7 +139,7 @@
 
         // Verify that stream is active when tab is user interactable and activity is resumed.
         when(mTab.isUserInteractable()).thenReturn(true);
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(true);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, true);
         verify(mStream, times(1)).onShow();
         verify(mStream, times(1)).onActive();
 
@@ -201,7 +201,7 @@
         verify(mStream, times(1)).onInactive();
 
         // When the Stream is inactive, it won't call Stream#onInactive() again.
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(false);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, false);
         verify(mStream, times(1)).onInactive();
 
         // Verify that the Stream cannot be set shown from inactive.
@@ -213,7 +213,7 @@
         verify(mStream, times(2)).onActive();
 
         // Verify that the Stream can be set inactive from active on tab interactability changed.
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(false);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, false);
         verify(mStream, times(2)).onInactive();
     }
 
@@ -385,26 +385,26 @@
 
         // On tab interactable.
         when(mTab.isUserInteractable()).thenReturn(true);
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(true);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, true);
         inOrder.verify(mStream).onActive();
         verify(mStream, times(1)).onActive();
 
         // On tab un-interactable (simulates user enter the tab switcher).
         when(mTab.isUserInteractable()).thenReturn(false);
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(false);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, false);
         inOrder.verify(mStream).onInactive();
         verify(mStream, times(1)).onInactive();
 
         // On tab interactable (simulates user exit the tab switcher).
         when(mTab.isUserInteractable()).thenReturn(true);
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(true);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, true);
         inOrder.verify(mStream).onActive();
         verify(mStream, times(2)).onActive();
 
         // On tab un-interactable and hidden (simulates user switch to another tab).
         when((mTab).isHidden()).thenReturn(true);
         when(mTab.isUserInteractable()).thenReturn(false);
-        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(false);
+        mNtpStreamLifecycleManager.getTabObserverForTesting().onInteractabilityChanged(mTab, false);
         mNtpStreamLifecycleManager.getTabObserverForTesting().onHidden(mTab, CHANGED_TABS);
         inOrder.verify(mStream).onInactive();
         inOrder.verify(mStream).onHide();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPromptTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPromptTest.java
new file mode 100644
index 0000000..501c3ceb
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/nfc/NfcSystemLevelPromptTest.java
@@ -0,0 +1,145 @@
+// 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.
+
+package org.chromium.chrome.browser.nfc;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.provider.Settings;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.modaldialog.ModalDialogManager;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Tests for the {@link NfcSystemLevelPrompt} class.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+public class NfcSystemLevelPromptTest {
+    private NfcSystemLevelPrompt mNfcSystemLevelPrompt;
+    private Activity mActivity;
+    @Mock
+    private WindowAndroid mWindowAndroid;
+    @Mock
+    private WindowAndroid.IntentCallback mWindowAndroidIntentCallback;
+    private CallbackHelper mDialogCallback = new CallbackHelper();
+    private CallbackHelper mIntentCallback = new CallbackHelper();
+    private MockModalDialogManager mModalDialogManager = new MockModalDialogManager();
+
+    private class MockModalDialogManager extends ModalDialogManager {
+        private PropertyModel mShownDialogModel;
+
+        public MockModalDialogManager() {
+            super(Mockito.mock(Presenter.class), 0);
+        }
+
+        @Override
+        public void showDialog(PropertyModel model, int dialogType) {
+            mShownDialogModel = model;
+        }
+
+        @Override
+        public void dismissDialog(PropertyModel model, int dismissalCause) {
+            model.get(ModalDialogProperties.CONTROLLER).onDismiss(model, dismissalCause);
+        }
+
+        public PropertyModel getShownDialogModel() {
+            return mShownDialogModel;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mActivity = Robolectric.buildActivity(Activity.class).setup().get();
+        doReturn(new WeakReference<>(mActivity)).when(mWindowAndroid).getActivity();
+
+        doAnswer(invocation -> {
+            Object intent = invocation.getArguments()[0];
+            String intentAction = ((Intent) intent).getAction();
+            Assert.assertEquals(intentAction, Settings.ACTION_NFC_SETTINGS);
+
+            Object intentCallback = invocation.getArguments()[1];
+            mWindowAndroidIntentCallback = (WindowAndroid.IntentCallback) intentCallback;
+
+            mIntentCallback.notifyCalled();
+            return null;
+        })
+                .when(mWindowAndroid)
+                .showIntent(any(Intent.class), any(WindowAndroid.IntentCallback.class), isNull());
+
+        doAnswer(invocation -> {
+            mDialogCallback.notifyCalled();
+            return null;
+        })
+                .when(mWindowAndroidIntentCallback)
+                .onIntentCompleted(any(WindowAndroid.class), anyInt(), any(Intent.class));
+
+        mNfcSystemLevelPrompt = new NfcSystemLevelPrompt();
+        mNfcSystemLevelPrompt.show(mWindowAndroid, mModalDialogManager, new Runnable() {
+            @Override
+            public void run() {
+                mDialogCallback.notifyCalled();
+            }
+        });
+    }
+
+    /**
+     * Tests whether callback for dismissal functions correctly.
+     */
+    @Test
+    public void testDismissCallback() {
+        PropertyModel shownDialogModel = mModalDialogManager.getShownDialogModel();
+        Assert.assertNotNull(shownDialogModel);
+        Assert.assertEquals(0, mDialogCallback.getCallCount());
+        Assert.assertEquals(0, mIntentCallback.getCallCount());
+
+        shownDialogModel.get(ModalDialogProperties.CONTROLLER)
+                .onClick(shownDialogModel, ModalDialogProperties.ButtonType.NEGATIVE);
+        Assert.assertEquals(1, mDialogCallback.getCallCount());
+        Assert.assertEquals(0, mIntentCallback.getCallCount());
+    }
+
+    /**
+     * Tests whether intent and callback for clicking on the 'Turn on' button functions correctly.
+     */
+    @Test
+    public void testTurnOnCallback() {
+        PropertyModel shownDialogModel = mModalDialogManager.getShownDialogModel();
+        Assert.assertNotNull(shownDialogModel);
+        Assert.assertEquals(0, mDialogCallback.getCallCount());
+        Assert.assertEquals(0, mIntentCallback.getCallCount());
+
+        shownDialogModel.get(ModalDialogProperties.CONTROLLER)
+                .onClick(shownDialogModel, ModalDialogProperties.ButtonType.POSITIVE);
+        Assert.assertEquals(0, mDialogCallback.getCallCount());
+        Assert.assertEquals(1, mIntentCallback.getCallCount());
+
+        mWindowAndroidIntentCallback.onIntentCompleted(
+                mWindowAndroid, 0 /* resultCode */, new Intent());
+        Assert.assertEquals(1, mDialogCallback.getCallCount());
+        Assert.assertEquals(1, mIntentCallback.getCallCount());
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
index eb39424..56024494a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
@@ -49,8 +49,7 @@
     public void setUp() {
         initMocks(this);
         IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class));
-        when(IdentityServicesProvider.get().getSigninManagerInternal())
-                .thenReturn(mSigninManagerMock);
+        when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock);
         mFragmentManager =
                 Robolectric.setupActivity(FragmentActivity.class).getSupportFragmentManager();
         mStateMachineDelegate = new ConfirmSyncDataStateMachineDelegate(mFragmentManager);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index e7562aa2..224488d 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-80.0.3987.5_rc-r1-merged.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-81.0.3999.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index 234ed23..7a95ae7 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -9,12 +9,6 @@
 #include "build/build_config.h"
 #include "chrome/browser/media/media_engagement_score_details.mojom.h"
 #include "chrome/browser/ui/webui/downloads/downloads.mojom.h"
-#include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
-#include "chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom.h"
-#include "chrome/browser/ui/webui/omnibox/omnibox.mojom.h"
-#include "chrome/browser/ui/webui/reset_password/reset_password.mojom.h"
-#include "chrome/browser/ui/webui/snippets_internals/snippets_internals.mojom.h"
-#include "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.h"
 #include "chrome/common/available_offline_content.mojom.h"
 #include "chrome/common/cache_stats_recorder.mojom.h"
 #include "chrome/common/net_benchmarking.mojom.h"
@@ -28,7 +22,6 @@
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer.mojom.h"
 #include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader.mojom.h"
-#include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.h"
 #include "chromeos/services/media_perception/public/mojom/media_perception.mojom.h"
 #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
 #include "chromeos/services/network_config/public/mojom/constants.mojom.h"  // nogncheck
@@ -91,11 +84,11 @@
         .RequireCapability("util_win", "util_win")
         .RequireCapability("xr_device_service", "xr_device_provider")
         .RequireCapability("xr_device_service", "xr_device_test_hook")
+#if defined(OS_CHROMEOS) || !defined(OS_ANDROID)
         .ExposeInterfaceFilterCapability_Deprecated(
             "navigation:frame", "renderer",
             service_manager::Manifest::InterfaceList<
 #if defined(OS_CHROMEOS)
-                chromeos::cellular_setup::mojom::CellularSetup,
                 chromeos::crostini_installer::mojom::PageHandlerFactory,
                 chromeos::crostini_upgrader::mojom::PageHandlerFactory,
                 chromeos::multidevice_setup::mojom::MultiDeviceSetup,
@@ -105,14 +98,11 @@
                 // WebUI-only interfaces go below this line. These should be
                 // brokered through a dedicated interface, but they're here
                 // for for now.
-                feed_internals::mojom::PageHandler,
-                new_tab_page::mojom::PageHandlerFactory,
 #if !defined(OS_ANDROID)
-                app_management::mojom::PageHandlerFactory,
+                app_management::mojom::PageHandlerFactory
 #endif
-                mojom::OmniboxPageHandler, mojom::ResetPasswordHandler,
-                mojom::UsbInternalsPageHandler,
-                snippets_internals::mojom::PageHandlerFactory>())
+                >())
+#endif  // defined(OS_CHROMEOS) || !defined(OS_ANDROID)
         .Build()
   };
   return *manifest;
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index d5b825e..6b792c286 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -907,6 +907,11 @@
   <message name="IDS_APP_START_WAIT_FOR_APP_WINDOW_MESSAGE" desc="Message displayed while waiting for the application to create its window in kiosk mode.">
     Waiting for application window...
   </message>
+  <message name="IDS_APP_START_WAIT_FOR_APP_WINDOW_INSTALL_FAILED_MESSAGE" desc="Message displayed when kiosk app installation fails, but we still try to run the app.">
+    Failed to obtain app data, still trying to run the app...
+  </message>
+
+
   <message name="IDS_APP_START_CONFIGURE_NETWORK" desc="Text displayed for configure network button while installing and/or launching web application in kiosk mode.">
     Configure network
   </message>
@@ -3455,9 +3460,6 @@
   <message name="IDS_INTERNAL_APP_CONTINUOUS_READING" desc="The default title of Chrome browser to allow users to seamlessly continue reading a web page when they switch from phones or tablets to Chromebook.">
     Continue reading in Chrome
   </message>
-  <message name="IDS_INTERNAL_APP_CAMERA" desc="The name of the Camera app in the app list.">
-    Camera
-  </message>
   <message name="IDS_INTERNAL_APP_DISCOVER" desc="Name for the Discover app in the app list.">
     Discover
   </message>
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 32d28b6..34c80e7 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -653,9 +653,6 @@
 
       <!-- Sync/sign-in error messages -->
       <if expr="not chromeos">
-        <message name="IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error bubble view when the user needs to update their sync passphrase.">
-          Chromium could not sync your data. Please update your Sync passphrase.
-        </message>
         <message name="IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sign-in error bubble view when the user's sign-in credentials are out of date.">
           Chromium could not sync your data because your account sign-in details are out of date.
         </message>
@@ -670,6 +667,12 @@
         <message name="IDS_SIGNIN_ERROR_SECONDARY_ACCOUNT_DISPLAY_SOURCE" desc="Context title shown in the notification header of sign-in error notification for Chromium OS Secondary Accounts.">
           Chromium OS System
         </message>
+        <message name="IDS_SYNC_NEEDS_KEYS_FOR_EVERYTHING_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error notification when the user needs to reauth to retrieve the sync encryption keys and resume sync.">
+          Chromium OS could not sync your data. Fix now.
+        </message>
+        <message name="IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error notification when the user needs to reauth to retrieve the sync encryption keys, required to resume syncing of passwords specifically (other sync data works normally).">
+          Chromium OS could not sync your passwords. Fix now.
+        </message>
         <message name="IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error notification when the user needs to update their sync passphrase.">
           Chromium OS could not sync your data. Please update your Sync passphrase.
         </message>
diff --git a/chrome/app/chromium_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1
new file mode 100644
index 0000000..6a44b8c
--- /dev/null
+++ b/chrome/app/chromium_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1
@@ -0,0 +1 @@
+839267c25e58108f3a41cf49e06c38bd3dd5ffc1
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 522e9bb..76e2657 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7258,6 +7258,10 @@
         desc="Used to indicate that the speech recognition service is waiting for user permission to use the microphone.">
         Waiting...
       </message>
+      <message name="IDS_NEW_TAB_VOICE_SEARCH_CLOSED"
+        desc="Message announced to screen reader users that the voice search overlay is closed.">
+        Voice search closed
+      </message>
 
       <if expr="not use_titlecase">
         <message name="IDS_NEW_TAB_APP_OPTIONS"
@@ -7711,7 +7715,7 @@
         Sign-in error
       </message>
       <message name="IDS_SYNC_ERROR_BUBBLE_VIEW_TITLE" desc="Title in the sync error bubble view/notification.">
-        Sync Error
+        Sync error
       </message>
       <message name="IDS_SYNC_ERROR_USER_MENU_TITLE" desc="Title of the sync/signin error header of desktop user menu.">
         Sync isn't working
@@ -8939,6 +8943,9 @@
       </if>
 
       <!-- NFC permission -->
+      <message name="IDS_NFC_PERMISSION_FRAGMENT" desc="Permission request shown if the user is visiting a site that wants to use NFC. Follows a prompt: 'This site would like to:'">
+        Use NFC devices
+      </message>
       <if expr="is_android">
         <message name="IDS_NFC_INFOBAR_TEXT" desc="Text requesting permission for a site to use NFC">
           <ph name="URL">$1<ex>google.com</ex></ph> wants to send and receive info when you tap your phone on an NFC device
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 2650cba..1fea58f 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -663,9 +663,6 @@
 
       <!-- Sync/sign-in error messages -->
       <if expr="not chromeos">
-        <message name="IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error bubble view when the user needs to update their sync passphrase.">
-          Google Chrome could not sync your data. Please update your Sync passphrase.
-        </message>
         <message name="IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sign-in error bubble view when the user's sign-in credentials are out of date.">
           Google Chrome could not sync your data because your account sign-in details are out of date.
         </message>
@@ -680,6 +677,12 @@
         <message name="IDS_SIGNIN_ERROR_SECONDARY_ACCOUNT_DISPLAY_SOURCE" desc="Context title shown in the notification header of sign-in error notification for Chrome OS Secondary Accounts.">
           Chrome OS System
         </message>
+        <message name="IDS_SYNC_NEEDS_KEYS_FOR_EVERYTHING_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error notification when the user needs to reauth to retrieve the sync encryption keys and resume sync.">
+          Chrome OS could not sync your data. Fix now.
+        </message>
+        <message name="IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error notification when the user needs to reauth to retrieve the sync encryption keys, required to resume syncing of passwords specifically (other sync data works normally).">
+          Chrome OS could not sync your passwords. Fix now.
+        </message>
         <message name="IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error bubble view when the user needs to update their sync passphrase.">
           Chrome OS could not sync your data. Please update your Sync passphrase.
         </message>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1
new file mode 100644
index 0000000..6a44b8c
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE.png.sha1
@@ -0,0 +1 @@
+839267c25e58108f3a41cf49e06c38bd3dd5ffc1
\ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_af.xtb b/chrome/app/resources/chromium_strings_af.xtb
index fdae3166..8972851 100644
--- a/chrome/app/resources/chromium_strings_af.xtb
+++ b/chrome/app/resources/chromium_strings_af.xtb
@@ -5,7 +5,6 @@
 
 Sommige kenmerke kan dalk nie beskikbaar wees nie en veranderings aan voorkeure sal nie gestoor word nie.</translation>
 <translation id="1104942323762546749">Chromium wil jou wagwoorde uitvoer. Tik jou Windows-wagwoord in om dit toe te laat.</translation>
-<translation id="1115445892567829615">Chromium kon nie jou data sinkroniseer nie. Dateer asseblief jou Sinkronisering-wagfrase op.</translation>
 <translation id="113122355610423240">Chromium is jou verstekblaaier</translation>
 <translation id="1185134272377778587">Meer oor Chromium</translation>
 <translation id="1396446129537741364">Chromium probeer tans om wagwoorde te wys.</translation>
diff --git a/chrome/app/resources/chromium_strings_am.xtb b/chrome/app/resources/chromium_strings_am.xtb
index 7fd2938..4a6c2984 100644
--- a/chrome/app/resources/chromium_strings_am.xtb
+++ b/chrome/app/resources/chromium_strings_am.xtb
@@ -5,7 +5,6 @@
 
 አንዳንድ ባህሪያት ላይገኙ ይችላሉ፣ እና በአማራጮች ላይ የተደረጉ ለውጦች አይቀመጡም።</translation>
 <translation id="1104942323762546749">Chromium የእርስዎን የይለፍ ቃላት ወደ ውጭ መላክ ይፈልጋል። ይህንን ለመፍቀድ የWindows የይለፍ ቃልዎን ይተይቡ።</translation>
-<translation id="1115445892567829615">Chromium የእርስዎን ውሂብ ማመሳሰል አልቻለም። የእርስዎን የማመሳሰያ የይለፍ ሐረግ እባክዎ ያዘምኑ።</translation>
 <translation id="113122355610423240">Chromium የእርስዎ ነባሪ አሳሽ ነው</translation>
 <translation id="1185134272377778587">ስለChromium</translation>
 <translation id="1396446129537741364">Chromium የይለፍ ቃላትን ለማሳየት እየሞከረ ነው።</translation>
diff --git a/chrome/app/resources/chromium_strings_ar.xtb b/chrome/app/resources/chromium_strings_ar.xtb
index eeb6df7..796aa727 100644
--- a/chrome/app/resources/chromium_strings_ar.xtb
+++ b/chrome/app/resources/chromium_strings_ar.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ar">
 <translation id="1065672644894730302">لا يمكن قراءة تفضيلاتك. قد تكون بعض الميزات غير متاحة، ولن يتم حفظ التغييرات في التفضيلات.</translation>
 <translation id="1104942323762546749">‏يرغب Chromium في تصدير كلمات المرور، لذا يُرجى كتابة كلمة مرور Windows للسماح بذلك.</translation>
-<translation id="1115445892567829615">‏تعذر على Chromium مزامنة البيانات. يُرجى تحديث عبارة مرور المزامنة.</translation>
 <translation id="113122355610423240">‏Chromium هو متصفحك التلقائي</translation>
 <translation id="1185134272377778587">‏حول Chromium</translation>
 <translation id="1396446129537741364">‏يحاول Chromium إظهار كلمات المرور.</translation>
diff --git a/chrome/app/resources/chromium_strings_as.xtb b/chrome/app/resources/chromium_strings_as.xtb
index 8ad1ee7..da32d2c 100644
--- a/chrome/app/resources/chromium_strings_as.xtb
+++ b/chrome/app/resources/chromium_strings_as.xtb
@@ -5,7 +5,6 @@
 
 কিছুমান সুবিধা উপলব্ধ নহ'ব পাৰে আৰু অগ্ৰাধিকাৰসমূহত কৰা সলনি কার্য ছেভ নহ'ব পাৰে।</translation>
 <translation id="1104942323762546749">Chromiumএ আপোনাৰ পাছৱর্ডসমূহ ৰপ্তানি কৰিব খোজে। ইয়াৰ অনুমতি আপোনাৰ দিবলৈ Windows পাছৱৰ্ড টাইপ কৰক।</translation>
-<translation id="1115445892567829615">Chromiumএ আপোনাৰ ডেটা ছিংক কৰিব নোৱাৰিলে। অনুগ্ৰহ কৰি আপোনাৰ ছিংক পাছফ্ৰে’জটো আপডে’ট কৰক।</translation>
 <translation id="113122355610423240">Chromium হৈছে আপোনাৰ ডিফ’ল্ট ব্ৰাউজাৰ</translation>
 <translation id="1185134272377778587">Chromiumৰ বিষয়ে</translation>
 <translation id="1396446129537741364">Chromiumএ পাছৱর্ডসমূহ দেখুৱাবলৈ চেষ্টা কৰি আছে।</translation>
diff --git a/chrome/app/resources/chromium_strings_az.xtb b/chrome/app/resources/chromium_strings_az.xtb
index 903a063..fc16fe1 100644
--- a/chrome/app/resources/chromium_strings_az.xtb
+++ b/chrome/app/resources/chromium_strings_az.xtb
@@ -5,7 +5,6 @@
 
 Bəzi funksiyalar əlçatmaz ola bilər ki, nəticədə tərcihlərə edilən dəyişikliklər saxlanmaya bilər.</translation>
 <translation id="1104942323762546749">Chromium parollarınızı eksport etmək istəyir. Buna icazə vermək üçün Windows parolunu yazın.</translation>
-<translation id="1115445892567829615">Chromium datanızı sinxronizasiya edə bilmədi. Lütfən, Sinxronizasiya parol ifadəsini güncəlləşdirin.</translation>
 <translation id="113122355610423240">Chromium defolt brauzerinizdir</translation>
 <translation id="1185134272377778587">Chromium haqqında</translation>
 <translation id="1396446129537741364">Chromium parolları göstərməyə çalışır.</translation>
diff --git a/chrome/app/resources/chromium_strings_be.xtb b/chrome/app/resources/chromium_strings_be.xtb
index dec97ce..9b5e9c4 100644
--- a/chrome/app/resources/chromium_strings_be.xtb
+++ b/chrome/app/resources/chromium_strings_be.xtb
@@ -5,7 +5,6 @@
 
 Некаторыя функцыі могуць быць недаступныя, і змены ў параметрах не захаваюцца.</translation>
 <translation id="1104942323762546749">Chromium запытвае дазвол на экспартаванне вашых пароляў. Каб дазволіць гэта, увядзіце пароль Windows.</translation>
-<translation id="1115445892567829615">Сінхранізаваць даныя ў браўзеры Chromium не ўдалося. Абнавіце фразу-пароль для сінхранізацыі.</translation>
 <translation id="113122355610423240">Chromium з'яўляецца стандартным браўзерам</translation>
 <translation id="1185134272377778587">Пра Chromium</translation>
 <translation id="1396446129537741364">Chromium спрабуе паказаць паролі.</translation>
diff --git a/chrome/app/resources/chromium_strings_bg.xtb b/chrome/app/resources/chromium_strings_bg.xtb
index 9408a6a6..cfbaf8ad 100644
--- a/chrome/app/resources/chromium_strings_bg.xtb
+++ b/chrome/app/resources/chromium_strings_bg.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="bg">
 <translation id="1065672644894730302">Предпочитанията ви не могат да бъдат прочетени. Възможно е да няма достъп до някои функции и промените в предпочитанията няма да бъдат запазени.</translation>
 <translation id="1104942323762546749">Chromium иска да експортира паролите ви. За да разрешите това, въведете паролата си за Windows.</translation>
-<translation id="1115445892567829615">Chromium не можа да синхронизира данните ви. Моля, актуализирайте пропуска си за синхронизиране.</translation>
 <translation id="113122355610423240">Chromium е браузърът ви по подразбиране</translation>
 <translation id="1185134272377778587">Всичко за Chromium</translation>
 <translation id="1396446129537741364">Chromium опитва да покаже паролите.</translation>
diff --git a/chrome/app/resources/chromium_strings_bn.xtb b/chrome/app/resources/chromium_strings_bn.xtb
index 24b21f33..cff4900 100644
--- a/chrome/app/resources/chromium_strings_bn.xtb
+++ b/chrome/app/resources/chromium_strings_bn.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="bn">
 <translation id="1065672644894730302">আপনার অভিরুচিগুলি পড়া যাবে না৷ কিছু বৈশিষ্ট্য অনুপলব্ধ থাকতে পারে ও অভিরুচিগুলিতে করা পরিবর্তনগুলি সংরক্ষিত হবে না৷</translation>
 <translation id="1104942323762546749">Chromium আপনার পাসওয়ার্ড এক্সপোর্ট করতে চাইছে। অনুমতি দিতে Windows এর পাসওয়ার্ড টাইপ করুন।</translation>
-<translation id="1115445892567829615">Chromium আপনার ডেটা সিঙ্ক করতে পারেনি৷ দয়া করে আপনার সিঙ্ক পাসফ্রেজ আপডেট করুন৷</translation>
 <translation id="113122355610423240">Chromium আপনার ডিফল্ট ব্রাউজার</translation>
 <translation id="1185134272377778587">Chromium সম্পর্কে</translation>
 <translation id="1396446129537741364">Chromium পাসওয়ার্ডগুলি দেখানোর চেষ্টা করছে৷</translation>
diff --git a/chrome/app/resources/chromium_strings_bs.xtb b/chrome/app/resources/chromium_strings_bs.xtb
index 6871e13..14515dc 100644
--- a/chrome/app/resources/chromium_strings_bs.xtb
+++ b/chrome/app/resources/chromium_strings_bs.xtb
@@ -5,7 +5,6 @@
 
 Neke funkcije možda neće biti dostupne i promjene postavki se neće sačuvati.</translation>
 <translation id="1104942323762546749">Chromium želi izvesti vaše zaporke. Upišite svoju zaporku za Windows da biste to dopustili.</translation>
-<translation id="1115445892567829615">Chromium nije mogao sinhronizirati vaše podatke. Ažurirajte pristupni izraz za sinhronizaciju.</translation>
 <translation id="113122355610423240">Chromium je vaš zadani preglednik</translation>
 <translation id="1185134272377778587">O programu Chromium</translation>
 <translation id="1396446129537741364">Chromium pokušava prikazati lozinke.</translation>
diff --git a/chrome/app/resources/chromium_strings_ca.xtb b/chrome/app/resources/chromium_strings_ca.xtb
index f71e30c3..a8b15f3 100644
--- a/chrome/app/resources/chromium_strings_ca.xtb
+++ b/chrome/app/resources/chromium_strings_ca.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ca">
 <translation id="1065672644894730302">No es poden llegir les vostres preferències. És possible que algunes funcions no estiguin disponibles i que els canvis a les preferències no es desin.</translation>
 <translation id="1104942323762546749">Chromium vol exportar les teves contrasenyes. Escriu la contrasenya de Windows per permetre-ho.</translation>
-<translation id="1115445892567829615">Chromium no ha pogut sincronitzar les dades. Actualitzeu la frase de contrasenya de sincronització.</translation>
 <translation id="113122355610423240">Chromium és el navegador predeterminat</translation>
 <translation id="1185134272377778587">Quant a Chromium</translation>
 <translation id="1396446129537741364">Chromium està provant de mostrar les contrasenyes.</translation>
diff --git a/chrome/app/resources/chromium_strings_cs.xtb b/chrome/app/resources/chromium_strings_cs.xtb
index 5793459..bec2859 100644
--- a/chrome/app/resources/chromium_strings_cs.xtb
+++ b/chrome/app/resources/chromium_strings_cs.xtb
@@ -5,7 +5,6 @@
 
 Některé funkce možná nebudou k dispozici a změny nastavení se neuloží.</translation>
 <translation id="1104942323762546749">Chromium chce exportovat vaše hesla. Tato akce vyžaduje zadání hesla systému Windows.</translation>
-<translation id="1115445892567829615">Prohlížeč Chromium vaše data nemohl synchronizovat. Aktualizujte prosím heslovou frázi pro synchronizaci.</translation>
 <translation id="113122355610423240">Chromium je vaším výchozím prohlížečem</translation>
 <translation id="1185134272377778587">O prohlížeči Chromium</translation>
 <translation id="1396446129537741364">Chromium se pokouší zobrazit hesla.</translation>
diff --git a/chrome/app/resources/chromium_strings_da.xtb b/chrome/app/resources/chromium_strings_da.xtb
index e49357de..1a4081e 100644
--- a/chrome/app/resources/chromium_strings_da.xtb
+++ b/chrome/app/resources/chromium_strings_da.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="da">
 <translation id="1065672644894730302">Dine præferencer kan ikke læses. Visse funktioner er muligvis ikke tilgængelige, og ændringer af præferencer gemmes ikke.</translation>
 <translation id="1104942323762546749">Chromium anmoder om at eksportere dine adgangskoder. Angiv din Windows-adgangskode for at tillade dette.</translation>
-<translation id="1115445892567829615">Chromium kunne ikke synkronisere dine data. Opdater din adgangssætning til synkronisering.</translation>
 <translation id="113122355610423240">Chromium er din standardbrowser</translation>
 <translation id="1185134272377778587">Om Chromium</translation>
 <translation id="1396446129537741364">Chromium forsøger at vise adgangskoder.</translation>
diff --git a/chrome/app/resources/chromium_strings_de.xtb b/chrome/app/resources/chromium_strings_de.xtb
index fbfc666..cd4f872 100644
--- a/chrome/app/resources/chromium_strings_de.xtb
+++ b/chrome/app/resources/chromium_strings_de.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="de">
 <translation id="1065672644894730302">Ihre Einstellungen können nicht gelesen werden. Einige Funktionen sind möglicherweise nicht verfügbar und Änderungen an Einstellungen werden nicht gespeichert.</translation>
 <translation id="1104942323762546749">Chromium möchte Ihre Passwörter exportieren. Wenn Sie dies zulassen möchten, geben Sie Ihr Windows-Passwort ein.</translation>
-<translation id="1115445892567829615">Chromium konnte Ihre Daten nicht synchronisieren. Bitte aktualisieren Sie Ihre Passphrase für die Synchronisierung.</translation>
 <translation id="113122355610423240">Chromium ist Ihr Standardbrowser</translation>
 <translation id="1185134272377778587">Über Chromium</translation>
 <translation id="1396446129537741364">Chromium versucht, Passwörter anzuzeigen.</translation>
diff --git a/chrome/app/resources/chromium_strings_el.xtb b/chrome/app/resources/chromium_strings_el.xtb
index 7f70f91f..9530ee09 100644
--- a/chrome/app/resources/chromium_strings_el.xtb
+++ b/chrome/app/resources/chromium_strings_el.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="el">
 <translation id="1065672644894730302">Δεν είναι δυνατή η ανάγνωση των προτιμήσεών σας. Ορισμένες λειτουργίες ενδέχεται να μην είναι διαθέσιμες και οι αλλαγές στις προτιμήσεις δεν θα αποθηκευτούν.</translation>
 <translation id="1104942323762546749">Το Chromium θέλει να εξαγάγει τους κωδικούς πρόσβασής σας. Για να το επιτρέψετε αυτό, πληκτρολογήστε τον κωδικό πρόσβασης για τα Windows.</translation>
-<translation id="1115445892567829615">Το Chromium δεν κατάφερε να συγχρονίσει τα δεδομένα σας. Ενημερώστε τη φράση πρόσβασης συγχρονισμού.</translation>
 <translation id="113122355610423240">Το Chromium είναι το προεπιλεγμένο πρόγραμμα περιήγησης</translation>
 <translation id="1185134272377778587">Σχετικά με το Chromium</translation>
 <translation id="1396446129537741364">Το Chromium επιχειρεί να εμφανίσει κωδικούς πρόσβασης.</translation>
diff --git a/chrome/app/resources/chromium_strings_en-GB.xtb b/chrome/app/resources/chromium_strings_en-GB.xtb
index ea10b49..2d8e8af2 100644
--- a/chrome/app/resources/chromium_strings_en-GB.xtb
+++ b/chrome/app/resources/chromium_strings_en-GB.xtb
@@ -5,7 +5,6 @@
 
 Some features may be unavailable and changes to preferences won't be saved.</translation>
 <translation id="1104942323762546749">Chromium wants to export your passwords. Type your Windows password to allow this.</translation>
-<translation id="1115445892567829615">Chromium could not sync your data. Please update your Sync passphrase.</translation>
 <translation id="113122355610423240">Chromium is your default browser</translation>
 <translation id="1185134272377778587">About Chromium</translation>
 <translation id="1396446129537741364">Chromium is trying to show passwords.</translation>
diff --git a/chrome/app/resources/chromium_strings_es-419.xtb b/chrome/app/resources/chromium_strings_es-419.xtb
index 27a959b..0ee7426 100644
--- a/chrome/app/resources/chromium_strings_es-419.xtb
+++ b/chrome/app/resources/chromium_strings_es-419.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="es-419">
 <translation id="1065672644894730302">No se pueden leer tus preferencias. Es posible que algunas funciones no estén disponibles y que no se guarden los cambios realizados a las preferencias.</translation>
 <translation id="1104942323762546749">Chromium desea exportar tus contraseñas. Para permitirlo, escribe tu contraseña de Windows.</translation>
-<translation id="1115445892567829615">Chromium no pudo sincronizar los datos. Actualiza la frase de contraseña de sincronización.</translation>
 <translation id="113122355610423240">Chromium es tu navegador predeterminado</translation>
 <translation id="1185134272377778587">Acerca de Chromium</translation>
 <translation id="1396446129537741364">Chromium está intentando mostrar contraseñas.</translation>
diff --git a/chrome/app/resources/chromium_strings_es.xtb b/chrome/app/resources/chromium_strings_es.xtb
index f482906a..381b3da 100644
--- a/chrome/app/resources/chromium_strings_es.xtb
+++ b/chrome/app/resources/chromium_strings_es.xtb
@@ -5,7 +5,6 @@
 
 Es posible que algunas funciones no estén disponibles y que no se guarden los cambios que hagas en las preferencias.</translation>
 <translation id="1104942323762546749">Chromium quiere exportar tus contraseñas. Escribe tu contraseña de Windows para permitirlo.</translation>
-<translation id="1115445892567829615">Chromium no ha podido sincronizar los datos. Actualiza la frase de contraseña de sincronización.</translation>
 <translation id="113122355610423240">Chromium es tu navegador predeterminado</translation>
 <translation id="1185134272377778587">Información de Chromium</translation>
 <translation id="1396446129537741364">Chromium está intentando mostrar contraseñas.</translation>
diff --git a/chrome/app/resources/chromium_strings_et.xtb b/chrome/app/resources/chromium_strings_et.xtb
index 0764619..6d8ed3c 100644
--- a/chrome/app/resources/chromium_strings_et.xtb
+++ b/chrome/app/resources/chromium_strings_et.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="et">
 <translation id="1065672644894730302">Teie eelistusi ei saa lugeda. Mõned funktsioonid ei pruugi saadaval olla ja eelistuste muudatusi ei salvestata.</translation>
 <translation id="1104942323762546749">Chromium soovib teie paroole eksportida. Selle lubamiseks sisestage oma Windowsi parool.</translation>
-<translation id="1115445892567829615">Chromium ei saanud teie andmeid sünkroonida. Värskendage oma sünkroonimisparooli.</translation>
 <translation id="113122355610423240">Chromium on teie vaikebrauser</translation>
 <translation id="1185134272377778587">Teave Chromiumi kohta</translation>
 <translation id="1396446129537741364">Chromium püüab paroole kuvada.</translation>
diff --git a/chrome/app/resources/chromium_strings_eu.xtb b/chrome/app/resources/chromium_strings_eu.xtb
index 122be74..e320d5dd 100644
--- a/chrome/app/resources/chromium_strings_eu.xtb
+++ b/chrome/app/resources/chromium_strings_eu.xtb
@@ -5,7 +5,6 @@
 
 Eginbide batzuk agian dira erabilgarri egongo eta hobespenei egindako aldaketak ez dira aldatuko.</translation>
 <translation id="1104942323762546749">Chromium-ek pasahitzak esportatu nahi ditu. Hori baimentzeko, idatzi Windows pasahitza.</translation>
-<translation id="1115445892567829615">Chromium arakatzaileak ezin izan ditu sinkronizatu zure datuak. Eguneratu sinkronizatzeko pasaesaldia.</translation>
 <translation id="113122355610423240">Chromium da arakatzaile lehenetsia</translation>
 <translation id="1185134272377778587">Chromium arakatzaileari buruz</translation>
 <translation id="1396446129537741364">Chromium pasahitzak erakusten saiatzen ari da.</translation>
diff --git a/chrome/app/resources/chromium_strings_fa.xtb b/chrome/app/resources/chromium_strings_fa.xtb
index 9f4733bf..816c0d7 100644
--- a/chrome/app/resources/chromium_strings_fa.xtb
+++ b/chrome/app/resources/chromium_strings_fa.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="fa">
 <translation id="1065672644894730302">تنظیمات برگزیده شما را نمی‌توان خواند. بعضی ویژگی‌ها ممکن است در دسترس نباشند و تغییرات تنظیمات برگزیده ذخیره نخواهد شد.</translation>
 <translation id="1104942323762546749">‏Chromium می‌خواهد گذرواژه‌های شما را صادر کند. برای اجازه به این کار، گذرواژه Windows خود را تایپ کنید.</translation>
-<translation id="1115445892567829615">‏Chromium قادر به همگام‌سازی داده‌های شما نبود. لطفاً رمز عبارتی همگام‌سازی خود را به‌روز کنید.</translation>
 <translation id="113122355610423240">‏Chromium مرورگر پیش‌فرضتان است</translation>
 <translation id="1185134272377778587">‏درباره Chromium</translation>
 <translation id="1396446129537741364">‏Chromium می‌خواهد گذرواژه‌ها را نشان دهد.</translation>
diff --git a/chrome/app/resources/chromium_strings_fi.xtb b/chrome/app/resources/chromium_strings_fi.xtb
index 6e67247..19e6a2ac 100644
--- a/chrome/app/resources/chromium_strings_fi.xtb
+++ b/chrome/app/resources/chromium_strings_fi.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="fi">
 <translation id="1065672644894730302">Asetuksiasi ei voi lukea. Kaikkia toimintoja ei voi välttämättä käyttää eikä asetuksiin tehtäviä muutoksia tallenneta.</translation>
 <translation id="1104942323762546749">Chromium yrittää viedä salasanojasi tiedostoon. Salli tämä kirjoittamalla Windows-salasanasi.</translation>
-<translation id="1115445892567829615">Chromium ei voinut synkronoida tietoja. Päivitä synkronoinnin tunnuslause.</translation>
 <translation id="113122355610423240">Chromium on oletusselaimesi.</translation>
 <translation id="1185134272377778587">Tietoja Chromiumista</translation>
 <translation id="1396446129537741364">Chromium yrittää näyttää salasanat.</translation>
diff --git a/chrome/app/resources/chromium_strings_fil.xtb b/chrome/app/resources/chromium_strings_fil.xtb
index 889147f..96722d8 100644
--- a/chrome/app/resources/chromium_strings_fil.xtb
+++ b/chrome/app/resources/chromium_strings_fil.xtb
@@ -5,7 +5,6 @@
 
 Maaaring hindi available ang ilang tampok at hindi mase-save ang mga pagbabago sa mga kagustuhan.</translation>
 <translation id="1104942323762546749">Gustong i-export ng Chromium ang iyong mga password. I-type ang iyong password sa Windows para payagan ito.</translation>
-<translation id="1115445892567829615">Hindi mai-sync ng Chromium ang iyong data. Paki-update ang iyong passphrase sa Pag-sync.</translation>
 <translation id="113122355610423240">Chromium ang iyong default na browser</translation>
 <translation id="1185134272377778587">Tungkol sa Chromium</translation>
 <translation id="1396446129537741364">Sinusubukan ng Chromium na magpakita ng mga password.</translation>
diff --git a/chrome/app/resources/chromium_strings_fr-CA.xtb b/chrome/app/resources/chromium_strings_fr-CA.xtb
index 7c2bf5f..c6dcfe3 100644
--- a/chrome/app/resources/chromium_strings_fr-CA.xtb
+++ b/chrome/app/resources/chromium_strings_fr-CA.xtb
@@ -5,7 +5,6 @@
 
 Certaines fonctionnalités ne seront peut-être pas disponibles et les modifications apportées à vos préférences ne seront pas enregistrées.</translation>
 <translation id="1104942323762546749">Chromium veut exporter vos mots de passe. Pour autoriser cette action, entrez votre mot de passe Windows.</translation>
-<translation id="1115445892567829615">Échec de synchronisation de vos données dans Chromium. Veuillez mettre à jour votre phrase de passe de synchronisation.</translation>
 <translation id="113122355610423240">Chromium est votre navigateur par défaut</translation>
 <translation id="1185134272377778587">À propos de Chromium</translation>
 <translation id="1396446129537741364">Chromium essaie d'afficher les mots de passe.</translation>
diff --git a/chrome/app/resources/chromium_strings_fr.xtb b/chrome/app/resources/chromium_strings_fr.xtb
index c5c2a63..f163887 100644
--- a/chrome/app/resources/chromium_strings_fr.xtb
+++ b/chrome/app/resources/chromium_strings_fr.xtb
@@ -4,7 +4,6 @@
 <translation id="1065672644894730302">Impossible de lire vos préférences.
 Certaines fonctionnalités ne seront peut-être pas disponibles, et les modifications apportées à vos préférences ne seront pas enregistrées.</translation>
 <translation id="1104942323762546749">Chromium veut exporter vos mots de passe. Pour autoriser cette action, saisissez votre mot de passe Windows.</translation>
-<translation id="1115445892567829615">Impossible de synchroniser vos données dans Chromium. Veuillez mettre à jour votre phrase secrète de synchronisation.</translation>
 <translation id="113122355610423240">Chromium est votre navigateur par défaut</translation>
 <translation id="1185134272377778587">À propos de Chromium</translation>
 <translation id="1396446129537741364">Tentative d'affichage des mots de passe dans Chromium</translation>
diff --git a/chrome/app/resources/chromium_strings_gl.xtb b/chrome/app/resources/chromium_strings_gl.xtb
index 176ac05..0ae9d71 100644
--- a/chrome/app/resources/chromium_strings_gl.xtb
+++ b/chrome/app/resources/chromium_strings_gl.xtb
@@ -5,7 +5,6 @@
 
 É posible que algunhas funcións non estean dispoñibles e que non se garden os cambios nas preferencias.</translation>
 <translation id="1104942323762546749">Chromium quere exportar os teus contrasinais. Escribe o teu contrasinal de Windows para permitir esta acción.</translation>
-<translation id="1115445892567829615">Chromium non puido sincronizar os teus datos. Actualiza a túa frase de acceso de sincronización.</translation>
 <translation id="113122355610423240">Chromium é o teu navegador predeterminado</translation>
 <translation id="1185134272377778587">Acerca de Chromium</translation>
 <translation id="1396446129537741364">Chromium está tentando mostrar contrasinais.</translation>
diff --git a/chrome/app/resources/chromium_strings_gu.xtb b/chrome/app/resources/chromium_strings_gu.xtb
index e8caceb..9ac759b 100644
--- a/chrome/app/resources/chromium_strings_gu.xtb
+++ b/chrome/app/resources/chromium_strings_gu.xtb
@@ -5,7 +5,6 @@
 
 કેટલીક સુવિધાઓ ઉપલબ્ધ હોઈ શકે છે અને પસંદગીઓ પરના ફેરફારોને સાચવવામાં આવશે નહીં.</translation>
 <translation id="1104942323762546749">Chromium તમારા પાસવર્ડની નિકાસ કરવા માગે છે. આને મંજૂરી આપવા માટે તમારો Windows પાસવર્ડ ટાઇપ કરો.</translation>
-<translation id="1115445892567829615">Chromium તમારા ડેટાને સમન્વયિત કરી શક્યું નથી. કૃપા કરીને તમારા સમન્વયન પાસફ્રેઝને અપડેટ કરો.</translation>
 <translation id="113122355610423240">Chromium તમારું ડિફૉલ્ટ બ્રાઉઝર છે</translation>
 <translation id="1185134272377778587">Chromium વિશે</translation>
 <translation id="1396446129537741364">Chromium પાસવર્ડ્સ બતાવવાનો પ્રયાસ કરી રહ્યું છે.</translation>
diff --git a/chrome/app/resources/chromium_strings_hi.xtb b/chrome/app/resources/chromium_strings_hi.xtb
index deb7cf5..f0c92af 100644
--- a/chrome/app/resources/chromium_strings_hi.xtb
+++ b/chrome/app/resources/chromium_strings_hi.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="hi">
 <translation id="1065672644894730302">आपकी प्राथमिकताओं को पढ़ा नहीं जा सकता| \\n\\nकुछ विशेषताएं अनुपलब्ध हो सकती हैं और प्राथमिकताओं में किए गए परिवर्तनों को सहेजा नहीं जाएगा.</translation>
 <translation id="1104942323762546749">क्रोमियम आपके पासवर्ड निर्यात करना चाहता है. इसकी मंज़ूरी देने के लिए अपना Windows पासवर्ड लिखें.</translation>
-<translation id="1115445892567829615">क्रोमियम आपका डेटा सिंक नहीं कर सका. कृपया अपना सिंक 'पासफ़्रेज़' अपडेट करें.</translation>
 <translation id="113122355610423240">क्रोमियम आपका डिफ़ॉल्ट ब्राउज़र है</translation>
 <translation id="1185134272377778587">क्रोमियम के बारे में</translation>
 <translation id="1396446129537741364">क्रोमियम पासवर्ड दिखाने का प्रयास कर रहा है.</translation>
diff --git a/chrome/app/resources/chromium_strings_hr.xtb b/chrome/app/resources/chromium_strings_hr.xtb
index 2007cf6..29c69fe 100644
--- a/chrome/app/resources/chromium_strings_hr.xtb
+++ b/chrome/app/resources/chromium_strings_hr.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="hr">
 <translation id="1065672644894730302">Vaše postavke nije moguće čitati. Neke značajke možda nisu dostupne i promjene postavki neće biti spremljene.</translation>
 <translation id="1104942323762546749">Chromium želi izvesti vaše zaporke. Upišite svoju zaporku za Windows da biste to dopustili.</translation>
-<translation id="1115445892567829615">Chromium nije mogao sinkronizirati vaše podatke. Ažurirajte svoju zaporku za sinkronizaciju.</translation>
 <translation id="113122355610423240">Chromium je vaš zadani preglednik</translation>
 <translation id="1185134272377778587">O pregledniku Chromium</translation>
 <translation id="1396446129537741364">Chromium pokušava prikazati zaporke.</translation>
diff --git a/chrome/app/resources/chromium_strings_hu.xtb b/chrome/app/resources/chromium_strings_hu.xtb
index 66ff87c7..4550b1b 100644
--- a/chrome/app/resources/chromium_strings_hu.xtb
+++ b/chrome/app/resources/chromium_strings_hu.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="hu">
 <translation id="1065672644894730302">A beállításait nem sikerült olvasni. Egyes funkciókat esetleg nem ér el, és a beállításaiban végrehajtott módosításokat nem menti a rendszer.</translation>
 <translation id="1104942323762546749">A Chromium exportálni szeretné a jelszavakat. Ennek engedélyezéséhez írja be Windows-jelszavát.</translation>
-<translation id="1115445892567829615">A Chromium nem tudta szinkronizálni az adatokat. Kérjük, frissítse a szinkronizálás jelszavát.</translation>
 <translation id="113122355610423240">A Chromium az alapértelmezett böngésző</translation>
 <translation id="1185134272377778587">A Chromium névjegye</translation>
 <translation id="1396446129537741364">A Chromium megpróbálja megjeleníteni a jelszavakat.</translation>
diff --git a/chrome/app/resources/chromium_strings_hy.xtb b/chrome/app/resources/chromium_strings_hy.xtb
index b401369..12eaaae8 100644
--- a/chrome/app/resources/chromium_strings_hy.xtb
+++ b/chrome/app/resources/chromium_strings_hy.xtb
@@ -5,7 +5,6 @@
 
 Որոշ գործառույթներ կարող են մատչելի չլինել: Նախընտրանքների փոփոխությունները չեն պահվի:</translation>
 <translation id="1104942323762546749">Chromium-ն ուզում է արտահանել ձեր գաղտնաբառերը: Թույլատրելու համար մուտքագրեք Windows-ի ձեր գաղտնաբառը:</translation>
-<translation id="1115445892567829615">Chromium-ը չկարողացավ համաժամացնել ձեր տվյալները: Թարմացրեք ձեր Համաժամացման անցաբառը:</translation>
 <translation id="113122355610423240">Chromium-ը ձեր կանխադրված դիտարկիչն է</translation>
 <translation id="1185134272377778587">Chromium-ի մասին</translation>
 <translation id="1396446129537741364">Chromium-ը փորձում է ցուցադրել գաղտնաբառերը:</translation>
diff --git a/chrome/app/resources/chromium_strings_id.xtb b/chrome/app/resources/chromium_strings_id.xtb
index 4f6c965..3590910 100644
--- a/chrome/app/resources/chromium_strings_id.xtb
+++ b/chrome/app/resources/chromium_strings_id.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="id">
 <translation id="1065672644894730302">Preferensi Anda tidak dapat dibaca. Beberapa fitur mungkin tidak tersedia dan perubahan pada preferensi tidak akan disimpan.</translation>
 <translation id="1104942323762546749">Chromium ingin mengekspor sandi. Ketik sandi Windows Anda untuk mengizinkannya.</translation>
-<translation id="1115445892567829615">Chromium tidak dapat menyinkronkan data Anda. Perbarui frasa sandi Sinkronisasi Anda.</translation>
 <translation id="113122355610423240">Chromium adalah browser default Anda</translation>
 <translation id="1185134272377778587">Tentang Chromium</translation>
 <translation id="1396446129537741364">Chromium mencoba menampilkan sandi.</translation>
diff --git a/chrome/app/resources/chromium_strings_is.xtb b/chrome/app/resources/chromium_strings_is.xtb
index c47e226b..491b8995 100644
--- a/chrome/app/resources/chromium_strings_is.xtb
+++ b/chrome/app/resources/chromium_strings_is.xtb
@@ -5,7 +5,6 @@
 
 Sumir eiginleikar kunna að vera óaðgengilegir og breytingar á kjörstillingum verða ekki vistaðar.</translation>
 <translation id="1104942323762546749">Chromium vill flytja út aðgangsorðin þín. Sláðu inn Windows-aðgangsorðið þitt til að leyfa það.</translation>
-<translation id="1115445892567829615">Chromium gat ekki samstillt gögnin þín. Uppfærðu aðgangsorðið fyrir samstillingu.</translation>
 <translation id="113122355610423240">Chromium er sjálfgefni vafrinn þinn</translation>
 <translation id="1185134272377778587">Um Chromium</translation>
 <translation id="1396446129537741364">Chromium er að reyna að birta aðgangsorð.</translation>
diff --git a/chrome/app/resources/chromium_strings_it.xtb b/chrome/app/resources/chromium_strings_it.xtb
index 2f6190ee..724916e 100644
--- a/chrome/app/resources/chromium_strings_it.xtb
+++ b/chrome/app/resources/chromium_strings_it.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="it">
 <translation id="1065672644894730302">Impossibile leggere le preferenze. Alcune funzioni potrebbero non essere disponibili e le modifiche alle preferenze non verranno salvate.</translation>
 <translation id="1104942323762546749">Chromium vuole esportare le password. Per consentire l'esportazione, digita la tua password Windows.</translation>
-<translation id="1115445892567829615">Impossibile sincronizzare i dati in Chromium. Aggiorna la passphrase di sincronizzazione.</translation>
 <translation id="113122355610423240">Chromium è il tuo browser predefinito</translation>
 <translation id="1185134272377778587">Informazioni su Chromium</translation>
 <translation id="1396446129537741364">Chromium sta cercando di visualizzare le password.</translation>
diff --git a/chrome/app/resources/chromium_strings_iw.xtb b/chrome/app/resources/chromium_strings_iw.xtb
index 798f248d..297e48f 100644
--- a/chrome/app/resources/chromium_strings_iw.xtb
+++ b/chrome/app/resources/chromium_strings_iw.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="iw">
 <translation id="1065672644894730302">לא היתה אפשרות לקרוא את ההעדפות שלך. ייתכן שחלק מהתכונות לא יהיו זמינות ושינויים בהעדפות לא יישמרו.</translation>
 <translation id="1104942323762546749">‏Chromium רוצה לייצא את הסיסמאות שלך. יש להקליד את הסיסמה שלך ל-Windows כדי לאפשר זאת.</translation>
-<translation id="1115445892567829615">‏Chromium לא הצליח לסנכרן את הנתונים שלך. עדכן את משפט הסיסמה לסנכרון.</translation>
 <translation id="113122355610423240">‏Chromium מוגדר כדפדפן ברירת המחדל</translation>
 <translation id="1185134272377778587">‏על Chromium</translation>
 <translation id="1396446129537741364">‏Chromium מנסה להציג סיסמאות.</translation>
diff --git a/chrome/app/resources/chromium_strings_ja.xtb b/chrome/app/resources/chromium_strings_ja.xtb
index a851bdd..8f35a727 100644
--- a/chrome/app/resources/chromium_strings_ja.xtb
+++ b/chrome/app/resources/chromium_strings_ja.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ja">
 <translation id="1065672644894730302">ユーザー設定ファイルを読み込むことができません。一部の機能が利用できない可能性があります。また、設定への変更は保存されません。</translation>
 <translation id="1104942323762546749">Chromium からパスワードをエクスポートするための許可を求められています。許可するには Windows のパスワードを入力してください。</translation>
-<translation id="1115445892567829615">Chromium はデータを同期できませんでした。同期パスフレーズを更新してください。</translation>
 <translation id="113122355610423240">既定のブラウザは Chromium です</translation>
 <translation id="1185134272377778587">Chromium について</translation>
 <translation id="1396446129537741364">Chromium はパスワードを表示しようとしています。</translation>
diff --git a/chrome/app/resources/chromium_strings_ka.xtb b/chrome/app/resources/chromium_strings_ka.xtb
index eb67dfb3..b9b39637 100644
--- a/chrome/app/resources/chromium_strings_ka.xtb
+++ b/chrome/app/resources/chromium_strings_ka.xtb
@@ -5,7 +5,6 @@
 
 ზოგიერთი ფუნქცია შეიძლება მიუწვდომელი იყოს და პარამეტრების ცვლილებები არ იქნება შენახული.</translation>
 <translation id="1104942323762546749">Chromium ითხოვს თქვენი პაროლების ექსპორტირებას. აღნიშნულის დასაშვებად აკრიფეთ თქვენი Windows-ის პაროლი.</translation>
-<translation id="1115445892567829615">Chromium-მა ვერ დაასინქრონა თქვენი მონაცემები. განაახლეთ სინქრონიზაციის საიდუმლო ფრაზა.</translation>
 <translation id="113122355610423240">Chromium თქვენი ნაგულისხმევი ბრაუზერია</translation>
 <translation id="1185134272377778587">Chromium-ის შესახებ</translation>
 <translation id="1396446129537741364">Chromium ცდილობს პაროლების ჩვენებას.</translation>
diff --git a/chrome/app/resources/chromium_strings_kk.xtb b/chrome/app/resources/chromium_strings_kk.xtb
index bcff948..d9327301 100644
--- a/chrome/app/resources/chromium_strings_kk.xtb
+++ b/chrome/app/resources/chromium_strings_kk.xtb
@@ -5,7 +5,6 @@
 
 Кейбір мүмкіндіктер қолжетімсіз болуы мүмкін және параметрлерге жасалған өзгертулер сақталмайды.</translation>
 <translation id="1104942323762546749">Chromium құпия сөздерді экспорттағысы келеді. Бұған рұқсат беру үшін Windows құпия сөзіңізді теріңіз.</translation>
-<translation id="1115445892567829615">Chromium деректеріңізді синхрондай алмайды. Синхрондау құпия фразасын жаңартыңыз.</translation>
 <translation id="113122355610423240">Chromium әдепкі браузеріңіз болып табылады</translation>
 <translation id="1185134272377778587">Chromium туралы ақпарат</translation>
 <translation id="1396446129537741364">Chromium құпия сөздерді көрсетпек.</translation>
diff --git a/chrome/app/resources/chromium_strings_km.xtb b/chrome/app/resources/chromium_strings_km.xtb
index 68c18e1..bc48dd7 100644
--- a/chrome/app/resources/chromium_strings_km.xtb
+++ b/chrome/app/resources/chromium_strings_km.xtb
@@ -5,7 +5,6 @@
 
 លក្ខណៈពិសេសមួយចំនួនប្រហែលជាមិនមាន ហើយការប្តូរទៅចំណូលចិត្តនឹងមិនត្រូវបានរក្សាទុកទេ។</translation>
 <translation id="1104942323762546749">Chromium ចង់​នាំ​ចេញពាក្យ​សម្ងាត់​របស់អ្នក។ សូមវាយ​បញ្ចូលពាក្យ​សម្ងាត់ Windows របស់អ្នក​ដើម្បីអនុញ្ញាត​ការនាំចេញ​នេះ។</translation>
-<translation id="1115445892567829615">Chromium មិនអាចធ្វើសមកម្មទិន្នន័យរបស់អ្នកទេ។ សូមធ្វើបច្ចុប្បន្នភាពឃ្លាសម្ងាត់សមកម្មរបស់អ្នក។</translation>
 <translation id="113122355610423240">Chromium គឺជា​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​លំនាំដើម​របស់​អ្នក</translation>
 <translation id="1185134272377778587">អំពី Chromium</translation>
 <translation id="1396446129537741364">Chromium កំពុងព្យាយាមបង្ហាញពាក្យសម្ងាត់។</translation>
diff --git a/chrome/app/resources/chromium_strings_kn.xtb b/chrome/app/resources/chromium_strings_kn.xtb
index 625a9120..579e090 100644
--- a/chrome/app/resources/chromium_strings_kn.xtb
+++ b/chrome/app/resources/chromium_strings_kn.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="kn">
 <translation id="1065672644894730302">ನಿಮ್ಮ ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ರೀಡ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಅಲ್ಲದೇ, ಕೆಲವು ವೈಶಿಷ್ಟ್ಯಗಳು ಲಭ್ಯವಿಲ್ಲದಿರಬಹುದು ಮತ್ತು ಪ್ರಾಶಸ್ತ್ಯಗಳಲ್ಲಿ ಮಾಡಿದ ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಲಾಗುವುದಿಲ್ಲ.</translation>
 <translation id="1104942323762546749">Chromium ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ರಫ್ತು ಮಾಡಲು ಬಯಸುತ್ತದೆ. ಇದನ್ನು ಅನುಮತಿಸಲು ನಿಮ್ಮ Windows ಪಾಸ್‌ವರ್ಡ್‌ ಟೈಪ್ ಮಾಡಿ.</translation>
-<translation id="1115445892567829615">Chromium ಗೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ನಿಮ್ಮ ಸಿಂಕ್ ಪಾಸ್‌ಫ್ರೇಸ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ.</translation>
 <translation id="113122355610423240">Chromium ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಬ್ರೌಸರ್ ಆಗಿದೆ.</translation>
 <translation id="1185134272377778587">Chromium ಕುರಿತು</translation>
 <translation id="1396446129537741364">Chromium ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ತೋರಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದೆ.</translation>
diff --git a/chrome/app/resources/chromium_strings_ko.xtb b/chrome/app/resources/chromium_strings_ko.xtb
index 9f53548..93825df 100644
--- a/chrome/app/resources/chromium_strings_ko.xtb
+++ b/chrome/app/resources/chromium_strings_ko.xtb
@@ -5,7 +5,6 @@
 
 일부 기능을 사용할 수 없으며 환경설정의 변경사항이 저장되지 않습니다.</translation>
 <translation id="1104942323762546749">Chromium에서 비밀번호를 내보내려고 합니다. 허용하려면 Windows 비밀번호를 입력하세요.</translation>
-<translation id="1115445892567829615">Chromium에서 데이터를 동기화하지 못했습니다. 동기화 암호를 업데이트하시기 바랍니다.</translation>
 <translation id="113122355610423240">Chromium이 기본 브라우저로 설정되어 있습니다.</translation>
 <translation id="1185134272377778587">Chromium 정보</translation>
 <translation id="1396446129537741364">Chromium이 비밀번호를 표시하려고 합니다.</translation>
diff --git a/chrome/app/resources/chromium_strings_ky.xtb b/chrome/app/resources/chromium_strings_ky.xtb
index dbfd3ab..8dded0c1f 100644
--- a/chrome/app/resources/chromium_strings_ky.xtb
+++ b/chrome/app/resources/chromium_strings_ky.xtb
@@ -5,7 +5,6 @@
 
 Айрым мүмкүнчүлүктөр иштебегендиктен, жеке жөндөөлөрдөгү өзгөрүүлөр сакталбайт.</translation>
 <translation id="1104942323762546749">Chromium сырсөздөрүңүздү экспорттогону жатат. Ага уруксат берүү үчүн Windows аккаунтуңуздун сырсөзүн териңиз.</translation>
-<translation id="1115445892567829615">Chromium дайындарыңызды шайкештештире албай койду. Шайкештештирүүнүн купуя сөз айкашын жаңыртыңыз.</translation>
 <translation id="113122355610423240">Chromium демейки серепчи катары колдонулат</translation>
 <translation id="1185134272377778587">Chromium жөнүндө</translation>
 <translation id="1396446129537741364">Chromium сырсөздөрдү көрсөткөнгө аракет кылып жатат.</translation>
diff --git a/chrome/app/resources/chromium_strings_lo.xtb b/chrome/app/resources/chromium_strings_lo.xtb
index 2257965..171fd751 100644
--- a/chrome/app/resources/chromium_strings_lo.xtb
+++ b/chrome/app/resources/chromium_strings_lo.xtb
@@ -5,7 +5,6 @@
 
 ບາງຄຸນສົມບັດ​ອາດຈະບໍ່ມີໃຫ້ ແລະການປ່ຽນແປງຕໍ່ຄວາມມັກຈະບໍ່ຖືກບັນທຶກ.</translation>
 <translation id="1104942323762546749">Chromium ຕ້ອງການສົ່ງອອກລະຫັດຜ່ານຂອງທ່ານ. ກະລຸນາພິມລະຫັດຜ່ານ Windows ຂອງທ່ານ ເພື່ອອະນຸຍາດສິ່ງນີ້.</translation>
-<translation id="1115445892567829615">Chromium ບໍ່​ສາ​ມາດຊິງຄ໌ຂໍ້​ມູນ​ຂອງ​ທ່ານໄດ້​. ກະ​ລຸ​ນາອັດ​ບ​ເດວະລີຜ່ານຊິງຄ໌ຂອງ​ທ່ານ​.</translation>
 <translation id="113122355610423240">Chromium ແມ່ນໂປຣແກຣມທ່ອງເວັບເລີ່ມຕົ້ນຂອງທ່ານ</translation>
 <translation id="1185134272377778587">ກ່ຽວ​ກັບ Chromium</translation>
 <translation id="1396446129537741364">Chromium ກໍາລັງພະຍາຍາມສະແດງລະຫັດຜ່ານ.</translation>
diff --git a/chrome/app/resources/chromium_strings_lt.xtb b/chrome/app/resources/chromium_strings_lt.xtb
index 20c780b..da8b7678 100644
--- a/chrome/app/resources/chromium_strings_lt.xtb
+++ b/chrome/app/resources/chromium_strings_lt.xtb
@@ -5,7 +5,6 @@
 
 Kai kurios funkcijos gali būti nepasiekiamos ir nuostatų pakeitimai nebus išsaugoti.</translation>
 <translation id="1104942323762546749">„Chromium“ nori eksportuoti jūsų slaptažodžius. Įveskite „Windows“ slaptažodį, kad tai leistumėte.</translation>
-<translation id="1115445892567829615">„Chromium“ negali sinchronizuoti jūsų duomenų. Atnaujinkite sinchronizavimo slaptafrazę.</translation>
 <translation id="113122355610423240">„Chromium“ yra numatytoji naršyklė</translation>
 <translation id="1185134272377778587">Apie „Chromium“</translation>
 <translation id="1396446129537741364">„Chromium“ bando parodyti slaptažodžius.</translation>
diff --git a/chrome/app/resources/chromium_strings_lv.xtb b/chrome/app/resources/chromium_strings_lv.xtb
index 419402e..4903d0b 100644
--- a/chrome/app/resources/chromium_strings_lv.xtb
+++ b/chrome/app/resources/chromium_strings_lv.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="lv">
 <translation id="1065672644894730302">Jūsu preferences nevar nolasīt. Dažas funkcijas var nebūt pieejamas, un preferenču izmaiņas netiks saglabātas</translation>
 <translation id="1104942323762546749">Pārlūkā Chromium tiek mēģināts eksportēt jūsu paroles. Lai to atļautu, ievadiet savu Windows paroli.</translation>
-<translation id="1115445892567829615">Chromium nevarēja sinhronizēt jūsu datus. Lūdzu, atjauniniet savu sinhronizācijas ieejas frāzi.</translation>
 <translation id="113122355610423240">Jūsu noklusējuma pārlūks ir Chromium.</translation>
 <translation id="1185134272377778587">Par Chromium</translation>
 <translation id="1396446129537741364">Chromium mēģina rādīt paroles.</translation>
diff --git a/chrome/app/resources/chromium_strings_mk.xtb b/chrome/app/resources/chromium_strings_mk.xtb
index fd7ef94f..d5414951e 100644
--- a/chrome/app/resources/chromium_strings_mk.xtb
+++ b/chrome/app/resources/chromium_strings_mk.xtb
@@ -5,7 +5,6 @@
 
 Некои функции може да се недостапни и промените на претпочитаните вредности нема да се зачуваат.</translation>
 <translation id="1104942323762546749">Chromium сака да ги извезе вашите лозинки. Внесете ја лозинката за Windows за да го дозволите ова.</translation>
-<translation id="1115445892567829615">Chromium не можеше да ги синхронизира вашите податоци. Ажурирајте ја пристапната фраза за Синхронизација.</translation>
 <translation id="113122355610423240">Chromium е вашиот стандарден прелистувач</translation>
 <translation id="1185134272377778587">За Chromium</translation>
 <translation id="1396446129537741364">Chromium се обидува да покаже лозинки.</translation>
diff --git a/chrome/app/resources/chromium_strings_ml.xtb b/chrome/app/resources/chromium_strings_ml.xtb
index 5d362bd..843fe04 100644
--- a/chrome/app/resources/chromium_strings_ml.xtb
+++ b/chrome/app/resources/chromium_strings_ml.xtb
@@ -5,7 +5,6 @@
 
 ചില സവിശേഷതകൾ ലഭ്യമല്ലായിരിക്കാം ഒപ്പം മുൻഗണനകളിലേക്കുള്ള മാറ്റങ്ങൾ സംരക്ഷിക്കപ്പെടുന്നതുമല്ല.</translation>
 <translation id="1104942323762546749">നിങ്ങളുടെ പാസ്‌വേഡുകൾ എക്‌സ്‌പോർട്ട് ചെയ്യാൻ Chromium ആഗ്രഹിക്കുന്നു. ഇത് അനുവദിക്കാൻ നിങ്ങളുടെ Windows പാസ്‌വേഡ് നൽകുക.</translation>
-<translation id="1115445892567829615">Chromium-ത്തിന് നിങ്ങളുടെ ഡാറ്റ സമന്വയിപ്പിക്കാനായില്ല. സമന്വയ പാസ്‌ഫ്രെയ്‌സ് അപ്‌ഡേറ്റ് ചെയ്യുക.</translation>
 <translation id="113122355610423240">Chromium നിങ്ങളുടെ ഡിഫോൾട്ട് ബ്രൗസറാണ്</translation>
 <translation id="1185134272377778587">Chromium-ത്തിനെക്കുറിച്ച്</translation>
 <translation id="1396446129537741364">Chromium പാസ്‌വേഡുകൾ ദൃശ്യമാക്കാൻ ശ്രമിക്കുന്നു.</translation>
diff --git a/chrome/app/resources/chromium_strings_mn.xtb b/chrome/app/resources/chromium_strings_mn.xtb
index f9485b2..ab49dbeb 100644
--- a/chrome/app/resources/chromium_strings_mn.xtb
+++ b/chrome/app/resources/chromium_strings_mn.xtb
@@ -5,7 +5,6 @@
 
 Зарим үйлдлүүд нь боломжгүй байж магадгүй бөгөөд сонголтонд хийсэн өөрчлөлтүүд хадгалагдахгүй.</translation>
 <translation id="1104942323762546749">Chromium таны нууц үгийг экспортлох хүсэлтэй байна. Үүнийг зөвшөөрч байгаа бол Windows-н нууц үгээ оруулна уу.</translation>
-<translation id="1115445892567829615">Chromium таны өгөгдлийг синхрончлох боломжгүй байна. Синхрончлолын нууц үгнүүдээ шинэчилнэ үү.</translation>
 <translation id="113122355610423240">Chromium таны өгөгдмөл хөтөч</translation>
 <translation id="1185134272377778587">Chromium-ийн тухай</translation>
 <translation id="1396446129537741364">Chromium нь нууц үгийг үзүүлэхээр ачаалж байна.</translation>
diff --git a/chrome/app/resources/chromium_strings_mr.xtb b/chrome/app/resources/chromium_strings_mr.xtb
index 0a8a6bd..9598b3b 100644
--- a/chrome/app/resources/chromium_strings_mr.xtb
+++ b/chrome/app/resources/chromium_strings_mr.xtb
@@ -4,7 +4,6 @@
 <translation id="1065672644894730302">तुमची प्राधान्ये वाचता आली नाहीत.
 काही वैशिष्‍ट्ये अनुपलब्ध असू शकतात आणि प्राधान्यांमधील बदल सेव्ह केले जाणार नाहीत.</translation>
 <translation id="1104942323762546749">Chromium ला तुमचे पासवर्ड निर्यात करायचे आहेत. हे करू देण्यासाठी तुमचा Windows पासवर्ड टाइप करा.</translation>
-<translation id="1115445892567829615">Chromium तुमचा डेटा सिंक करू शकले नाही. कृपया तुमची सिंक पासफ्रेज अपडेट करा.</translation>
 <translation id="113122355610423240">Chromium तुमचा डीफॉल्ट ब्राउझर आहे</translation>
 <translation id="1185134272377778587">Chromium बद्दल</translation>
 <translation id="1396446129537741364">Chromium पासवर्ड दर्शविण्याचा प्रयत्न करत आहे.</translation>
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb
index 39d6a93..fb0626f 100644
--- a/chrome/app/resources/chromium_strings_ms.xtb
+++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ms">
 <translation id="1065672644894730302">Pilihan anda tidak dapat dibaca. Beberapa ciri mungkin tidak tersedia dan perubahan terhadap pilihan tidak akan disimpan.</translation>
 <translation id="1104942323762546749">Chromium mahu mengeksport kata laluan anda. Taip kata laluan Windows anda untuk membenarkannya.</translation>
-<translation id="1115445892567829615">Chromium tidak dapat menyegerakkan data anda. Sila kemas kini frasa laluan Segerak anda.</translation>
 <translation id="113122355610423240">Chromium ialah penyemak imbas lalai anda</translation>
 <translation id="1185134272377778587">Mengenai Chromium</translation>
 <translation id="1396446129537741364">Chromium sedang cuba memaparkan kata laluan.</translation>
diff --git a/chrome/app/resources/chromium_strings_my.xtb b/chrome/app/resources/chromium_strings_my.xtb
index 6035c1ab..61cc812 100644
--- a/chrome/app/resources/chromium_strings_my.xtb
+++ b/chrome/app/resources/chromium_strings_my.xtb
@@ -5,7 +5,6 @@
 
 အချို့အင်္ဂရပ်များ မရရှိနိုင်ပါ၊ စိတ်ကြိုက်များသို့ ပြောင်းလဲခြင်းများ သိမ်းမည်မဟုတ်ပါ။</translation>
 <translation id="1104942323762546749">Chromium သည် သင်၏ စကားဝှက်များကို တင်ပို့လိုသည်။ ၎င်းကို ခွင့်ပြုရန် သင်၏ Windows စကားဝှက်ကို ထည့်ပါ။</translation>
-<translation id="1115445892567829615">Chromium က သင့် ဒေတာကို စင့်က် လုပ်မပေးနိုင်ခဲ့ပါ။ ကျေးဇူးပြုပြီး သင်၏ စင့်က် စကားစုဝှက်ကို မွမ်းမံပေးပါ။</translation>
 <translation id="113122355610423240">Chromium သည် သင်၏ မူရင်းဘရောင်ဇာဖြစ်သည်</translation>
 <translation id="1185134272377778587">Chromium အကြောင်း</translation>
 <translation id="1396446129537741364">Chromium က စကားဝှက်များကို ပြရန် ကြိုးစားနေသည်။</translation>
diff --git a/chrome/app/resources/chromium_strings_ne.xtb b/chrome/app/resources/chromium_strings_ne.xtb
index 31cdeae7..2d4e72f 100644
--- a/chrome/app/resources/chromium_strings_ne.xtb
+++ b/chrome/app/resources/chromium_strings_ne.xtb
@@ -5,7 +5,6 @@
 
 केही सुविधाहरू अनुपलब्ध हुन सक्छन् र प्राथमिकताहरूमा परिवर्तनहरू बचत हुने छैनन्।</translation>
 <translation id="1104942323762546749">Chromium तपाईंका पासवर्डहरू निर्यात गर्न चाहन्छ। यसो गर्ने अनुमति दिन Windows को आफ्नो पासवर्ड टाइप गर्नुहोस्‌।</translation>
-<translation id="1115445892567829615">Chromium ले तपाईंको डाटालाई समक्रमण गर्न सकेन। कृपया आप्नो समक्रमण पासफ्रेजलाई अद्यावधिक गर्नुहोस्।</translation>
 <translation id="113122355610423240">Chromium तपाईंको पूर्वनिर्धारित ब्राउजर हो</translation>
 <translation id="1185134272377778587">Chromium का बारेमा</translation>
 <translation id="1396446129537741364">Chromium ले पासवर्डहरू देखाउने प्रयास गर्दैछ।</translation>
diff --git a/chrome/app/resources/chromium_strings_nl.xtb b/chrome/app/resources/chromium_strings_nl.xtb
index 9ea9b48..1d50e9ab 100644
--- a/chrome/app/resources/chromium_strings_nl.xtb
+++ b/chrome/app/resources/chromium_strings_nl.xtb
@@ -5,7 +5,6 @@
 
 Sommige functies zijn wellicht niet beschikbaar en wijzigingen in voorkeuren worden niet opgeslagen.</translation>
 <translation id="1104942323762546749">Chromium wil je wachtwoorden exporteren. Geef je Windows-wachtwoord op om dit toe te staan.</translation>
-<translation id="1115445892567829615">Chromium kan je gegevens niet synchroniseren. Update je synchronisatiewachtwoord.</translation>
 <translation id="113122355610423240">Chromium is je standaardbrowser</translation>
 <translation id="1185134272377778587">Over Chromium</translation>
 <translation id="1396446129537741364">Chromium probeert wachtwoorden weer te geven.</translation>
diff --git a/chrome/app/resources/chromium_strings_no.xtb b/chrome/app/resources/chromium_strings_no.xtb
index 7619fd4..35882c4 100644
--- a/chrome/app/resources/chromium_strings_no.xtb
+++ b/chrome/app/resources/chromium_strings_no.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="no">
 <translation id="1065672644894730302">Kan ikke lese innstillingene. Enkelte funksjoner kan være utilgjengelige, og endringer av innstillingene blir ikke lagret.</translation>
 <translation id="1104942323762546749">Chromium forsøker å eksportere passordene dine. Skriv inn Windows-passordet ditt for å tillate dette.</translation>
-<translation id="1115445892567829615">Chromium kunne ikke synkronisere dataene dine. Oppdater passordfrasen for synkronisering.</translation>
 <translation id="113122355610423240">Chromium er standardnettleseren din</translation>
 <translation id="1185134272377778587">Om Chromium</translation>
 <translation id="1396446129537741364">Chromium prøver å vise passord.</translation>
diff --git a/chrome/app/resources/chromium_strings_or.xtb b/chrome/app/resources/chromium_strings_or.xtb
index 576b2b0..f718901 100644
--- a/chrome/app/resources/chromium_strings_or.xtb
+++ b/chrome/app/resources/chromium_strings_or.xtb
@@ -5,7 +5,6 @@
 
 କିଛି ବୈଶିଷ୍ଟ୍ୟ ହୁଏତ ଉପଲବ୍ଧ ନଥାଇପାରେ ଏବଂ ଅଗ୍ରାଧିକାରଗୁଡ଼ିକରେ କରାଯାଇଥିବା ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ସେଭ୍ ନହୋଇପାରେ।</translation>
 <translation id="1104942323762546749">ଆପଣଙ୍କର ପାସ୍‌ୱାର୍ଡଗୁଡିକୁ Chromium ଏକ୍ସପୋର୍ଟ କରିବାକୁ ଚାହେଁ। ଏହାକୁ ଅନୁମତି ଦେବାପାଇଁ ଆପଣଙ୍କର Windows ପାସ୍‌ୱର୍ଡ ଟାଇପ୍ କରନ୍ତୁ।</translation>
-<translation id="1115445892567829615">Chromium ଆପଣଙ୍କ ଡାଟାକୁ ସିଙ୍କ୍ କରିପାରିଲା ନାହିଁ। ଦୟାକରି ଆପଣଙ୍କର ସିଙ୍କ୍ ପାସ୍‌ଫ୍ରେଜ୍ ଅପ୍‌‌ଡେଟ୍ କରନ୍ତୁ।</translation>
 <translation id="113122355610423240">Chromium ହେଉଛି ଆପଣଙ୍କର ଡିଫଲ୍ଟ ବ୍ରାଉଜର୍</translation>
 <translation id="1185134272377778587">Chromium ବିଷୟରେ</translation>
 <translation id="1396446129537741364">ପାସ୍‌ୱର୍ଡଗୁଡ଼ିକ ଦେଖାଇବାକୁ Chromium ଚେଷ୍ଟା କରୁଛି।</translation>
diff --git a/chrome/app/resources/chromium_strings_pa.xtb b/chrome/app/resources/chromium_strings_pa.xtb
index 39cc897..4ad40b04 100644
--- a/chrome/app/resources/chromium_strings_pa.xtb
+++ b/chrome/app/resources/chromium_strings_pa.xtb
@@ -5,7 +5,6 @@
 
 ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਣਉਪਲਬਧ ਹੋ ਸਕਦੀਆਂ ਹਨ ਅਤੇੇ ਤਰਜੀਹਾਂ ਵਿੱਚ ਕੀਤੇ ਬਦਲਾਵ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤੇ ਜਾਣਗੇ।</translation>
 <translation id="1104942323762546749">Chromium ਤੁਹਾਡੇ ਪਾਸਵਰਡ ਨਿਰਯਾਤ ਕਰਨਾ ਚਾਹੁੰਦਾ ਹੈ। ਇਹ ਕਰਨ ਦੇਣ ਲਈ ਆਪਣਾ ਵਿੰਡੋ ਪਾਸਵਰਡ ਟਾਈਪ ਕਰੋ।</translation>
-<translation id="1115445892567829615">Chromium ਤੁਹਾਡਾ ਡਾਟਾ ਸਿੰਕ ਨਹੀਂ ਕਰ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਸਿੰਕ ਪਾਸਫਰੇਜ਼ ਅੱਪਡੇਟ ਕਰੋ।</translation>
 <translation id="113122355610423240">Chromium ਤੁਹਾਡਾ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਬ੍ਰਾਊਜ਼ਰ ਹੈ</translation>
 <translation id="1185134272377778587">Chromium ਬਾਰੇ</translation>
 <translation id="1396446129537741364">Chromium ਪਾਸਵਰਡ ਦਿਖਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ।</translation>
diff --git a/chrome/app/resources/chromium_strings_pl.xtb b/chrome/app/resources/chromium_strings_pl.xtb
index 80946a86..6daf6b1 100644
--- a/chrome/app/resources/chromium_strings_pl.xtb
+++ b/chrome/app/resources/chromium_strings_pl.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="pl">
 <translation id="1065672644894730302">Nie można odczytać ustawień. Niektóre funkcje mogą być niedostępne, a zmiany w ustawieniach nie zostaną zapisane.</translation>
 <translation id="1104942323762546749">Chromium chce wyeksportować Twoje hasła. Wpisz swoje hasło do Windows, by na to zezwolić.</translation>
-<translation id="1115445892567829615">Chromium nie może zsynchronizować Twoich danych. Zaktualizuj hasło synchronizacji.</translation>
 <translation id="113122355610423240">Chromium jest domyślną przeglądarką</translation>
 <translation id="1185134272377778587">Chromium – informacje</translation>
 <translation id="1396446129537741364">Chromium próbuje pokazać hasła.</translation>
diff --git a/chrome/app/resources/chromium_strings_pt-BR.xtb b/chrome/app/resources/chromium_strings_pt-BR.xtb
index 9d91f98..b228892 100644
--- a/chrome/app/resources/chromium_strings_pt-BR.xtb
+++ b/chrome/app/resources/chromium_strings_pt-BR.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="pt-BR">
 <translation id="1065672644894730302">Não foi possível ler suas preferências. Alguns recursos podem não estar disponíveis e as alterações nas preferências não serão salvas.</translation>
 <translation id="1104942323762546749">O Chromium quer exportar suas senhas. Digite sua senha do Windows para permitir isso.</translation>
-<translation id="1115445892567829615">O Chromium não pôde sincronizar seus dados. Atualize sua senha de sincronização.</translation>
 <translation id="113122355610423240">O Chromium é seu navegador padrão</translation>
 <translation id="1185134272377778587">Sobre o Chromium</translation>
 <translation id="1396446129537741364">O Chromium está tentando mostrar senhas.</translation>
diff --git a/chrome/app/resources/chromium_strings_pt-PT.xtb b/chrome/app/resources/chromium_strings_pt-PT.xtb
index 754dd04..62a2f356 100644
--- a/chrome/app/resources/chromium_strings_pt-PT.xtb
+++ b/chrome/app/resources/chromium_strings_pt-PT.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="pt-PT">
 <translation id="1065672644894730302">Não é possível ler as suas preferências. Algumas funcionalidades poderão estar indisponíveis e as alterações efetuadas às preferências não serão guardadas.</translation>
 <translation id="1104942323762546749">O Chromium pretende exportar as suas palavras-passe. Escreva a sua palavra-passe do Windows para permitir esta ação.</translation>
-<translation id="1115445892567829615">O Chromium não conseguiu sincronizar os dados. Atualize a frase de acesso da Sincronização.</translation>
 <translation id="113122355610423240">O Chromium é o seu navegador predefinido</translation>
 <translation id="1185134272377778587">Acerca do Chromium</translation>
 <translation id="1396446129537741364">O Chromium está a tentar mostrar palavras-passe.</translation>
diff --git a/chrome/app/resources/chromium_strings_ro.xtb b/chrome/app/resources/chromium_strings_ro.xtb
index ae9c38a6..5b2e4ba 100644
--- a/chrome/app/resources/chromium_strings_ro.xtb
+++ b/chrome/app/resources/chromium_strings_ro.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ro">
 <translation id="1065672644894730302">Preferințele dvs. nu pot fi citite. Este posibil ca unele funcții să nu fie disponibile, iar modificările aduse preferințelor nu vor fi salvate.</translation>
 <translation id="1104942323762546749">Chromium vrea să îți exporte parolele. Pentru a permite asta, introdu parola pentru Windows.</translation>
-<translation id="1115445892567829615">Chromium nu a putut sincroniza datele. Actualizați expresia de acces pentru sincronizare.</translation>
 <translation id="113122355610423240">Chromium este browserul prestabilit</translation>
 <translation id="1185134272377778587">Despre Chromium</translation>
 <translation id="1396446129537741364">Chromium încearcă să afișeze parolele.</translation>
diff --git a/chrome/app/resources/chromium_strings_ru.xtb b/chrome/app/resources/chromium_strings_ru.xtb
index c97c5be..8cc7c66 100644
--- a/chrome/app/resources/chromium_strings_ru.xtb
+++ b/chrome/app/resources/chromium_strings_ru.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ru">
 <translation id="1065672644894730302">Не удается получить настройки. Некоторые функции могут быть недоступны, а изменения настроек не будут сохраняться.</translation>
 <translation id="1104942323762546749">Чтобы экспортировать пароли из Chromium, введите пароль своего аккаунта Windows.</translation>
-<translation id="1115445892567829615">Chromium не удалось синхронизировать данные. Обновите кодовую фразу в Sync.</translation>
 <translation id="113122355610423240">Chromium используется как браузер по умолчанию</translation>
 <translation id="1185134272377778587">О Chromium</translation>
 <translation id="1396446129537741364">Вводимые пароли будут отображаться в Chromium.</translation>
diff --git a/chrome/app/resources/chromium_strings_si.xtb b/chrome/app/resources/chromium_strings_si.xtb
index 33ff560d..3bf4f95 100644
--- a/chrome/app/resources/chromium_strings_si.xtb
+++ b/chrome/app/resources/chromium_strings_si.xtb
@@ -5,7 +5,6 @@
 
 ඇතැම් විශේෂාංගයන් නොපැවතිය හැකි අතර තේරීම් වල සිදුකරන වෙනස්ක්ම් නොසුරැකෙනු ඇත.</translation>
 <translation id="1104942323762546749">Chromium හට ඔබගේ මුරපද නිර්යාත කිරීමට අවශ්‍යය. මේ සඳහා අවසර දීමට ඔබගේ Windows මුරපදය ටයිප් කරන්න.</translation>
-<translation id="1115445892567829615">Chromium හට ඔබේ දත්ත සම්මුහුර්ත කළ නොහැක. ඔබේ සමමුහුර්ත කිරීමේ මුරපදය යාවත්කාලීන කරන්න.</translation>
 <translation id="113122355610423240">Chromium ඔබේ පෙරනිමි බ්‍රව්සරය වේ</translation>
 <translation id="1185134272377778587">Chromium පිළිබඳ</translation>
 <translation id="1396446129537741364">Chromium මුරපද පෙන්වීමට උත්සාහ කරමින් සිටී.</translation>
diff --git a/chrome/app/resources/chromium_strings_sk.xtb b/chrome/app/resources/chromium_strings_sk.xtb
index a3a964a..1888d360 100644
--- a/chrome/app/resources/chromium_strings_sk.xtb
+++ b/chrome/app/resources/chromium_strings_sk.xtb
@@ -5,7 +5,6 @@
 
 Niektoré funkcie nemusia byť k dispozícii a zmeny vykonané v predvoľbách sa neuložia.</translation>
 <translation id="1104942323762546749">Prehliadač Chromium sa pokúša exportovať vaše heslá. Ak to chcete povoliť, zadajte heslo systému Windows.</translation>
-<translation id="1115445892567829615">Prehliadaču Chromium sa nepodarilo synchronizovať vaše údaje. Aktualizujte prístupovú frázu synchronizácie.</translation>
 <translation id="113122355610423240">Chromium je vaším predvoleným prehliadačom</translation>
 <translation id="1185134272377778587">Informácie o prehliadači Chromium</translation>
 <translation id="1396446129537741364">Prehliadač Chromium sa snaží zobraziť heslá.</translation>
diff --git a/chrome/app/resources/chromium_strings_sl.xtb b/chrome/app/resources/chromium_strings_sl.xtb
index 0676018..2c35fa1 100644
--- a/chrome/app/resources/chromium_strings_sl.xtb
+++ b/chrome/app/resources/chromium_strings_sl.xtb
@@ -5,7 +5,6 @@
 
 Nekatere funkcije morda niso na voljo in spremembe nastavitev ne bodo shranjene.</translation>
 <translation id="1104942323762546749">Chromium želi izvoziti gesla. Če želite omogočiti to, vnesite geslo za Windows.</translation>
-<translation id="1115445892567829615">Chromium ni mogel sinhronizirati podatkov. Posodobite sinhronizacijsko geslo.</translation>
 <translation id="113122355610423240">Chromium je privzeti brskalnik</translation>
 <translation id="1185134272377778587">O Chromiumu</translation>
 <translation id="1396446129537741364">Chromium poskuša prikazati gesla.</translation>
diff --git a/chrome/app/resources/chromium_strings_sq.xtb b/chrome/app/resources/chromium_strings_sq.xtb
index 28cdf16..1001078 100644
--- a/chrome/app/resources/chromium_strings_sq.xtb
+++ b/chrome/app/resources/chromium_strings_sq.xtb
@@ -5,7 +5,6 @@
 
 Disa funksione mund të mos ofrohen dhe ndryshimet në preferenca nuk do të ruhen.</translation>
 <translation id="1104942323762546749">Chromium dëshiron të eksportojë fjalëkalimet e tua. Shkruaj fjalëkalimin tënd të Windows për ta lejuar këtë.</translation>
-<translation id="1115445892567829615">Chromium nuk mundi të sinkronizonte të dhënat e tua. Përditëso shprehjen e kalimit për sinkronizim.</translation>
 <translation id="113122355610423240">Chromium është shfletuesi yt i parazgjedhur</translation>
 <translation id="1185134272377778587">Rreth Chromium</translation>
 <translation id="1396446129537741364">Chromium po përpiqet të shfaqë fjalëkalimet.</translation>
diff --git a/chrome/app/resources/chromium_strings_sr.xtb b/chrome/app/resources/chromium_strings_sr.xtb
index bd30894d..1146e01 100644
--- a/chrome/app/resources/chromium_strings_sr.xtb
+++ b/chrome/app/resources/chromium_strings_sr.xtb
@@ -5,7 +5,6 @@
 
 Неке функције су можда недоступне и промене подешавања неће бити сачуване.</translation>
 <translation id="1104942323762546749">Chromium жели да извезе лозинке. Унесите лозинку за Windows да бисте то омогућили.</translation>
-<translation id="1115445892567829615">Chromium не може да синхронизује податке. Ажурирајте приступну фразу за Синхронизацију.</translation>
 <translation id="113122355610423240">Chromium је подразумевани прегледач</translation>
 <translation id="1185134272377778587">О Chromium-у</translation>
 <translation id="1396446129537741364">Chromium покушава да прикаже лозинке.</translation>
diff --git a/chrome/app/resources/chromium_strings_sv.xtb b/chrome/app/resources/chromium_strings_sv.xtb
index a93e9e38..37d442de 100644
--- a/chrome/app/resources/chromium_strings_sv.xtb
+++ b/chrome/app/resources/chromium_strings_sv.xtb
@@ -5,7 +5,6 @@
 
 Vissa funktioner kanske inte är tillgängliga och ändringar i inställningarna sparas inte.</translation>
 <translation id="1104942323762546749">Lösenorden exporteras från Chromium. Skriv ditt Windows-lösenord om du tillåter detta.</translation>
-<translation id="1115445892567829615">Chromium kunde inte synkronisera data. Uppdatera lösenfrasen för synkroniseringen.</translation>
 <translation id="113122355610423240">Chromium är din standardwebbläsare</translation>
 <translation id="1185134272377778587">Om Chromium</translation>
 <translation id="1396446129537741364">Chromium försöker visa lösenord.</translation>
diff --git a/chrome/app/resources/chromium_strings_sw.xtb b/chrome/app/resources/chromium_strings_sw.xtb
index cd54430..4bc9402 100644
--- a/chrome/app/resources/chromium_strings_sw.xtb
+++ b/chrome/app/resources/chromium_strings_sw.xtb
@@ -5,7 +5,6 @@
 
 Baadhi ya vipengele huenda visipatikane na mabadiliko katika mapendeleo hayatahifadhiwa.</translation>
 <translation id="1104942323762546749">Chromium ingependa kuhamisha manenosiri yako. Andika nenosiri lako la Windows ili uruhusu shughuli hii.</translation>
-<translation id="1115445892567829615">Chromium haikuweza kusawazisha data yako. Tafadhali sasisha kauli siri yako ya Usawazishaji.</translation>
 <translation id="113122355610423240">Chromium ni kivinjari chako chaguomsingi</translation>
 <translation id="1185134272377778587">Kuhusu Chromium</translation>
 <translation id="1396446129537741364">Chromium inajaribu kuonyesha manenosiri.</translation>
diff --git a/chrome/app/resources/chromium_strings_ta.xtb b/chrome/app/resources/chromium_strings_ta.xtb
index c7a8e7b..13d5fc7 100644
--- a/chrome/app/resources/chromium_strings_ta.xtb
+++ b/chrome/app/resources/chromium_strings_ta.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="ta">
 <translation id="1065672644894730302">உங்கள் விருப்பதேர்வுகள் படிக்கும்படி இல்லை. சில அம்சங்கள் கிடைக்காமல் இருக்கலாம் மேலும் விருப்பதேர்வுகளின் மாற்றங்களைச் சேமிக்க முடியாது.</translation>
 <translation id="1104942323762546749">Chromium உங்கள் கடவுச்சொற்களை ஏற்ற விரும்புகிறது. இதை அனுமதிக்க, உங்கள் Windows கடவுச்சொல்லை உள்ளிடவும்.</translation>
-<translation id="1115445892567829615">Chromium ஆல் உங்கள் தரவை ஒத்திசைக்க முடியவில்லை. உங்கள் ஒத்திசைவு கடவுச்சொற்றொடரைப் புதுப்பிக்கவும்.</translation>
 <translation id="113122355610423240">உங்கள் இயல்புநிலை உலாவி Chromium ஆகும்</translation>
 <translation id="1185134272377778587">Chromium அறிமுகம்</translation>
 <translation id="1396446129537741364">Chromium ஆனது கடவுச்சொற்களைக் காட்ட முயற்சிக்கிறது.</translation>
diff --git a/chrome/app/resources/chromium_strings_te.xtb b/chrome/app/resources/chromium_strings_te.xtb
index 72815cc..a9a54dee 100644
--- a/chrome/app/resources/chromium_strings_te.xtb
+++ b/chrome/app/resources/chromium_strings_te.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="te">
 <translation id="1065672644894730302">మీ ప్రాధాన్యతలు చదవబడలేవు. కొన్ని లక్షణాలు అందుబాటులో ఉండకపోవచ్చు మరియు ప్రాధాన్యతలకు మార్పులు సేవ్ చేయబడకపోవచ్చు.</translation>
 <translation id="1104942323762546749">Chromium మీ పాస్‌వర్డ్‌లను ఎగుమతి చేయాలనుకుంటోంది. దీనిని అనుమతించడం కోసం మీ Windows పాస్‌వర్డ్‌ని టైప్ చేయండి.</translation>
-<translation id="1115445892567829615">Chromium మీ డేటాను సింక్ చేయ‌లేక‌పోయింది. దయచేసి మీ సింక్‌ రహస్య పదబంధాన్ని అప్‌డేట్ చేయండి.</translation>
 <translation id="113122355610423240">మీ డిఫాల్ట్ బ్రౌజర్ Chromium</translation>
 <translation id="1185134272377778587">Chromium గురించి</translation>
 <translation id="1396446129537741364">Chromium పాస్‌వర్డ్‌లను చూపడానికి ప్రయత్నిస్తోంది.</translation>
diff --git a/chrome/app/resources/chromium_strings_th.xtb b/chrome/app/resources/chromium_strings_th.xtb
index 1445f11..507a0ae9 100644
--- a/chrome/app/resources/chromium_strings_th.xtb
+++ b/chrome/app/resources/chromium_strings_th.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="th">
 <translation id="1065672644894730302">ค่ากำหนดของคุณไม่สามารถอ่านได้ ฟีเจอร์บางอย่างอาจใช้ไม่ได้และการเปลี่ยนแปลงค่ากำหนดจะไม่ได้รับการบันทึก</translation>
 <translation id="1104942323762546749">Chromium ต้องการส่งออกรหัสผ่านของคุณ พิมพ์รหัสผ่าน Windows เพื่ออนุญาตให้ดำเนินการ</translation>
-<translation id="1115445892567829615">Chromium ไม่สามารถซิงค์ข้อมูลของคุณ โปรดอัปเดตข้อความรหัสผ่านการซิงค์</translation>
 <translation id="113122355610423240">Chromium เป็นเบราว์เซอร์เริ่มต้นของคุณ</translation>
 <translation id="1185134272377778587">เกี่ยวกับ Chromium</translation>
 <translation id="1396446129537741364">Chromium กำลังพยายามแสดงรหัสผ่าน</translation>
diff --git a/chrome/app/resources/chromium_strings_tr.xtb b/chrome/app/resources/chromium_strings_tr.xtb
index 638f8af9..1f8511d 100644
--- a/chrome/app/resources/chromium_strings_tr.xtb
+++ b/chrome/app/resources/chromium_strings_tr.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="tr">
 <translation id="1065672644894730302">Tercihleriniz okunamıyor. Bazı özellikler kullanılamayabilir. Tercihlerde yapılan değişiklikler kaydedilmeyecektir.</translation>
 <translation id="1104942323762546749">Chromium, şifrelerinizi dışa aktarmak istiyor. Buna izin vermek için Windows şifrenizi yazın.</translation>
-<translation id="1115445892567829615">Chromium, verilerinizi senkronize edemedi. Lütfen Senkronizasyon parolanızı güncelleyin.</translation>
 <translation id="113122355610423240">Chromium varsayılan tarayıcınız</translation>
 <translation id="1185134272377778587">Chromium hakkında</translation>
 <translation id="1396446129537741364">Chromium, şifreleri göstermeye çalışıyor.</translation>
diff --git a/chrome/app/resources/chromium_strings_uk.xtb b/chrome/app/resources/chromium_strings_uk.xtb
index f2dc50e..c3729c74 100644
--- a/chrome/app/resources/chromium_strings_uk.xtb
+++ b/chrome/app/resources/chromium_strings_uk.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="uk">
 <translation id="1065672644894730302">Не вдається розпізнати налаштування. Деякі функції можуть бути не доступні, а зміни в налаштуваннях не зберігатимуться.</translation>
 <translation id="1104942323762546749">Chromium хоче експортувати ваші паролі. Щоб дозволити, введіть свій пароль Windows.</translation>
-<translation id="1115445892567829615">Chromium не вдалося синхронізувати ваші дані. Оновіть свою парольну фразу для синхронізації.</translation>
 <translation id="113122355610423240">Chromium – ваш веб-переглядач за умовчанням</translation>
 <translation id="1185134272377778587">Про Chromium</translation>
 <translation id="1396446129537741364">Chromium намагається показати паролі.</translation>
diff --git a/chrome/app/resources/chromium_strings_ur.xtb b/chrome/app/resources/chromium_strings_ur.xtb
index 0572135..7aa2356 100644
--- a/chrome/app/resources/chromium_strings_ur.xtb
+++ b/chrome/app/resources/chromium_strings_ur.xtb
@@ -5,7 +5,6 @@
 
 کچھ خصوصیات غیر دستیاب ہو سکتی ہیں اور ترجیحات میں تبدیلیاں محفوظ نہیں ہونگی۔</translation>
 <translation id="1104942323762546749">‏Chromium آپ کے پاس ورڈز برآمد کرنا چاہتا ہے۔ اس کی اجازت دینے کیلئے، اپنا Windows پاس ورڈ ٹائپ کریں۔</translation>
-<translation id="1115445892567829615">‏Chromium آپ کے ڈیٹا کی مطابقت پذیری نہیں کر سکا۔ براہ کرم اپنی Sync کا پاس فریز اپ ڈیٹ کریں۔</translation>
 <translation id="113122355610423240">‏Chromium آپ کا ڈیفالٹ براؤزر ہے</translation>
 <translation id="1185134272377778587">‏Chromium کے بارے میں</translation>
 <translation id="1396446129537741364">‏Chromium پاس ورڈز دکھانے کی کوشش کر رہا ہے۔</translation>
diff --git a/chrome/app/resources/chromium_strings_uz.xtb b/chrome/app/resources/chromium_strings_uz.xtb
index 769848a..0d2a72d 100644
--- a/chrome/app/resources/chromium_strings_uz.xtb
+++ b/chrome/app/resources/chromium_strings_uz.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="uz">
 <translation id="1065672644894730302">Sozlamalarni ko‘rib bo‘lmadi. Ba’zi funksiyalar mavjud emas va o‘zgartirilgan sozlamalar saqlanmaydi.</translation>
 <translation id="1104942323762546749">Chromium parollaringizni eksport qilmoqchi. Ruxsat berish uchun Windows platformasidagi parolingizni kiriting.</translation>
-<translation id="1115445892567829615">Chromium ma’lumotlarni sinxronlay olmadi. Sync kodli iborasini yangilashingiz kerak.</translation>
 <translation id="113122355610423240">Qurilmangizdagi asosiy brauzer – Chromium.</translation>
 <translation id="1185134272377778587">Chromium haqida</translation>
 <translation id="1396446129537741364">Kirtilgan parollar Chromium brauzerida ko‘rsatiladi.</translation>
diff --git a/chrome/app/resources/chromium_strings_vi.xtb b/chrome/app/resources/chromium_strings_vi.xtb
index 4ac1538..c3928690 100644
--- a/chrome/app/resources/chromium_strings_vi.xtb
+++ b/chrome/app/resources/chromium_strings_vi.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="vi">
 <translation id="1065672644894730302">Không thể đọc tùy chọn của bạn. Một số tính năng có thể không khả dụng và các thay đổi đối với tùy chọn sẽ không được lưu.</translation>
 <translation id="1104942323762546749">Chromium muốn xuất các mật khẩu của bạn. Hãy nhập mật khẩu Windows để cho phép thực hiện việc này.</translation>
-<translation id="1115445892567829615">Chromium không thể đồng bộ hóa dữ liệu của bạn. Vui lòng cập nhật cụm mật khẩu Đồng bộ hóa của bạn.</translation>
 <translation id="113122355610423240">Chromium là trình duyệt mặc định của bạn</translation>
 <translation id="1185134272377778587">Giới thiệu về Chromium</translation>
 <translation id="1396446129537741364">Chromium đang cố gắng hiển thị mật khẩu.</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-CN.xtb b/chrome/app/resources/chromium_strings_zh-CN.xtb
index 892cff3..62748d6 100644
--- a/chrome/app/resources/chromium_strings_zh-CN.xtb
+++ b/chrome/app/resources/chromium_strings_zh-CN.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="zh-CN">
 <translation id="1065672644894730302">系统无法读取您的偏好设置。某些功能可能无法使用,并且对偏好设置所做的更改不会保存。</translation>
 <translation id="1104942323762546749">Chromium 想导出您的密码。请输入您的 Windows 密码以允许此操作。</translation>
-<translation id="1115445892567829615">Chromium无法同步您的数据。请更新您的同步密码。</translation>
 <translation id="113122355610423240">Chromium 是您的默认浏览器</translation>
 <translation id="1185134272377778587">关于 Chromium</translation>
 <translation id="1396446129537741364">Chromium 正尝试显示密码。</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-HK.xtb b/chrome/app/resources/chromium_strings_zh-HK.xtb
index 468d1905..9354426 100644
--- a/chrome/app/resources/chromium_strings_zh-HK.xtb
+++ b/chrome/app/resources/chromium_strings_zh-HK.xtb
@@ -5,7 +5,6 @@
 
 部分功能可能無法使用,而系統也不會儲存任何偏好設定的變更。</translation>
 <translation id="1104942323762546749">Chromium 想匯出您的密碼。請輸入 Windows 密碼以允許此操作。</translation>
-<translation id="1115445892567829615">Chromium 無法同步處理您的數據,請更新您的同步複雜密碼。</translation>
 <translation id="113122355610423240">Chromium 現為您的預設瀏覽器</translation>
 <translation id="1185134272377778587">關於 Chromium</translation>
 <translation id="1396446129537741364">Chromium 即將顯示密碼。</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-TW.xtb b/chrome/app/resources/chromium_strings_zh-TW.xtb
index ee6752c..02342d5d 100644
--- a/chrome/app/resources/chromium_strings_zh-TW.xtb
+++ b/chrome/app/resources/chromium_strings_zh-TW.xtb
@@ -3,7 +3,6 @@
 <translationbundle lang="zh-TW">
 <translation id="1065672644894730302">系統無法讀取你的偏好設定。部分功能可能無法使用,且系統也不會儲存任何偏好設定的變更。</translation>
 <translation id="1104942323762546749">Chromium 要求匯出你的密碼。如果允許,請輸入你的 Windows 密碼。</translation>
-<translation id="1115445892567829615">Chromium 無法同步處理你的資料,請更新你的同步通關密語。</translation>
 <translation id="113122355610423240">Chromium 是你的預設瀏覽器</translation>
 <translation id="1185134272377778587">關於 Chromium</translation>
 <translation id="1396446129537741364">Chromium 即將顯示密碼。</translation>
diff --git a/chrome/app/resources/chromium_strings_zu.xtb b/chrome/app/resources/chromium_strings_zu.xtb
index f49a817..6acd6c0 100644
--- a/chrome/app/resources/chromium_strings_zu.xtb
+++ b/chrome/app/resources/chromium_strings_zu.xtb
@@ -5,7 +5,6 @@
 
 Ezinye izici kungenzeka zingabi khona futhi izinguquko kokuncamelayo ngeke zize zilondolozwe.</translation>
 <translation id="1104942323762546749">I-Chromium ifuna ukuthumela amaphasiwedi akho. Thayipha iphasiwedi yakho ye-Windows ukuze uvumele lokhu.</translation>
-<translation id="1115445892567829615">I-Chromium ayikwazanga ukuvumelanisa idatha yakho. Sicela ubuyekeze umushwana wokungena wakho wokuvumelanisa.</translation>
 <translation id="113122355610423240">I-Chromium iyisiphequluli sakho esizenzakalelayo</translation>
 <translation id="1185134272377778587">Mayelana ne-Chromium</translation>
 <translation id="1396446129537741364">I-Chromium izama ukubonisa amaphasiwedi.</translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb
index 64a05b2..b61acfc5 100644
--- a/chrome/app/resources/generated_resources_af.xtb
+++ b/chrome/app/resources/generated_resources_af.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Voer die PIN vir jou sekuriteitsleutel in</translation>
 <translation id="457386861538956877">Nog meer …</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bind Bluetooth-toestel saam</translation>
 <translation id="4579581181964204535">Kan nie <ph name="HOST_NAME" /> uitsaai nie.</translation>
 <translation id="4581774856936278355">Kon nie Linux terugstel nie</translation>
 <translation id="4582563038311694664">Stel alle instellings terug</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Oorskandeer</translation>
 <translation id="7978412674231730200">Private sleutel</translation>
 <translation id="7978450511781612192">Dit sal jou by al jou Google-rekeninge afmeld. Jou boekmerke, geskiedenis, wagwoorde en meer sal nie meer gesinkroniseer word nie.</translation>
-<translation id="7979036127916589816">Sinkroniseringfout</translation>
 <translation id="7980084013673500153">Bate-ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Laai bladsye vooraf om vinniger te blaai en te soek</translation>
 <translation id="798145602633458219">Heg hierdie voorstel <ph name="SUGGESTION_NAME" /> aan soekkassie</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">Uitbreidings</translation>
 <translation id="862727964348362408">Opgeskort</translation>
 <translation id="862750493060684461">CSS-kas</translation>
+<translation id="8627706565932943526">Sinkroniseringfout</translation>
 <translation id="8627795981664801467">Net beveiligde verbindings</translation>
 <translation id="8630903300770275248">Voer gebruiker onder toesig in</translation>
 <translation id="8631032106121706562">Blomblare</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index 1759566..36e4969 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">ለእርስዎ የደህንነት ቁልፍ ፒን ያስገቡ</translation>
 <translation id="457386861538956877">ተጨማሪ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">የብሉቱዝ መሣሪያን ያጣምሩ</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />ን cast ማድረግ አልተቻለም።</translation>
 <translation id="4581774856936278355">Linux እንደነበረ መመለስ ላይ ስህተት</translation>
 <translation id="4582563038311694664">ሁሉንም ቅንብሮች ዳግም አስጀምር</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">ትርፍ ቅኝት</translation>
 <translation id="7978412674231730200">የግል ቁልፍ</translation>
 <translation id="7978450511781612192">ይህ ከእርስዎ የGoogle መለያዎች ዘግተው እንዲወጡ ያደርግዎታል። የእርስዎ እልባቶች፣ ታሪክ፣ የይለፍ ቃላት እና ተጨማሪ ነገሮች ከእንግዲህ አይሰምሩም።</translation>
-<translation id="7979036127916589816">የማመሳሰል ስህተት</translation>
 <translation id="7980084013673500153">የእሴት መታወቂያ፦ <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ይበልጥ ፈጣን ለሆነ አሰሳ እና ፍለጋ ገጾችን ቅድሚያ ይጫኑ</translation>
 <translation id="798145602633458219">ሳጥኑን ለመፈለግ የአስተያየት ጥቆማ <ph name="SUGGESTION_NAME" />ን አያይዝ</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;ቅጥያዎች</translation>
 <translation id="862727964348362408">ተንጠልጥሏል</translation>
 <translation id="862750493060684461">የCSS መሸጎጫ</translation>
+<translation id="8627706565932943526">የማመሳሰል ስህተት</translation>
 <translation id="8627795981664801467">ጥብቅ የሆኑ ግንኙነቶች ብቻ</translation>
 <translation id="8630903300770275248">ትክክል የሚደረግበት ተጠቃሚ አስመጣ</translation>
 <translation id="8631032106121706562">እንቡጥ አበቦች</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index 199f2c3..a439632 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">يُرجى إدخال رقم التعريف الشخصي لمفتاح الأمان</translation>
 <translation id="457386861538956877">المزيد...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">إقران جهاز بلوتوث</translation>
 <translation id="4579581181964204535">يتعذّر إرسال <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">‏حدث خطأ أثناء استعادة Linux</translation>
 <translation id="4582563038311694664">إعادة تعيين كل الإعدادات</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">الخروج عن إطار الشاشة</translation>
 <translation id="7978412674231730200">مفتاح خاص</translation>
 <translation id="7978450511781612192">‏سيؤدي ذلك إلى تسجيل خروجك من حساباتك على Google. ولن تتم بعد ذلك مزامنة الإشارات المرجعية والسجلّ وكلمات المرور والمزيد.</translation>
-<translation id="7979036127916589816">حدث خطأ في المزامنة</translation>
 <translation id="7980084013673500153">رقم تعريف مادة العرض: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">التحميل المُسبق للصفحات للحصول على أداء أسرع أثناء التصفّح والبحث</translation>
 <translation id="798145602633458219">إضافة الاقتراح <ph name="SUGGESTION_NAME" /> إلى مربَّع البحث</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;الإضافات</translation>
 <translation id="862727964348362408">معلقة</translation>
 <translation id="862750493060684461">‏ذاكرة التخزين المؤقت للغة CSS</translation>
+<translation id="8627706565932943526">حدث خطأ أثناء المزامنة</translation>
 <translation id="8627795981664801467">الاتصالات الآمنة فقط</translation>
 <translation id="8630903300770275248">استيراد مستخدم يخضع للإشراف</translation>
 <translation id="8631032106121706562">البتلات</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb
index eeb598b..9ce7b4e 100644
--- a/chrome/app/resources/generated_resources_as.xtb
+++ b/chrome/app/resources/generated_resources_as.xtb
@@ -2489,7 +2489,6 @@
 <translation id="4572779512957829735">আপোনাৰ সুৰক্ষা চাবিৰ পিনটো দিয়ক</translation>
 <translation id="457386861538956877">অধিক…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ব্লুটুথ ডিভাইচ যোৰা লগাওক</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> কাষ্ট কৰিব পৰা নগ’ল।</translation>
 <translation id="4581774856936278355">Linux পুনঃস্থাপন কৰি থাকোঁতে আসোঁৱাহ হ’ল</translation>
 <translation id="4582563038311694664">সকলো ছেটিং ৰিছেট কৰক</translation>
@@ -4799,7 +4798,6 @@
 <translation id="7974936243149753750">অ’ভাৰস্কেন</translation>
 <translation id="7978412674231730200">ব্যক্তিগত কী</translation>
 <translation id="7978450511781612192">এই কার্যয়ে আপোনাক নিজৰ Google একাউণ্টৰ পৰা ছাইন আউট কৰাব। আপোনাৰ বুকমাৰ্ক, ইতিহাস, পাছৱর্ড তথা অধিক সমল আৰু ছিংক কৰা নহয়।</translation>
-<translation id="7979036127916589816">ছিংকৰ আসোঁৱাহ</translation>
 <translation id="7980084013673500153">সম্পদৰ আইডি: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">দ্ৰুতভাৱে ব্ৰাউজ আৰু সন্ধান কৰিবলৈ পৃষ্ঠা আগতীয়াকৈ ল'ড কৰক</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> চুপাৰিছটো সন্ধান বাকচলৈ এপেণ্ড কৰক</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb
index 0aa918bb..c149f387 100644
--- a/chrome/app/resources/generated_resources_az.xtb
+++ b/chrome/app/resources/generated_resources_az.xtb
@@ -2522,7 +2522,6 @@
 <translation id="4572779512957829735">Təhlükəsizlik açarı üçün PIN daxil edin</translation>
 <translation id="457386861538956877">Digər...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth cihazı ilə qoşalaşdırın</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> hostunu yayımlamaq mümkün olmadı.</translation>
 <translation id="4581774856936278355">Linux bərpa edilərkən xəta baş verdi</translation>
 <translation id="4582563038311694664">Bütün ayarları sıfırlayın</translation>
@@ -4860,7 +4859,6 @@
 <translation id="7974936243149753750">Overskan</translation>
 <translation id="7978412674231730200">Şəxsi açar</translation>
 <translation id="7978450511781612192">Bununla Google Hesablarınızdan çıxacaqsınız. Əlfəcin, tarixçə, parol və digərləri artıq sinxronizasiya olunmayacaq.</translation>
-<translation id="7979036127916589816">Sinxronlaşdırma Xətası</translation>
 <translation id="7980084013673500153">Obyekt identifikatoru: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Sürətli axtarış üçün səhifələri əvvəlcədən yükləyin</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> təklifini axtarış xanasına əlavə edin</translation>
@@ -5307,6 +5305,7 @@
 <translation id="862542460444371744">Artırmalar</translation>
 <translation id="862727964348362408">Ləğv edilib</translation>
 <translation id="862750493060684461">CSS keşi</translation>
+<translation id="8627706565932943526">Sinx xətası</translation>
 <translation id="8627795981664801467">Yalnız bağlantıları güvənli edin</translation>
 <translation id="8630903300770275248">Nəzarət edilən istifadəçini import edin</translation>
 <translation id="8631032106121706562">Ləçəklər</translation>
diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb
index eebda027..1f91493 100644
--- a/chrome/app/resources/generated_resources_be.xtb
+++ b/chrome/app/resources/generated_resources_be.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Увядзіце PIN-код для ключа бяспекі</translation>
 <translation id="457386861538956877">Яшчэ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Спалучыць прыладу Bluetooth</translation>
 <translation id="4579581181964204535">Не ўдаецца трансліраваць <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Памылка падчас аднаўлення кантэйнера Linux</translation>
 <translation id="4582563038311694664">Скінуць усе налады</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Вылет разгорткі</translation>
 <translation id="7978412674231730200">Закрыты ключ</translation>
 <translation id="7978450511781612192">Вы выйдзеце з Уліковых запісаў Google. Вашы закладкі, гісторыя, паролі і г. д. больш не будуць сінхранізавацца.</translation>
-<translation id="7979036127916589816">Памылка сінхранізацыі</translation>
 <translation id="7980084013673500153">Ідэнтыфікатар аб'екта ўласнасці: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Папярэдне загружаць старонкі для больш хуткага прагляду і пошуку</translation>
 <translation id="798145602633458219">Дадаць у поле пошуку прапанову "<ph name="SUGGESTION_NAME" />"</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index 59a56164..6081804 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Въведете ПИН кода за ключа си за сигурност</translation>
 <translation id="457386861538956877">Още...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Сдвояване на устройство с Bluetooth</translation>
 <translation id="4579581181964204535">Предаването на <ph name="HOST_NAME" /> не е възможно.</translation>
 <translation id="4581774856936278355">Грешка при възстановяването на Linux</translation>
 <translation id="4582563038311694664">Нулиране на всички настройки</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Допълнителна област</translation>
 <translation id="7978412674231730200">Личен ключ</translation>
 <translation id="7978450511781612192">Така ще излезете от профилите си в Google. Вашите отметки, история, пароли и др. повече няма да се синхронизират.</translation>
-<translation id="7979036127916589816">Грешка при синхронизирането</translation>
 <translation id="7980084013673500153">Идент. № на актива: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Предварително зареждане на страниците с цел по-бързо сърфиране и търсене</translation>
 <translation id="798145602633458219">Добавяне на предложението <ph name="SUGGESTION_NAME" /> към полето за търсене</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Разширения</translation>
 <translation id="862727964348362408">Спряно</translation>
 <translation id="862750493060684461">Кеш за CSS</translation>
+<translation id="8627706565932943526">Грешка при синхронизирането</translation>
 <translation id="8627795981664801467">Само сигурни връзки</translation>
 <translation id="8630903300770275248">Импортиране на контролиран потребител</translation>
 <translation id="8631032106121706562">Цвете</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index dae57ece..a9a5b5c 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">আপনার নিরাপত্তা কীয়ের পিনটি লিখুন</translation>
 <translation id="457386861538956877">আরও...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ব্লুটুথ ডিভাইস যুক্ত করুন</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> কাস্ট করতে ব্যর্থ হয়েছে।</translation>
 <translation id="4581774856936278355">Linux ফিরিয়ে আনার সময় সমস্যা হয়েছে</translation>
 <translation id="4582563038311694664">সব সেটিংস রিসেট করুন</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">ওভারস্ক্যান</translation>
 <translation id="7978412674231730200">ব্যক্তিগত কী</translation>
 <translation id="7978450511781612192">এটি আপনাকে আপনার Google অ্যাকাউন্ট থেকে সাইন-আউট করিয়ে দেবে। আপনার বুকমার্ক, ইতিহাস, পাসওয়ার্ড এবং আরও অনেক কিছু আর সিঙ্ক করা হবে না।</translation>
-<translation id="7979036127916589816">সিঙ্ক ত্রুটি</translation>
 <translation id="7980084013673500153">সম্পত্তি আইডি: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">আরও দ্রুত ব্রাউজ করা এবং খোঁজার জন্য পৃষ্ঠা আগে লোড করুন</translation>
 <translation id="798145602633458219">সার্চ বক্সে <ph name="SUGGESTION_NAME" /> সাজেশন যোগ করুন</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;এক্সটেনশনস</translation>
 <translation id="862727964348362408">সাসপেন্ড</translation>
 <translation id="862750493060684461">CSS ক্যাশে</translation>
+<translation id="8627706565932943526">সিঙ্ক ত্রুটি</translation>
 <translation id="8627795981664801467">কেবলমাত্র নিরাপদ কানেকশন</translation>
 <translation id="8630903300770275248">তত্ত্বাবধানে থাকা ব্যবহারকারীকে ইমপোর্ট করুন</translation>
 <translation id="8631032106121706562">পাপড়ি</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb
index fa30f5e3..23d7b1f 100644
--- a/chrome/app/resources/generated_resources_bs.xtb
+++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Unesite PIN za svoj sigurnosni ključ</translation>
 <translation id="457386861538956877">Više...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Uparivanje Bluetooth uređaja</translation>
 <translation id="4579581181964204535">Nije moguće emitirati host računar <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Greška prilikom vraćanja Linuxa</translation>
 <translation id="4582563038311694664">Vrati sve postavke na zadano</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Ivično područje ekrana</translation>
 <translation id="7978412674231730200">Privatni ključ</translation>
 <translation id="7978450511781612192">Ovo će vas odjaviti s vaših Google računa. Vaše oznake, historija, lozinke i još mnogo toga neće više biti sinhronizirani.</translation>
-<translation id="7979036127916589816">Greška prilikom sinhroniziranja</translation>
 <translation id="7980084013673500153">ID materijala: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Prethodno učitaj stranice za brže pregledavanje i pretraživanje</translation>
 <translation id="798145602633458219">Dodaj prijedlog <ph name="SUGGESTION_NAME" /> u okvir za pretraživanje</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Ekstenzije</translation>
 <translation id="862727964348362408">Suspendirana</translation>
 <translation id="862750493060684461">CSS keš memorija</translation>
+<translation id="8627706565932943526">Pogreška sinkronizacije</translation>
 <translation id="8627795981664801467">Samo sigurne veze</translation>
 <translation id="8630903300770275248">Uvezi korisnika pod nadzorom</translation>
 <translation id="8631032106121706562">Latice</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb
index 10afdca..72729e07 100644
--- a/chrome/app/resources/generated_resources_ca.xtb
+++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Introdueix el PIN de la clau de seguretat</translation>
 <translation id="457386861538956877">Més...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Vincula un dispositiu Bluetooth</translation>
 <translation id="4579581181964204535">No es pot emetre <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">S'ha produït un error en restaurar Linux</translation>
 <translation id="4582563038311694664">Restableix tota la configuració</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Ajusta la mida</translation>
 <translation id="7978412674231730200">Clau privada</translation>
 <translation id="7978450511781612192">Aquesta acció tancarà la sessió dels Comptes de Google. Les adreces d'interès, l'historial, les contrasenyes i altres opcions es deixaran de sincronitzar.</translation>
-<translation id="7979036127916589816">Error de sincronització</translation>
 <translation id="7980084013673500153">Identificador de l'element: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Carrega les pàgines prèviament per poder-hi navegar i fer cerques més de pressa</translation>
 <translation id="798145602633458219">Afegeix el suggeriment <ph name="SUGGESTION_NAME" /> al quadre de cerca</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Extensions</translation>
 <translation id="862727964348362408">Suspesa</translation>
 <translation id="862750493060684461">Memòria cau CSS</translation>
+<translation id="8627706565932943526">Error de sincronització</translation>
 <translation id="8627795981664801467">Només les connexions segures</translation>
 <translation id="8630903300770275248">Importa un usuari supervisat</translation>
 <translation id="8631032106121706562">Flor</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb
index 8b7d055..dd3bccd 100644
--- a/chrome/app/resources/generated_resources_cs.xtb
+++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">Zadejte PIN bezpečnostního klíče</translation>
 <translation id="457386861538956877">Další...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Párování zařízení Bluetooth</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> nelze odeslat.</translation>
 <translation id="4581774856936278355">Při obnovování systému Linux došlo k chybě</translation>
 <translation id="4582563038311694664">Resetovat všechna nastavení</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">Přesah obrazu</translation>
 <translation id="7978412674231730200">Soukromý klíč</translation>
 <translation id="7978450511781612192">Tímto se odhlásíte ze svých účtů Google. Vaše záložky, historie, hesla a další údaje již nebudou synchronizovány.</translation>
-<translation id="7979036127916589816">Chyba synchronizace</translation>
 <translation id="7980084013673500153">ID díla: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Předběžně načítat stránky pro rychlejší procházení a vyhledávání</translation>
 <translation id="798145602633458219">Přidat návrh <ph name="SUGGESTION_NAME" /> do vyhledávacího pole</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">Rozšíř&amp;ení</translation>
 <translation id="862727964348362408">Pozastaveno</translation>
 <translation id="862750493060684461">Mezipaměť CSS</translation>
+<translation id="8627706565932943526">Chyba synchronizace</translation>
 <translation id="8627795981664801467">Pouze zabezpečená spojení</translation>
 <translation id="8630903300770275248">Importovat dozorovaného uživatele</translation>
 <translation id="8631032106121706562">Kopretina</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index e6053e2..3f896d1 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Angiv pinkoden til din sikkerhedsnøgle</translation>
 <translation id="457386861538956877">Flere...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Par Bluetooth-enhed</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> kunne ikke castes.</translation>
 <translation id="4581774856936278355">Der opstod en fejl ved gendannelsen af Linux</translation>
 <translation id="4582563038311694664">Nulstil alle indstillinger</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Privat nøgle</translation>
 <translation id="7978450511781612192">Dermed logges du ud af dine Google-konti. Dine bogmærker, din historik, dine adgangskoder m.m. synkroniseres ikke længere.</translation>
-<translation id="7979036127916589816">Synkroniseringsfejl</translation>
 <translation id="7980084013673500153">Aktiv-id: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Forudindlæs sider, så du kan browse og søge hurtigere</translation>
 <translation id="798145602633458219">Føj forslaget <ph name="SUGGESTION_NAME" /> til søgefeltet</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Udvidelser</translation>
 <translation id="862727964348362408">På pause</translation>
 <translation id="862750493060684461">CSS-cache</translation>
+<translation id="8627706565932943526">Synkroniseringsfejl</translation>
 <translation id="8627795981664801467">Kun sikre forbindelser</translation>
 <translation id="8630903300770275248">Importér administreret bruger</translation>
 <translation id="8631032106121706562">Marguerit</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb
index 3e312b1..6ce9878e 100644
--- a/chrome/app/resources/generated_resources_de.xtb
+++ b/chrome/app/resources/generated_resources_de.xtb
@@ -2525,7 +2525,6 @@
 <translation id="4572779512957829735">Geben Sie die PIN für Ihren Sicherheitsschlüssel ein</translation>
 <translation id="457386861538956877">Mehr...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth-Gerät koppeln</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> kann nicht gestreamt werden.</translation>
 <translation id="4581774856936278355">Fehler beim Wiederherstellen von Linux</translation>
 <translation id="4582563038311694664">Alle Einstellungen zurücksetzen</translation>
@@ -4865,7 +4864,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Privater Schlüssel</translation>
 <translation id="7978450511781612192">Dadurch werden Sie aus Ihren Google-Konten abgemeldet. Ihre Lesezeichen, Ihr Verlauf, Ihre Passwörter usw. werden nicht mehr synchronisiert.</translation>
-<translation id="7979036127916589816">Synchronisierungsfehler</translation>
 <translation id="7980084013673500153">Geräte-ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Seiten vorab laden, um das Surfen und die Suche zu beschleunigen</translation>
 <translation id="798145602633458219">Vorschlag "<ph name="SUGGESTION_NAME" />" an Suchfeld anhängen</translation>
@@ -5313,6 +5311,7 @@
 <translation id="862542460444371744">&amp;Erweiterungen</translation>
 <translation id="862727964348362408">Ausgesetzt</translation>
 <translation id="862750493060684461">CSS-Cache</translation>
+<translation id="8627706565932943526">Synchronisierungsfehler</translation>
 <translation id="8627795981664801467">Nur sichere Verbindungen</translation>
 <translation id="8630903300770275248">Betreuten Nutzer importieren</translation>
 <translation id="8631032106121706562">Margerite</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index b5e4021..662bbc10 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Εισαγάγετε το PIN για το κλειδί ασφαλείας σας</translation>
 <translation id="457386861538956877">Περισσότερα...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Σύζευξη συσκευής Bluetooth</translation>
 <translation id="4579581181964204535">Δεν είναι δυνατή η μετάδοση <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Σφάλμα κατά την επαναφορά του Linux</translation>
 <translation id="4582563038311694664">Επαναφορά όλων των ρυθμίσεων</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Υπερσάρωση</translation>
 <translation id="7978412674231730200">Ιδιωτικό κλειδί</translation>
 <translation id="7978450511781612192">Με αυτήν την ενέργεια, θα αποσυνδεθείτε από τους Λογαριασμούς σας Google. Οι σελιδοδείκτες, το ιστορικό, οι κωδικοί πρόσβασης και άλλες ρυθμίσεις δεν θα συγχρονίζονται πλέον.</translation>
-<translation id="7979036127916589816">Σφάλμα συγχρονισμού</translation>
 <translation id="7980084013673500153">Αναγνωριστικό στοιχείου: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Προφόρτωση ιστοσελίδων για ταχύτερη περιήγηση και αναζήτηση</translation>
 <translation id="798145602633458219">Προσαρτήστε την πρόταση <ph name="SUGGESTION_NAME" /> στο πλαίσιο αναζήτησης</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;Επεκτάσεις</translation>
 <translation id="862727964348362408">Σε αναστολή</translation>
 <translation id="862750493060684461">Προσωρινή μνήμη CSS</translation>
+<translation id="8627706565932943526">Σφάλμα συγχρονισμού</translation>
 <translation id="8627795981664801467">Μόνο ασφαλείς συνδέσεις</translation>
 <translation id="8630903300770275248">Εισαγωγή χρήστη υπό επίβλεψη</translation>
 <translation id="8631032106121706562">Πέταλα</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index fede051..cdd319c 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Enter the PIN for your security key</translation>
 <translation id="457386861538956877">More...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Pair Bluetooth device</translation>
 <translation id="4579581181964204535">Unable to cast <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Error while restoring Linux</translation>
 <translation id="4582563038311694664">Reset all settings</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Private key</translation>
 <translation id="7978450511781612192">This will sign you out of your Google accounts. Your bookmarks, history, passwords and more will no longer be synced.</translation>
-<translation id="7979036127916589816">Sync Error</translation>
 <translation id="7980084013673500153">Asset ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Preload pages for faster browsing and searching</translation>
 <translation id="798145602633458219">Append the suggestion <ph name="SUGGESTION_NAME" /> to search box</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Extensions</translation>
 <translation id="862727964348362408">Suspended</translation>
 <translation id="862750493060684461">CSS cache</translation>
+<translation id="8627706565932943526">Sync error</translation>
 <translation id="8627795981664801467">Secure connections only</translation>
 <translation id="8630903300770275248">Import supervised user</translation>
 <translation id="8631032106121706562">Petals</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index e1d15ad..280ec48 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Ingresa el PIN para tu llave de seguridad</translation>
 <translation id="457386861538956877">Más ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Sincronizar dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">No se puede transmitir <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Se produjo un error al restablecer Linux</translation>
 <translation id="4582563038311694664">Restablecer toda la configuración</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">Desajuste de dimensiones</translation>
 <translation id="7978412674231730200">Clave privada</translation>
 <translation id="7978450511781612192">Con esta acción, saldrás de tus cuentas de Google. Ya no se sincronizarán tus favoritos, historial ni contraseñas, entre otros datos.</translation>
-<translation id="7979036127916589816">Error de sincronización</translation>
 <translation id="7980084013673500153">ID de activo: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Cargar previamente las páginas para acelerar la navegación y las búsquedas</translation>
 <translation id="798145602633458219">Agregar la sugerencia <ph name="SUGGESTION_NAME" /> al cuadro de búsqueda</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">&amp;Extensiones</translation>
 <translation id="862727964348362408">En suspensión</translation>
 <translation id="862750493060684461">Caché CSS</translation>
+<translation id="8627706565932943526">Error al sincronizar</translation>
 <translation id="8627795981664801467">Conexiones seguras solamente</translation>
 <translation id="8630903300770275248">Importar usuario supervisado</translation>
 <translation id="8631032106121706562">Pétalos</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb
index fd4b4e1..3c1f9ba 100644
--- a/chrome/app/resources/generated_resources_es.xtb
+++ b/chrome/app/resources/generated_resources_es.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Introduce el PIN de la llave de seguridad</translation>
 <translation id="457386861538956877">Más...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Vincular dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">No se puede enviar <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Error al restaurar Linux</translation>
 <translation id="4582563038311694664">Recuperar configuración completa</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Reajuste</translation>
 <translation id="7978412674231730200">Clave privada</translation>
 <translation id="7978450511781612192">Se cerrará la sesión en tus cuentas de Google. Tus marcadores, historial, contraseñas y otros elementos dejarán de sincronizarse.</translation>
-<translation id="7979036127916589816">Error de sincronización</translation>
 <translation id="7980084013673500153">ID de recurso: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Cargar previamente las páginas para que la navegación y las búsquedas sean más rápidas</translation>
 <translation id="798145602633458219">Añadir la sugerencia <ph name="SUGGESTION_NAME" /> al cuadro de búsqueda</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Extensiones</translation>
 <translation id="862727964348362408">En suspensión</translation>
 <translation id="862750493060684461">Caché de CSS</translation>
+<translation id="8627706565932943526">Error de sincronización</translation>
 <translation id="8627795981664801467">Conexiones seguras solamente</translation>
 <translation id="8630903300770275248">Importar usuario supervisado</translation>
 <translation id="8631032106121706562">Pétalos</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb
index 9bf16edc..fc376d6 100644
--- a/chrome/app/resources/generated_resources_et.xtb
+++ b/chrome/app/resources/generated_resources_et.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Sisestage turvavõtme PIN-kood</translation>
 <translation id="457386861538956877">Rohkem ...</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetoothi seadme sidumine</translation>
 <translation id="4579581181964204535">Hosti <ph name="HOST_NAME" /> ei saa üle kanda.</translation>
 <translation id="4581774856936278355">Viga Linuxi taastamisel</translation>
 <translation id="4582563038311694664">Lähtesta kõik seaded</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Üleskannimine</translation>
 <translation id="7978412674231730200">Privaatvõti</translation>
 <translation id="7978450511781612192">See logib teid teie Google'i kontodelt välja. Teie järjehoidjaid, ajalugu, paroole ja muud ei sünkroonita enam.</translation>
-<translation id="7979036127916589816">Sünkroonimise viga</translation>
 <translation id="7980084013673500153">Vara ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Eellaaditakse lehti kiiremaks sirvimiseks ja otsimiseks</translation>
 <translation id="798145602633458219">Lisa otsingukasti soovitus <ph name="SUGGESTION_NAME" /></translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Laiendused</translation>
 <translation id="862727964348362408">Peatatud</translation>
 <translation id="862750493060684461">CSS-i vahemälu</translation>
+<translation id="8627706565932943526">Sünkroonimisviga</translation>
 <translation id="8627795981664801467">Turvalised ühendused ainult</translation>
 <translation id="8630903300770275248">Impordi jälgitavad kasutajad</translation>
 <translation id="8631032106121706562">Kroonlehed</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb
index 3b536da..04ab84e 100644
--- a/chrome/app/resources/generated_resources_eu.xtb
+++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -351,6 +351,7 @@
 <translation id="1493892686965953381"><ph name="LOAD_STATE_PARAMETER" /> parametroaren zain…</translation>
 <translation id="1495486559005647033">Beste <ph name="NUM_PRINTERS" /> gailu erabilgarri.</translation>
 <translation id="1495677929897281669">Itzuli fitxara</translation>
+<translation id="1499271269825557605">Luzapenen bat ezagutzen ez baduzu edo arakatzaileak ez badu funtzionatzen behar bezala, desaktibatu edo pertsonalizatu luzapenak hemen.</translation>
 <translation id="1500297251995790841">Identifikatu ezin den gailua [<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />]</translation>
 <translation id="1503394326855300303">Saio anitzeko saioetan, jabeak hasi behar du kontua lehendabizi.</translation>
 <translation id="150411034776756821">Kendu <ph name="SITE" /></translation>
@@ -358,6 +359,7 @@
 <translation id="1507170440449692343">Orriari kamera atzitzeko aukera blokeatu zaio.</translation>
 <translation id="1507246803636407672">&amp;Baztertu</translation>
 <translation id="1508491105858779599">Gailua desblokeatzeko, jarri hatza hatz-marken sentsorean.</translation>
+<translation id="1508575541972276599">Uneko bertsioa Debian 9 (Stretch) da</translation>
 <translation id="1509281256533087115">Atzitu edozer <ph name="DEVICE_NAME_AND_VENDOR" /> USB bidez</translation>
 <translation id="150962533380566081">PUK kodeak ez du balio.</translation>
 <translation id="1510030919967934016">Orri honi zure kokapenaren jarraipena egiteko aukera blokeatu zaio.</translation>
@@ -433,6 +435,7 @@
 <translation id="1601560923496285236">Aplikatu</translation>
 <translation id="1603914832182249871">(Ezkutuko modua)</translation>
 <translation id="1604432177629086300">Ezin izan da inprimatu. Begiratu inprimagailua eta saiatu berriro.</translation>
+<translation id="1605544918554600534"><ph name="PROFILE_NAME" />: pasahitzen sinkronizazioa ez dabil</translation>
 <translation id="1607139524282324606">Garbitu sarrera</translation>
 <translation id="1608626060424371292">Kendu erabiltzailea</translation>
 <translation id="1608668830839595724">Ekintza gehiago hautatutako elementuetarako</translation>
@@ -559,6 +562,8 @@
 <translation id="177336675152937177">Aplikazio ostatatuen datuak</translation>
 <translation id="1776712937009046120">Gehitu erabiltzailea</translation>
 <translation id="1776883657531386793"><ph name="OID" />: <ph name="INFO" /></translation>
+<translation id="1777310661937894236"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> da gailuaren kudeatzailea.
+<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kontuan saioa hasteko, sakatu "Hurrengoa".</translation>
 <translation id="1779652936965200207">Idazti pasagako hau "<ph name="DEVICE_NAME" />" gailuan:</translation>
 <translation id="1780152987505130652">Itxi taldea</translation>
 <translation id="1781291988450150470">Uneko PINa</translation>
@@ -746,6 +751,7 @@
 <translation id="2048653237708779538">Ekintza ez dago erabilgarri</translation>
 <translation id="2050339315714019657">Bertikala</translation>
 <translation id="2053312383184521053">Jarduerarik gabeko egoeraren datuak</translation>
+<translation id="2055585478631012616">Webgune horietako saioa amaitu egingo da, baita irekita dauden fitxetakoa ere</translation>
 <translation id="205560151218727633">Google-ren Laguntzailea eginbidearen logotipoa</translation>
 <translation id="2058456167109518507">Hautemandako gailua</translation>
 <translation id="2059913712424898428">Ordu-zona</translation>
@@ -761,6 +767,7 @@
 <translation id="2079545284768500474">Desegin</translation>
 <translation id="2080070583977670716">Ezarpen gehiago</translation>
 <translation id="2087822576218954668">Inprimatu: <ph name="PRINT_NAME" /></translation>
+<translation id="2088690981887365033">VPN sarea</translation>
 <translation id="2089566709556890888">Arakatu sarea segurtasun osoz Google Chrome-rekin</translation>
 <translation id="2089795179672254991">Eskatu nire baimena webguneren batek arbelean kopiatzen ditudan testuak eta irudiak ikusi nahi dituenean (gomendatua)</translation>
 <translation id="2090165459409185032">Kontuko informazioa berreskuratzeko, joan hona: google.com/accounts/recovery</translation>
@@ -984,6 +991,7 @@
 <translation id="2379232090534544565">Audio- eta bideo-sarrera atzitzen ari da webgune bat</translation>
 <translation id="2379281330731083556">Inprimatu sistemaren leihoaren bidez… <ph name="SHORTCUT_KEY" /></translation>
 <translation id="2381756643783702095">Galdetu bidali aurretik (gomendatua)</translation>
+<translation id="2382818385048255866">Egiaztatu luzapenak</translation>
 <translation id="2384436799579181135">Errore bat gertatu da. Egiaztatu inprimagailuaren egoera eta saiatu berriro.</translation>
 <translation id="2387458720915042159">Proxy konexio mota</translation>
 <translation id="2391419135980381625">Letra-tipo estandarra</translation>
@@ -1035,6 +1043,7 @@
 <translation id="2462724976360937186">Ziurtagiri-emailearen gakoaren IDa</translation>
 <translation id="2462752602710430187">Gehitu da <ph name="PRINTER_NAME" /></translation>
 <translation id="2464089476039395325">HTTP proxya</translation>
+<translation id="2467267713099745100"><ph name="NETWORK_TYPE" /> sarea. Desaktibatuta.</translation>
 <translation id="2468205691404969808">Zure hobespenak gogoratzeko erabiltzen ditu cookieak, orri horietara joaten ez bazara ere</translation>
 <translation id="2468402215065996499">Tamagotchi</translation>
 <translation id="2469259292033957819">Ez daukazu inprimagailurik gordeta.</translation>
@@ -1289,6 +1298,7 @@
 <translation id="2800760947029405028">Kargatu irudi bat</translation>
 <translation id="2803375539583399270">Idatzi PIN kodea</translation>
 <translation id="2804043232879091219">Ezin izan da ireki beste arakatzaile bat</translation>
+<translation id="2804667941345577550">Webguneko saioa amaituko da, baita irekita dauden fitxetakoa ere</translation>
 <translation id="2804680522274557040">Kamera erabiltzeko baimena desaktibatuta dago</translation>
 <translation id="2805646850212350655">Fitxategiak enkriptatzeko Microsoft sistema (EFS)</translation>
 <translation id="2805756323405976993">Aplikazioak</translation>
@@ -1296,6 +1306,7 @@
 <translation id="2806891468525657116">Jada badago lasterbide hori</translation>
 <translation id="2807517655263062534">Deskargatutako fitxategiak agertuko dira hemen</translation>
 <translation id="2809586584051668049">eta beste <ph name="NUMBER_ADDITIONAL_DISABLED" /></translation>
+<translation id="2810390687497823527">Luzapenen bat ezagutzen ez baduzu edo arakatzaileak ez badu funtzionatzen behar bezala, desaktibatu edo pertsonalizatu luzapenak hemen.</translation>
 <translation id="2812049959647166806">Thunderbolt konektorea ez da bateragarria</translation>
 <translation id="2812944337881233323">Amaitu eta hasi berriro saioa.</translation>
 <translation id="2812989263793994277">Ez erakutsi irudirik</translation>
@@ -1335,6 +1346,7 @@
 <translation id="2861941300086904918">Bezero natiboaren segurtasun-kudeatzailea</translation>
 <translation id="2864601841139725659">Ezarri profileko argazkia</translation>
 <translation id="2865919525181940183">Pantailan dauden programen pantaila-argazkia</translation>
+<translation id="286674810810214575">Energia-iturriak egiaztatzen…</translation>
 <translation id="2867768963760577682">Ireki fitxa ainguratu gisa</translation>
 <translation id="2868746137289129307">Enpresaren gidalerroak zaharkituta eta desgaituta utzi du luzapena. Automatikoki gai liteke bertsio berria eskuragarri egotean.</translation>
 <translation id="2870560284913253234">Webgunea</translation>
@@ -1412,6 +1424,7 @@
 <translation id="2972581237482394796">&amp;Berregin</translation>
 <translation id="2973324205039581528">Desaktibatu webguneko audioa</translation>
 <translation id="2977480621796371840">Kendu taldetik</translation>
+<translation id="2979520980928493164">Chrome hobea eta bizkorragoa</translation>
 <translation id="2979639724566107830">Ireki beste leiho batean</translation>
 <translation id="2981113813906970160">Erakutsi saguaren erakusle handia</translation>
 <translation id="2982970937345031">Bidali anonimoki</translation>
@@ -1518,6 +1531,7 @@
 <translation id="3143515551205905069">Utzi sinkronizazioa bertan behera</translation>
 <translation id="3143754809889689516">Erreproduzitu hasieratik</translation>
 <translation id="3144647712221361880">Ireki esteka honela:</translation>
+<translation id="3145187901750964977">Ezin izan da instalatu makina birtuala. Saiatu berriro edo jarri harremanetan erakundeko gailuen administratzailearekin. Errore-kodea: <ph name="ERROR_CODE" />.</translation>
 <translation id="3149477159749171726">Bertsioa:
     <ph name="LINUX_VERSION" />
 
@@ -1556,6 +1570,7 @@
 <translation id="3192947282887913208">Audio-fitxategiak</translation>
 <translation id="3194737229810486521"><ph name="URL" /> webguneak datuak gorde nahi ditu gailuan modu iraunkorrean</translation>
 <translation id="3199127022143353223">Zerbitzariak</translation>
+<translation id="3201306578844503970">Ezin izan da instalatu makina birtuala sareko errore bat dela. Saiatu berriro edo jarri harremanetan erakundeko gailuen administratzailearekin. Errore-kodea: <ph name="ERROR_CODE" />.</translation>
 <translation id="3201422919974259695">Hemen agertuko dira erabilgarri dauden USB gailuak.</translation>
 <translation id="3202131003361292969">Bide-izena</translation>
 <translation id="3202173864863109533">Fitxaren audioa desaktibatuta dago.</translation>
@@ -2065,6 +2080,7 @@
 <translation id="389589731200570180">Partekatu gonbidatuekin</translation>
 <translation id="389901847090970821">Hautatu teklatua</translation>
 <translation id="3899879303189199559">Ez da konektatu duela urtebete baino gehiago</translation>
+<translation id="3900789207771372462">Zenbait luzapenek arakatze-jarduerak ikus ditzakete, informazio pertsonala barne.</translation>
 <translation id="3900966090527141178">Esportatu pasahitzak</translation>
 <translation id="3901991538546252627"><ph name="NAME" /> sarera konektatzen</translation>
 <translation id="3905761538810670789">Konpondu aplikazioa</translation>
@@ -2192,6 +2208,7 @@
 <translation id="407520071244661467">Eskala</translation>
 <translation id="4075639477629295004">Ezin da igorri <ph name="FILE_NAME" />.</translation>
 <translation id="4077917118009885966">Iragarkiak blokeatu egin dira webgune honetan</translation>
+<translation id="4077919383365622693">Garbitu egingo dira <ph name="SITE" /> webguneak gordetako datu eta cookie guztiak.</translation>
 <translation id="4079140982534148664">Erabili ortografia-zuzentzaile hobetua</translation>
 <translation id="4081242589061676262">Ezin da igorri fitxategia.</translation>
 <translation id="4084682180776658562">Laster-marka</translation>
@@ -2266,6 +2283,7 @@
 <translation id="4181841719683918333">Hizkuntzak</translation>
 <translation id="4184885522552335684">Arrastatu pantailak mugitzeko</translation>
 <translation id="4194570336751258953">Gaitu sakatuta klik egiteko aukera</translation>
+<translation id="4194595472342532425">Ezin izan da instalatu Plugin VM konfigurazio-arazo batengatik. Jarri harremanetan erakundeko gailuen administratzailearekin. Errore-kodea: <ph name="ERROR_CODE" />.</translation>
 <translation id="4195643157523330669">Ireki fitxa berri batean</translation>
 <translation id="4195814663415092787">Jarraitu utzi zenuen tokitik</translation>
 <translation id="4198146608511578238">Eduki sakatuta abiarazlearen ikonoa Google-ren Laguntzailea eginbidearekin hitz egiteko.</translation>
@@ -2489,6 +2507,7 @@
 <translation id="4549791035683739768">Segurtasun-giltzak ez dauka hatz-markarik gordeta</translation>
 <translation id="4551763574344810652">Sakatu <ph name="MODIFIER_KEY_DESCRIPTION" /> desegiteko</translation>
 <translation id="4552089082226364758">Flash</translation>
+<translation id="4552759165874948005"><ph name="NETWORK_TYPE" /> sarea. Seinalearen indarra: % <ph name="SIGNAL_STRENGTH" />.</translation>
 <translation id="4554591392113183336">Kanpoko luzapena lehendik dagoenaren bertsio berean edo zaharragoan dago.</translation>
 <translation id="4555769855065597957">Itzala</translation>
 <translation id="4555863373929230635">Pasahitzak Google-ko kontuan gordetzeko, hasi saioa eta aktibatu sinkronizazioa.</translation>
@@ -2510,7 +2529,6 @@
 <translation id="4572779512957829735">Idatzi segurtasun-giltzaren PINa</translation>
 <translation id="457386861538956877">Gehiago…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Parekatu Bluetooth bidezko gailua</translation>
 <translation id="4579581181964204535">Ezin da igorri <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Errore bat gertatu da Linux leheneratzean</translation>
 <translation id="4582563038311694664">Berrezarri ezarpen guztiak</translation>
@@ -2566,6 +2584,7 @@
 <translation id="4665446389743427678">Ezabatu egingo dira <ph name="SITE" /> webguneak gordetako datu guztiak.</translation>
 <translation id="4668721319092543482">Egin klik <ph name="PLUGIN_NAME" /> gaitzeko</translation>
 <translation id="4672657274720418656">Bihurtu orria</translation>
+<translation id="46733273239502219">Garbitu egingo dira instalatutako aplikazioetako konexiorik gabe erabiltzeko datu guztiak</translation>
 <translation id="4673442866648850031">Ireki arkatzaren tresnak arkatza kendu ondoren</translation>
 <translation id="4677585247300749148"><ph name="URL" /> webguneak erabilerraztasun-gertaerei erantzun nahi die</translation>
 <translation id="4677772697204437347">GPU memoria</translation>
@@ -2697,6 +2716,7 @@
 <translation id="4876273079589074638">Lagundu gure ingeniariei hutsegitea aztertzen eta konpontzen. Ahal baduzu, azaldu zer egin duzun urratsez urrats. Xehetasun txikienek ere garrantzitsuak dira!</translation>
 <translation id="4876895919560854374">Blokeatu eta desblokeatu pantaila</translation>
 <translation id="4877276003880815204">Aztertu elementuak</translation>
+<translation id="4878653975845355462">Administratzaileak desaktibatu egin ditu pertsonaliza daitezkeen atzeko planoak</translation>
 <translation id="4879491255372875719">Automatikoa (lehenetsia)</translation>
 <translation id="4880328057631981605">Sarbide-puntuaren izena</translation>
 <translation id="4880827082731008257">Bilatu historian</translation>
@@ -2752,6 +2772,7 @@
 <translation id="4943691134276646401">"<ph name="CHROME_EXTENSION_NAME" />" luzapenak serie-ataka batera konektatu nahi du</translation>
 <translation id="4944310289250773232"><ph name="SAML_DOMAIN" /> da autentifikazio-zerbitzuaren ostalaria</translation>
 <translation id="495170559598752135">Ekintzak</translation>
+<translation id="4952981627953231344">Ez da onartzen Plugin VM gailu honetan. Jarri harremanetan erakundeko gailuen administratzailearekin.</translation>
 <translation id="4953689047182316270">Erantzun erabilerraztasun-gertaerei</translation>
 <translation id="4953808748584563296">Abatar laranja lehenetsia</translation>
 <translation id="4955710816792587366">Aukeratu PIN kodea</translation>
@@ -3251,6 +3272,7 @@
 <translation id="5687326903064479980">Ordu-zona</translation>
 <translation id="5689516760719285838">Kokapena</translation>
 <translation id="56907980372820799">Estekatu datuak</translation>
+<translation id="5691180005790455277">Garbitu egingo dira <ph name="SITE_GROUP_NAME" /> webguneak eta haren barneko webguneek gordetako datu eta cookie guztiak.</translation>
 <translation id="5691511426247308406">Familia</translation>
 <translation id="5692183275898619210">Inprimatu da</translation>
 <translation id="5696143504434933566">Salatu "<ph name="EXTENSION_NAME" />" luzapenak erabilera okerra egin duela</translation>
@@ -3472,6 +3494,7 @@
 <translation id="6007240208646052708">Ahozko bilaketa ez dago eskuragarri zure hizkuntzan.</translation>
 <translation id="6009781704028455063">Sentsore integratua</translation>
 <translation id="6010869025736512584">Bideo-sarrera atzitzen</translation>
+<translation id="6011074160056912900">Ethernet sarea</translation>
 <translation id="6011193465932186973">Hatz-marka</translation>
 <translation id="6011449291337289699">Garbitu webgunearen datuak</translation>
 <translation id="6015266928248016057">PUK kodeak ez du balio. Geratzen diren saiakerak: <ph name="RETRIES" />.</translation>
@@ -3508,6 +3531,7 @@
 <translation id="6053401458108962351">&amp;Garbitu arakatze-datuak…</translation>
 <translation id="6055171183283175969">Idatzi duzun pasahitza ez da zuzena.</translation>
 <translation id="6055392876709372977">PKCS #1 SHA-256 RSA enkriptatzearekin</translation>
+<translation id="6055907707645252013"><ph name="NETWORK_TYPE" /> sarea. Konektatu gabe.</translation>
 <translation id="6056710589053485679">Kargatu berriro modu normalean</translation>
 <translation id="6057381398996433816">Webgune honi blokeatu egin zaio mugimenduaren eta argiaren sentsoreak erabiltzeko aukera.</translation>
 <translation id="6058567592298841668">Plugin bidezko makina birtuala: <ph name="PLUGIN_VM_NAME" /></translation>
@@ -3571,6 +3595,7 @@
 <translation id="6136114942382973861">Itxi deskargen barra</translation>
 <translation id="6137767437444130246">Erabiltzaile-ziurtagiria</translation>
 <translation id="6138680304137685902">SHA-384 ziurtagiria duen X9.62 ECDSA sinadura</translation>
+<translation id="6138894911715675297">Ez dago sarerik (<ph name="NETWORK_TYPE" />)</translation>
 <translation id="6141988275892716286">Berretsi deskarga</translation>
 <translation id="6143186082490678276">Lortu laguntza</translation>
 <translation id="6144938890088808325">Lagundu Chromebook-ak hobetzen</translation>
@@ -3877,6 +3902,7 @@
 <translation id="6602956230557165253">Erabili ezker eta eskuin geziak nabigatzeko.</translation>
 <translation id="6605847144724004692">Ezein erabiltzailek ez du baloratu oraindik.</translation>
 <translation id="6607831829715835317">&amp;Tresna gehiago</translation>
+<translation id="6611972847767394631">Bilatu fitxak hemen</translation>
 <translation id="6612358246767739896">Eduki babestua</translation>
 <translation id="6615455863669487791">Erakuts iezadazu</translation>
 <translation id="6618097958368085618">Gorde hala ere</translation>
@@ -3945,6 +3971,7 @@
 <translation id="6709133671862442373">Albisteak</translation>
 <translation id="6709357832553498500">Konektatu <ph name="EXTENSIONNAME" /> erabilita</translation>
 <translation id="6710213216561001401">Aurrekoa</translation>
+<translation id="6715803357256707211">Errore bat gertatu da Linux aplikazioa instalatzean. Xehetasunak ikusteko, sakatu jakinarazpena.</translation>
 <translation id="6721678857435001674">Ikusi segurtasun-giltzaren marka eta modeloa</translation>
 <translation id="6721972322305477112">&amp;Fitxategia</translation>
 <translation id="672213144943476270">Desblokea ezazu profila gonbidatu gisa arakatu ahal izateko.</translation>
@@ -3978,6 +4005,7 @@
 <translation id="6769712124046837540">Inprimagailua gehitzen…</translation>
 <translation id="6770664076092644100">Egiaztatu NFC bidez</translation>
 <translation id="6771503742377376720">Ziurtagiri-emailea da</translation>
+<translation id="6772339735733515807">Kudeatu luzapenak</translation>
 <translation id="6775163072363532304">Erabilgarri dauden gailuak hemen agertuko dira.</translation>
 <translation id="6777817260680419853">Blokeatu egin da birbideratzeko ekintza</translation>
 <translation id="6778737459546443941">Gurasoek ez dute onartu eskaera oraindik</translation>
@@ -4116,6 +4144,7 @@
 <translation id="6972180789171089114">Audioa/Bideoa</translation>
 <translation id="6972553992270299730"><ph name="ORIGIN" /> webguneak ezin ditu ireki karpeta honetako fitxategiak sistemaren fitxategiak daudelako karpetan.</translation>
 <translation id="6972754398087986839">Hasi erabiltzen</translation>
+<translation id="6973611239564315524">Debian 10 (Buster) berritzeko bertsio bat erabilgarri dago</translation>
 <translation id="6974609594866392343">Konexiorik gabeko demo modua</translation>
 <translation id="6977381486153291903">Firmwarearen berrikuspena</translation>
 <translation id="6978121630131642226">Bilatzaileak</translation>
@@ -4575,6 +4604,7 @@
 <translation id="7644543211198159466">Kolorea eta gaia</translation>
 <translation id="7645176681409127223"><ph name="USER_NAME" /> (jabea)</translation>
 <translation id="7645681574855902035">Linux-eko babeskopia bertan behera uzten</translation>
+<translation id="7646772052135772216">Pasahitzen sinkronizazioa ez dabil</translation>
 <translation id="7647403192093989392">Ez dago azkenaldiko jarduerarik</translation>
 <translation id="7648992873808071793">Gorde fitxategiak gailu honetan</translation>
 <translation id="7649070708921625228">Laguntza</translation>
@@ -4763,6 +4793,7 @@
 <translation id="7877451762676714207">Zerbitzariko errore ezezaguna. Saiatu berriro edo jarri harremanetan zerbitzariaren administratzailearekin.</translation>
 <translation id="7877680364634660272">Txangoa</translation>
 <translation id="7878562273885520351">Baliteke pasahitza arriskuan egotea</translation>
+<translation id="7879631849810108578">Ezarri da lasterbidea: <ph name="IDS_SHORT_SET_COMMAND" /></translation>
 <translation id="7880823633812189969">Gailuan dituzun datuak ezabatu egingo dira gailua berrabiarazten duzunean</translation>
 <translation id="7881483672146086348">Ikusi kontua</translation>
 <translation id="7882358943899516840">Hornitzaile mota</translation>
@@ -4837,7 +4868,6 @@
 <translation id="7974936243149753750">Bilatu gainetik</translation>
 <translation id="7978412674231730200">Gako pribatua</translation>
 <translation id="7978450511781612192">Zure Google-ko kontuen saioa amaituko da. Aurrerantzean, ez dira sinkronizatuko laster-markak, historia, pasahitzak eta beste.</translation>
-<translation id="7979036127916589816">Sinkronizazio-errorea</translation>
 <translation id="7980084013673500153">Erreproduzigai IDa: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Aurrekargatu orriak azkarrago arakatzeko eta bilatzeko</translation>
 <translation id="798145602633458219">Erantsi <ph name="SUGGESTION_NAME" /> iradokizuna bilaketa-koadroan</translation>
@@ -4849,6 +4879,7 @@
 <translation id="7987814697832569482">Konektatu beti VPN honen bidez</translation>
 <translation id="7988355189918024273">Gaitu erabilerraztasun-eginbideak</translation>
 <translation id="7991296728590311172">Erabilerraztasun-osagarriaren ezarpenak</translation>
+<translation id="7994350303002908848">Ezin izan da instalatu Plugin VM. Saiatu berriro edo jarri harremanetan erakundeko gailuen administratzailearekin. Errore-kodea: <ph name="ERROR_CODE" />.</translation>
 <translation id="7994702968232966508">EAP metodoa</translation>
 <translation id="7997826902155442747">Prozesuaren lehentasuna</translation>
 <translation id="7999229196265990314">Fitxategi hauek sortu dira:
@@ -5096,6 +5127,7 @@
 <translation id="8327039559959785305">Errore bat gertatu da Linux fitxategiak muntatzean. Saiatu berriro.</translation>
 <translation id="8335587457941836791">Desainguratu apaletik</translation>
 <translation id="8336407002559723354">Data honetan amaituko dira eguneratzeak: <ph name="MONTH_AND_YEAR" /></translation>
+<translation id="8336721153892716270">Berrabiarazi gailua sistemaren testua hizkuntza honetan erakusteko: <ph name="LANGUAGE" /></translation>
 <translation id="8336739000755212683">Aldatu gailuko kontuaren irudia</translation>
 <translation id="8337047789441383384">Dagoeneko erregistratu duzu segurtasun-giltza hau. Ez duzu berriro erregistratu behar.</translation>
 <translation id="8338952601723052325">Garatzaileen webgunea</translation>
@@ -5139,6 +5171,7 @@
 <translation id="8400146488506985033">Kudeatu jendea</translation>
 <translation id="8401432541486058167">Eman txartel adimendunarekin lotutako PIN kodea.</translation>
 <translation id="8405046151008197676">Irakurri azken eguneratzeari buruzko datu aipagarriak</translation>
+<translation id="8408068190360279472"><ph name="NETWORK_TYPE" /> sarea. Konektatzen.</translation>
 <translation id="8410775397654368139">Google Play</translation>
 <translation id="8413385045638830869">Galdetu lehenbizi (gomendatua)</translation>
 <translation id="8418445294933751433">&amp;Erakutsi fitxa gisa</translation>
@@ -5282,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Luzapenak</translation>
 <translation id="862727964348362408">Inaktibo</translation>
 <translation id="862750493060684461">CSS cachea</translation>
+<translation id="8627706565932943526">Sinkronizazio-errorea</translation>
 <translation id="8627795981664801467">Konexio seguruak soilik</translation>
 <translation id="8630903300770275248">Inportatu erabiltzaile gainbegiratua</translation>
 <translation id="8631032106121706562">Petaloak</translation>
@@ -5428,6 +5462,7 @@
 <translation id="8807632654848257479">Egonkorra</translation>
 <translation id="8808478386290700967">Web Store</translation>
 <translation id="8808686172382650546">Katua</translation>
+<translation id="8808744862003883508">Chrome-n instalatuta dauden luzapen guztiak ikus ditzakezu orri honetan.</translation>
 <translation id="8809147117840417135">Anil argia</translation>
 <translation id="8813698869395535039">Ezin da hasi saioa <ph name="USERNAME" /> kontuan</translation>
 <translation id="8813811964357448561">paper-orria</translation>
@@ -5693,6 +5728,7 @@
 <translation id="9188732951356337132">Bidali erabilera- eta diagnostiko-datuak. Gailu honek automatikoki bidaltzen dizkio Google-ri diagnostikoak eta gailu zein aplikazioen erabilerari buruzko datuak. Informazio hori ez da erabiliko haurra identifikatzeko eta, hari esker, sistemaren eta aplikazioen egonkortasuna hobetuko da, besteak beste. Gainera, multzokatutako datu batzuk oso baliagarriak izango dira Google-ren aplikazioak hobetzeko eta bazkideei laguntzeko (adibidez, Android-en garatzaileei). Haurraren kontuko Sareko eta aplikazioetako jarduera gehigarriak ezarpena aktibatuta badago, baliteke datu horiek haren Google-ko kontuan gordetzea. <ph name="BEGIN_LINK2" />Lortu informazio gehiago<ph name="END_LINK2" /></translation>
 <translation id="9190063653747922532">L2TP/IPsec + aurrez partekatutako gakoa</translation>
 <translation id="920045321358709304">Bilatu <ph name="SEARCH_ENGINE" /> zerbitzuaren bidez</translation>
+<translation id="9201023452444595544">Garbitu egingo dira konexiorik gabe erabiltzeko datu guztiak</translation>
 <translation id="9201220332032049474">Pantaila blokeatzeko aukerak</translation>
 <translation id="9203398526606335860">&amp;Profilen sorrera gaituta</translation>
 <translation id="9203904171912129171">Hautatu gailua</translation>
@@ -5705,6 +5741,7 @@
 <translation id="9220525904950070496">Kendu kontua</translation>
 <translation id="9220820413868316583">Jaso hatza eta saiatu berriro.</translation>
 <translation id="923467487918828349">Erakutsi guztiak</translation>
+<translation id="929117907539171075">Garbitu egingo dira instalatutako aplikazioko konexiorik gabe erabiltzeko datu guztiak</translation>
 <translation id="930268624053534560">Denbora-zigilu xehatua</translation>
 <translation id="932327136139879170">Hasiera</translation>
 <translation id="932508678520956232">Ezin izan da hasi inprimatzen.</translation>
@@ -5730,6 +5767,7 @@
 <translation id="960719561871045870">Operadorearen kodea</translation>
 <translation id="960987915827980018">Gutxi gorabehera, ordubete falta da</translation>
 <translation id="962802172452141067">Laster-marken karpetaren zuhaitza</translation>
+<translation id="964057662886721376">Zenbait luzapenek erabilera motel dezakete, batez ere, berariaz instalatu ez dituzunek.</translation>
 <translation id="964286338916298286">IT administratzaileak desgaitu egin ditu zure gailurako osagarriak.</translation>
 <translation id="964439421054175458">{NUM_APLLICATIONS,plural, =1{Aplikazioa}other{Aplikazioak}}</translation>
 <translation id="965211523698323809">Bidali eta jaso testu-mezuak <ph name="DEVICE_TYPE" /> gailua erabilita. <ph name="LINK_BEGIN" />Lortu informazio gehiago<ph name="LINK_END" /></translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index a7a23df..eff4f3d 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">پین را برای کلید امنیتی وارد کنید</translation>
 <translation id="457386861538956877">بیشتر...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">مرتبط‌سازی دستگاه بلوتوث</translation>
 <translation id="4579581181964204535">ارسال محتوای <ph name="HOST_NAME" /> امکان‌پذیر نیست.</translation>
 <translation id="4581774856936278355">‏خطا هنگام بازیابی Linux</translation>
 <translation id="4582563038311694664">بازنشانی همه تنظیمات</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">تصویر بزرگ‌تر از صفحه</translation>
 <translation id="7978412674231730200">کلید خصوصی</translation>
 <translation id="7978450511781612192">‏با این کار از سیستم حساب Google خود خارج می‌شوید. نشانک‌ها، سابقه، گذرواژه‌ها و سایر موارد دیگر همگام‌سازی نمی‌شوند.</translation>
-<translation id="7979036127916589816">خطای همگام‌سازی</translation>
 <translation id="7980084013673500153">شناسه دارایی: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">پیش‌بارگیری صفحه‌ها برای مرور و جستجوی سریع‌تر</translation>
 <translation id="798145602633458219">افزودن پیشنهاد <ph name="SUGGESTION_NAME" /> به کادر جستجو</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">&amp;برنامه های افزودنی</translation>
 <translation id="862727964348362408">معلق شد</translation>
 <translation id="862750493060684461">‏حافظهٔ پنهان CSS</translation>
+<translation id="8627706565932943526">خطای همگام‌سازی</translation>
 <translation id="8627795981664801467">فقط اتصالات ایمن</translation>
 <translation id="8630903300770275248">وارد کردن کاربر نظارت شده</translation>
 <translation id="8631032106121706562">گل</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb
index 3099c39..b9d47ad 100644
--- a/chrome/app/resources/generated_resources_fi.xtb
+++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Anna suojausavaimen PIN-koodi</translation>
 <translation id="457386861538956877">Lisää...</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Parin muodostus Bluetooth-laitteen kanssa</translation>
 <translation id="4579581181964204535">Osoitteen <ph name="HOST_NAME" /> suoratoisto ei onnistu.</translation>
 <translation id="4581774856936278355">Virhe palautettaessa Linuxia</translation>
 <translation id="4582563038311694664">Palauta kaikki asetukset</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">Yliskannaus</translation>
 <translation id="7978412674231730200">Yksityinen avain</translation>
 <translation id="7978450511781612192">Tämä kirjaa sinut ulos Google-tileiltäsi. Kirjanmerkkejä, historiaa, salasanoja tai muita ei enää synkronoida.</translation>
-<translation id="7979036127916589816">Synkronointivirhe</translation>
 <translation id="7980084013673500153">Sisältötunnus: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Esilataa sivuja nopeuttaaksesi lataamista ja hakemista</translation>
 <translation id="798145602633458219">Lisää ehdotus <ph name="SUGGESTION_NAME" /> hakukenttään</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">Laaj&amp;ennukset</translation>
 <translation id="862727964348362408">Pysäytetty</translation>
 <translation id="862750493060684461">CSS-välimuisti</translation>
+<translation id="8627706565932943526">Synkronointivirhe</translation>
 <translation id="8627795981664801467">Vain suojatut yhteydet</translation>
 <translation id="8630903300770275248">Tuo valvottu käyttäjä</translation>
 <translation id="8631032106121706562">Kukka</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index 23526c4..f141b96 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Ilagay ang PIN para sa iyong security key</translation>
 <translation id="457386861538956877">Higit pa...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Magpares ng Bluetooth device</translation>
 <translation id="4579581181964204535">Hindi ma-cast ang <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Error habang nire-restore ang Linux</translation>
 <translation id="4582563038311694664">I-reset lahat ng setting</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Private na key</translation>
 <translation id="7978450511781612192">Dahil dito, masa-sign out ka sa iyong mga Google Account. Hindi na masi-sync ang iyong mga bookmark, history, mga password, at higit pa.</translation>
-<translation id="7979036127916589816">Error sa Pag-sync</translation>
 <translation id="7980084013673500153">Asset ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">I-preload ang mga page para sa mas mabilis na pag-browse at paghahanap</translation>
 <translation id="798145602633458219">Idagdag ang suhestyong <ph name="SUGGESTION_NAME" /> sa box para sa paghahanap</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;Mga Extension</translation>
 <translation id="862727964348362408">Sinuspinde</translation>
 <translation id="862750493060684461">CSS cache</translation>
+<translation id="8627706565932943526">Error sa pag-sync</translation>
 <translation id="8627795981664801467">Secure na mga koneksyon lamang</translation>
 <translation id="8630903300770275248">Mag-import ng pinangangasiwaang user</translation>
 <translation id="8631032106121706562">Bulaklak</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb
index a346398..124befb3 100644
--- a/chrome/app/resources/generated_resources_fr-CA.xtb
+++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -2530,7 +2530,6 @@
 <translation id="4572779512957829735">Entrez le NIP de votre clé de sécurité</translation>
 <translation id="457386861538956877">Autres...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Associer un appareil Bluetooth</translation>
 <translation id="4579581181964204535">Impossible de diffuser <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Une erreur s'est produite lors de la restauration du conteneur Linux</translation>
 <translation id="4582563038311694664">Réinitialiser tous les paramètres</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Surbalayage</translation>
 <translation id="7978412674231730200">Clé privée</translation>
 <translation id="7978450511781612192">Cela vous déconnectera de vos comptes Google. Vos favoris, votre historique, vos mots de passe et autres ne seront plus synchronisés.</translation>
-<translation id="7979036127916589816">Erreur de synchronisation</translation>
 <translation id="7980084013673500153">Identifiant de ressource : <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Précharger les pages pour une navigation et une recherche plus rapides</translation>
 <translation id="798145602633458219">Ajouter la suggestion <ph name="SUGGESTION_NAME" /> au champ de recherche</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Extensions</translation>
 <translation id="862727964348362408">Suspendu</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Erreur de synchronisation</translation>
 <translation id="8627795981664801467">Connexions sécurisées seulement</translation>
 <translation id="8630903300770275248">Importer un utilisateur supervisé</translation>
 <translation id="8631032106121706562">Pétale</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index 7a006a4..b05f0f56 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -751,7 +751,7 @@
 <translation id="2048653237708779538">Action non disponible</translation>
 <translation id="2050339315714019657">Portrait</translation>
 <translation id="2053312383184521053">Données sur l'état de veille</translation>
-<translation id="2055585478631012616">Vous allez être déconnecté de ces sites, onglets ouverts inclus</translation>
+<translation id="2055585478631012616">Vous allez être déconnecté de ce site, y compris dans les onglets ouverts</translation>
 <translation id="205560151218727633">Logo de l'Assistant Google</translation>
 <translation id="2058456167109518507">Appareil détecté</translation>
 <translation id="2059913712424898428">Fuseau horaire</translation>
@@ -1043,7 +1043,7 @@
 <translation id="2462724976360937186">ID de clé de l'autorité de certification</translation>
 <translation id="2462752602710430187">L'imprimante <ph name="PRINTER_NAME" /> a bien été ajoutée.</translation>
 <translation id="2464089476039395325">Proxy HTTP</translation>
-<translation id="2467267713099745100">Réseau <ph name="NETWORK_TYPE" /> désactivé</translation>
+<translation id="2467267713099745100">Réseau <ph name="NETWORK_TYPE" />, désactivé</translation>
 <translation id="2468205691404969808">Utilise des cookies pour mémoriser vos préférences, même si vous n'accédez pas à ces pages</translation>
 <translation id="2468402215065996499">Tamagotchi</translation>
 <translation id="2469259292033957819">Vous n'avez aucune imprimante enregistrée.</translation>
@@ -1298,7 +1298,7 @@
 <translation id="2800760947029405028">Importer une image</translation>
 <translation id="2803375539583399270">Saisir le code</translation>
 <translation id="2804043232879091219">Impossible d'ouvrir le navigateur secondaire</translation>
-<translation id="2804667941345577550">Vous allez être déconnecté de ce site, onglets ouverts inclus</translation>
+<translation id="2804667941345577550">Vous allez être déconnecté de ce site, y compris dans les onglets ouverts</translation>
 <translation id="2804680522274557040">Caméra désactivée</translation>
 <translation id="2805646850212350655">Système de fichiers de chiffrement Microsoft </translation>
 <translation id="2805756323405976993">Applications</translation>
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Saisissez le code associé à votre clé de sécurité</translation>
 <translation id="457386861538956877">Autres...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Associer un appareil Bluetooth</translation>
 <translation id="4579581181964204535">Impossible de caster <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Erreur lors de la restauration de Linux</translation>
 <translation id="4582563038311694664">Réinitialiser tous les paramètres</translation>
@@ -3597,7 +3596,7 @@
 <translation id="6136114942382973861">Fermer la barre de téléchargements</translation>
 <translation id="6137767437444130246">Certificat utilisateur</translation>
 <translation id="6138680304137685902">Signature X9.62 ECDSA avec SHA-384</translation>
-<translation id="6138894911715675297"><ph name="NETWORK_TYPE" />, aucun réseau détecté</translation>
+<translation id="6138894911715675297"><ph name="NETWORK_TYPE" />, aucun réseau disponible</translation>
 <translation id="6141988275892716286">Confirmer le téléchargement</translation>
 <translation id="6143186082490678276">Aide</translation>
 <translation id="6144938890088808325">Aidez-nous à améliorer les Chromebooks</translation>
@@ -4795,7 +4794,7 @@
 <translation id="7877451762676714207">Erreur serveur inconnue. Veuillez réessayer ou contacter l'administrateur du serveur.</translation>
 <translation id="7877680364634660272">Visite</translation>
 <translation id="7878562273885520351">Votre mot de passe a peut-être été piraté</translation>
-<translation id="7879631849810108578">Raccourci activé : <ph name="IDS_SHORT_SET_COMMAND" /></translation>
+<translation id="7879631849810108578">Raccourci défini : <ph name="IDS_SHORT_SET_COMMAND" /></translation>
 <translation id="7880823633812189969">Les données locales seront supprimées lorsque vous redémarrerez l'appareil</translation>
 <translation id="7881483672146086348">Afficher le compte</translation>
 <translation id="7882358943899516840">Type de fournisseur</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Surbalayage</translation>
 <translation id="7978412674231730200">Clé privée</translation>
 <translation id="7978450511781612192">Vous serez déconnecté de vos comptes Google. Vos favoris, votre historique et vos mots de passe ne seront plus synchronisés.</translation>
-<translation id="7979036127916589816">Erreur de synchronisation</translation>
 <translation id="7980084013673500153">ID d'élément : <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Précharger les pages pour accélérer la navigation et la recherche</translation>
 <translation id="798145602633458219">Ajouter la suggestion <ph name="SUGGESTION_NAME" /> au champ de recherche</translation>
@@ -5175,7 +5173,7 @@
 <translation id="8400146488506985033">Gérer les utilisateurs</translation>
 <translation id="8401432541486058167">Utilisez le code associé à votre carte à puce.</translation>
 <translation id="8405046151008197676">Découvrez les nouveautés de la dernière mise à jour</translation>
-<translation id="8408068190360279472"><ph name="NETWORK_TYPE" /> : connexion…</translation>
+<translation id="8408068190360279472">Réseau <ph name="NETWORK_TYPE" /> : connexion…</translation>
 <translation id="8410775397654368139">Google Play</translation>
 <translation id="8413385045638830869">Demander d'abord (recommandé)</translation>
 <translation id="8418445294933751433">Afficher dan&amp;s un onglet</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;Extensions</translation>
 <translation id="862727964348362408">Suspendu</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Erreur de synchronisation.</translation>
 <translation id="8627795981664801467">Uniquement les connexions sécurisées</translation>
 <translation id="8630903300770275248">Importer un utilisateur supervisé</translation>
 <translation id="8631032106121706562">Fleur</translation>
@@ -5465,7 +5464,7 @@
 <translation id="8807632654848257479">Stable</translation>
 <translation id="8808478386290700967">Web Store</translation>
 <translation id="8808686172382650546">Chat</translation>
-<translation id="8808744862003883508">Sur cette page, vous pouvez consulter toutes les extensions installées sur Chrome.</translation>
+<translation id="8808744862003883508">Sur cette page, vous pouvez consulter toutes les extensions installées dans Chrome.</translation>
 <translation id="8809147117840417135">Turquoise clair</translation>
 <translation id="8813698869395535039">Impossible de se connecter au compte <ph name="USERNAME" /></translation>
 <translation id="8813811964357448561">feuille de papier</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb
index 01a2b93f..676a7ff5 100644
--- a/chrome/app/resources/generated_resources_gl.xtb
+++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Introduce o PIN da túa chave de seguranza</translation>
 <translation id="457386861538956877">Máis...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Sincronizar dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">Non se puido emitir <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Produciuse un erro ao restaurar Linux</translation>
 <translation id="4582563038311694664">Restablecer toda a configuración</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Sobrevarrido</translation>
 <translation id="7978412674231730200">Clave privada</translation>
 <translation id="7978450511781612192">Desta forma pecharase sesión nas túas Contas de Google. Deixarán de sincronizarse os marcadores, o historial, os contrasinais e outros datos.</translation>
-<translation id="7979036127916589816">Erro de sincronización</translation>
 <translation id="7980084013673500153">Código de identificación do recurso: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Cargar previamente as páxinas para que a navegación e as buscas sexan máis rápidas</translation>
 <translation id="798145602633458219">Anexar a suxestión "<ph name="SUGGESTION_NAME" />" á caixa de busca</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;Extensións</translation>
 <translation id="862727964348362408">Suspendido</translation>
 <translation id="862750493060684461">Caché de CSS</translation>
+<translation id="8627706565932943526">Erro de sincronización</translation>
 <translation id="8627795981664801467">Só conexións seguras</translation>
 <translation id="8630903300770275248">Importar usuario supervisado</translation>
 <translation id="8631032106121706562">Pétalos</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index 6d50690d..41ddf43 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -2525,7 +2525,6 @@
 <translation id="4572779512957829735">તમારા સુરક્ષા કોડ માટે પિન દાખલ કરો</translation>
 <translation id="457386861538956877">વધુ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth ડિવાઇસની જોડી કરો</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> કાસ્ટ કરવામાં અસમર્થ.</translation>
 <translation id="4581774856936278355">Linuxની પુનઃસ્થાપના કરતી વખતે ભૂલ આવી</translation>
 <translation id="4582563038311694664">તમામ સેટિંગ્સને ફરીથી સેટ કરો</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">ઓવરસ્કૅન</translation>
 <translation id="7978412674231730200">ખાનગી કી</translation>
 <translation id="7978450511781612192">આનાથી તમે તમારા Google એકાઉન્ટમાંથી સાઇન આઉટ થઈ જશો. ત્યાર પછી તમારાં બુકમાર્ક, ઇતિહાસ, પાસવર્ડ અને ઘણું બધું સિંક કરવામાં નહીં આવે.</translation>
-<translation id="7979036127916589816">સમન્વય ભૂલ</translation>
 <translation id="7980084013673500153">સંપત્તિ ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ઝડપી બ્રાઉઝિંગ અને શોધ માટે પેજને પહેલેથી લોડ કરો</translation>
 <translation id="798145602633458219">શોધ બૉક્સમાં સૂચન <ph name="SUGGESTION_NAME" /> જોડો</translation>
@@ -5310,6 +5308,7 @@
 <translation id="862542460444371744">&amp;એક્સ્ટેન્શન્સ</translation>
 <translation id="862727964348362408">સસ્પેન્ડેડ</translation>
 <translation id="862750493060684461">CSS કૅશ મેમરી</translation>
+<translation id="8627706565932943526">સમન્વય ભૂલ</translation>
 <translation id="8627795981664801467">ફક્ત સુરક્ષિત કનેક્શન્સ</translation>
 <translation id="8630903300770275248">નિરીક્ષિત વપરાશકર્તા આયાત કરો</translation>
 <translation id="8631032106121706562">પેટલ્સ</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index bd6ddc82..4f3c15c1 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -1533,7 +1533,7 @@
 <translation id="3154429428035006212">एक माह से ज़्यादा समय से ऑफ़लाइन</translation>
 <translation id="3154736273843608862"><ph name="IDS_SHORT_PRODUCT_NAME" /> पर आपके अभिभावक ने जो सीमा तय की थी वह खत्म हो गई.</translation>
 <translation id="3156531245809797194">Chrome का इस्तेमाल करने के लिए, कृपया साइन इन करें</translation>
-<translation id="3157931365184549694">पुनर्स्थापित करें</translation>
+<translation id="3157931365184549694">वापस लाएं</translation>
 <translation id="3158033540161634471">अपना फ़िंगरप्रिंट सेट अप करें</translation>
 <translation id="3159493096109238499">मटमैला</translation>
 <translation id="3160842278951476457"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (हार्डवेयर समर्थित)</translation>
@@ -2509,7 +2509,6 @@
 <translation id="4572779512957829735">अपनी 'सुरक्षा कुंजी' का पिन डालें</translation>
 <translation id="457386861538956877">ज़्यादा...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ब्लूटूथ डिवाइस युग्मित करें</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> को कास्ट करने में असमर्थ.</translation>
 <translation id="4581774856936278355">Linux को बहाल करते समय गड़बड़ी हुई</translation>
 <translation id="4582563038311694664">सभी सेटिंग रीसेट करें</translation>
@@ -4835,7 +4834,6 @@
 <translation id="7974936243149753750">ओवरस्कैन</translation>
 <translation id="7978412674231730200">निजी कुंजी</translation>
 <translation id="7978450511781612192">इससे आप अपने Google खातों से साइन आउट हो जाएंगे. आपके बुकमार्क, इतिहास, पासवर्ड और कई चीज़ें अब सिंक नहीं की जाएंगी.</translation>
-<translation id="7979036127916589816">समन्वयन गड़बड़ी</translation>
 <translation id="7980084013673500153">एसेट आईडी: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ज़्यादा तेज़ी से ब्राउज़ करने और खोजने के लिए पेज पहले से लोड करें</translation>
 <translation id="798145602633458219">सर्च बॉक्स में <ph name="SUGGESTION_NAME" /> सुझाव जोड़ें</translation>
@@ -5108,7 +5106,7 @@
 <translation id="8352772353338965963">एक से ज़्यादा साइन-इन के लिए कोई खाता जोड़ें. सभी साइन इन किए गए खातों को पासवर्ड के बिना एक्सेस किया जा सकता है, इसलिए इस सुविधा का इस्तेमाल सिर्फ़ विश्वसनीय खातों के साथ किया जाना चाहिए.</translation>
 <translation id="8353683614194668312">यह निम्न कर सकता है:</translation>
 <translation id="8356197132883132838"><ph name="TITLE" /> - <ph name="COUNT" /></translation>
-<translation id="8358685469073206162">पृष्ठों को पुनर्स्थापित करें?</translation>
+<translation id="8358685469073206162">सभी पेज वापस लाएं?</translation>
 <translation id="8358912028636606457">टैब ऑडियो कास्ट करने की सुविधा इस डिवाइस पर काम नहीं करती.</translation>
 <translation id="8363095875018065315">स्‍थिर</translation>
 <translation id="8363142353806532503">माइक्रोफ़ोन ब्लॉक किया गया है</translation>
@@ -5281,6 +5279,7 @@
 <translation id="862542460444371744">&amp;एक्‍सटेंशन</translation>
 <translation id="862727964348362408">निलंबित</translation>
 <translation id="862750493060684461">CSS कैश मेमोरी</translation>
+<translation id="8627706565932943526">समन्वयन गड़बड़ी</translation>
 <translation id="8627795981664801467">केवल सुरक्षित कनेक्शन</translation>
 <translation id="8630903300770275248">'निगरानी में रखे गए उपयोगकर्ता' को यहां लेकर आएं</translation>
 <translation id="8631032106121706562">पेटल्स</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index e202a8b2..0afedde 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Unesite PIN za sigurnosni ključ</translation>
 <translation id="457386861538956877">Više...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Uparivanje Bluetooth uređaja</translation>
 <translation id="4579581181964204535">Ne može se emitirati <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Došlo je do pogreške prilikom vraćanja Linuxa</translation>
 <translation id="4582563038311694664">Vraćanje svih postavki na zadano</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Rubno područje zaslona</translation>
 <translation id="7978412674231730200">Osobni ključ</translation>
 <translation id="7978450511781612192">Time ćete se odjaviti s Google računa. Vaše se oznake, povijest, zaporke i druge postavke više neće sinkronizirati.</translation>
-<translation id="7979036127916589816">Sinkronizacijska pogreška</translation>
 <translation id="7980084013673500153">ID uređaja: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Prethodno učitaj stranice za brže pregledavanje i pretraživanje</translation>
 <translation id="798145602633458219">Dodaj prijedlog <ph name="SUGGESTION_NAME" /> u okvir za pretraživanje</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Proširenja</translation>
 <translation id="862727964348362408">Obustavljeno</translation>
 <translation id="862750493060684461">CSS predmemorija</translation>
+<translation id="8627706565932943526">Pogreška sinkronizacije</translation>
 <translation id="8627795981664801467">Samo sigurne veze</translation>
 <translation id="8630903300770275248">Uvezi zaštićenog korisnika</translation>
 <translation id="8631032106121706562">Latica</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb
index f0b47d3..b2c8e226 100644
--- a/chrome/app/resources/generated_resources_hu.xtb
+++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Adja meg a biztonsági hardverkulcs PIN-kódját</translation>
 <translation id="457386861538956877">Továbbiak...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth-eszköz párosítása</translation>
 <translation id="4579581181964204535">Nem lehet átküldeni a következőt: <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Hiba történt a Linux visszaállítása során</translation>
 <translation id="4582563038311694664">Összes beállítás visszaállítása</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Túlpásztázás</translation>
 <translation id="7978412674231730200">Privát kulcs</translation>
 <translation id="7978450511781612192">Ezzel kijelentkezik Google-fiókjaiból. Könyvjelzőinek, előzményeinek, jelszavainak és egyéb adatainak szinkronizálása megszűnik.</translation>
-<translation id="7979036127916589816">Szinkronizálási hiba</translation>
 <translation id="7980084013673500153">Tartalomazonosító: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Oldalak előtöltése a gyorsabb böngészés és keresés érdekében</translation>
 <translation id="798145602633458219">A következő javaslat hozzáadása a keresőmezőhöz: <ph name="SUGGESTION_NAME" /></translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">Bővítménye&amp;k</translation>
 <translation id="862727964348362408">Felfüggesztett</translation>
 <translation id="862750493060684461">CSS gyorsítótár</translation>
+<translation id="8627706565932943526">Szinkronizálási hiba</translation>
 <translation id="8627795981664801467">Csak biztonságos kapcsolaton keresztül</translation>
 <translation id="8630903300770275248">Felügyelt felhasználó importálása</translation>
 <translation id="8631032106121706562">Virág</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb
index 6c6f102..f5eda988 100644
--- a/chrome/app/resources/generated_resources_hy.xtb
+++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -2530,7 +2530,6 @@
 <translation id="4572779512957829735">Մուտքագրեք անվտանգության բանալու PIN կոդը</translation>
 <translation id="457386861538956877">Ավելին…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth սարքի զուգակցում</translation>
 <translation id="4579581181964204535">Չհաջողվեց հեռարձակել <ph name="HOST_NAME" /> տիրույթը:</translation>
 <translation id="4581774856936278355">Չհաջողվեց վերականգնել Լինուքսը սխալի պատճառով</translation>
 <translation id="4582563038311694664">Վերակայել բոլոր կարգավորումները</translation>
@@ -4872,7 +4871,6 @@
 <translation id="7974936243149753750">էկրանի շրջանակ</translation>
 <translation id="7978412674231730200">Մասնավոր բանալի</translation>
 <translation id="7978450511781612192">Դուք դուրս կգաք Google հաշվից: Ձեր էջանիշները, այցելությունների պատմությունը, գաղտնաբառերը և մյուս կարգավորումներն այլևս չեն համաժամացվի:</translation>
-<translation id="7979036127916589816">Համաժամացման սխալ</translation>
 <translation id="7980084013673500153">Օբյեկտի ID-ն՝ <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Նախաբեռնել էջերը ավելի արագ դիտարկման և որոնման համար</translation>
 <translation id="798145602633458219">Ավելացնել «<ph name="SUGGESTION_NAME" />» առաջարկը որոնման դաշտում</translation>
@@ -5320,6 +5318,7 @@
 <translation id="862542460444371744">&amp;Ընդլայնումներ</translation>
 <translation id="862727964348362408">Ընդհատված է</translation>
 <translation id="862750493060684461">CSS-ի քեշ</translation>
+<translation id="8627706565932943526">Համաժամացման սխալ</translation>
 <translation id="8627795981664801467">Միայն ապահով կապակցումները</translation>
 <translation id="8630903300770275248">Ներմուծել վերահսկվող պրոֆիլը</translation>
 <translation id="8631032106121706562">Ծաղիկ</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index 0b786880..75fd751 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">Masukkan PIN untuk kunci keamanan Anda</translation>
 <translation id="457386861538956877">Lainnya...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Sandingkan perangkat Bluetooth</translation>
 <translation id="4579581181964204535">Tidak dapat mentransmisi <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Terjadi error saat memulihkan Linux</translation>
 <translation id="4582563038311694664">Setel ulang semua setelan</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">Pemindaian berlebih</translation>
 <translation id="7978412674231730200">Kunci pribadi</translation>
 <translation id="7978450511781612192">Tindakan ini akan membuat Anda logout dari Akun Google. Bookmark, histori, sandi, dan lainnya tidak akan disinkronkan lagi.</translation>
-<translation id="7979036127916589816">Kesalahan Sinkronisasi</translation>
 <translation id="7980084013673500153">ID Aset: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pramuat halaman agar browsing dan menelusuri lebih cepat</translation>
 <translation id="798145602633458219">Tambahkan saran <ph name="SUGGESTION_NAME" /> ke kotak penelusuran</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;Ekstensi</translation>
 <translation id="862727964348362408">Ditangguhkan</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Kesalahan sinkronisasi</translation>
 <translation id="8627795981664801467">Hanya sambungan aman</translation>
 <translation id="8630903300770275248">Impor pengguna yang dilindungi</translation>
 <translation id="8631032106121706562">Puspa</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb
index 3a4bf4c34..02c4debc 100644
--- a/chrome/app/resources/generated_resources_is.xtb
+++ b/chrome/app/resources/generated_resources_is.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Sláðu inn PIN-númer fyrir öryggislykilinn</translation>
 <translation id="457386861538956877">Meira...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Para Bluetooth-tæki</translation>
 <translation id="4579581181964204535">Ekki var hægt að senda <ph name="HOST_NAME" /> út.</translation>
 <translation id="4581774856936278355">Villa við endurheimt á Linux</translation>
 <translation id="4582563038311694664">Núllstilla allt</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Klipptur rammi</translation>
 <translation id="7978412674231730200">Einkalykill</translation>
 <translation id="7978450511781612192">Þetta skráir þig út af Google reikningnum þínum. Bókamerki, ferill, aðgangsorð og fleira verður ekki lengur samstillt.</translation>
-<translation id="7979036127916589816">Samstillingarvilla</translation>
 <translation id="7980084013673500153">Auðkenni eignar: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Forhlaða síðum til að geta leitað hraðar á netinu</translation>
 <translation id="798145602633458219">Hengja tillöguna <ph name="SUGGESTION_NAME" /> við leitarreit</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">Viðbætur</translation>
 <translation id="862727964348362408">Í bið</translation>
 <translation id="862750493060684461">CSS-skyndiminni</translation>
+<translation id="8627706565932943526">Samstillingarvilla</translation>
 <translation id="8627795981664801467">Aðeins öruggar tengingar</translation>
 <translation id="8630903300770275248">Flytja inn stýrðan notanda</translation>
 <translation id="8631032106121706562">Baldursbrá</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index 86af019..444095d 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -2452,7 +2452,7 @@
 <translation id="4469477701382819144">Bloccati sui siti che mostrano annunci invasivi o fuorvianti</translation>
 <translation id="4469762931504673593"><ph name="ORIGIN" /> può modificare i file nella cartella <ph name="FOLDERNAME" /></translation>
 <translation id="4470957202018033307">Preferenze dello spazio di archiviazione esterno</translation>
-<translation id="447252321002412580">Contribuisci a migliorare le funzioni e le prestazioni di Chrome</translation>
+<translation id="447252321002412580">Contribuisci a migliorare le funzionalità e le prestazioni di Chrome</translation>
 <translation id="4474155171896946103">Aggiungi tutte le schede ai Preferiti...</translation>
 <translation id="4474461121892222090">Potrebbero essere necessari fino a 15 minuti per completare l'attivazione dei dati mobili.</translation>
 <translation id="4475552974751346499">Cerca tra i file scaricati</translation>
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Inserisci il codice PIN per il token di sicurezza</translation>
 <translation id="457386861538956877">Altro...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Accoppia dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">Impossibile trasmettere <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Errore durante il ripristino di Linux</translation>
 <translation id="4582563038311694664">Ripristina tutte le impostazioni</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Chiave privata</translation>
 <translation id="7978450511781612192">I tuoi Account Google verranno scollegati e verrà interrotta la sincronizzazione di preferiti, cronologia, password e altro.</translation>
-<translation id="7979036127916589816">Errore di sincronizzazione</translation>
 <translation id="7980084013673500153">ID asset: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Le pagine vengono precaricate per velocizzare la navigazione e la ricerca</translation>
 <translation id="798145602633458219">Aggiungi il suggerimento <ph name="SUGGESTION_NAME" /> alla casella di ricerca</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;Estensioni</translation>
 <translation id="862727964348362408">Sospeso</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Errore di sincronizzazione</translation>
 <translation id="8627795981664801467">Solo connessioni protette</translation>
 <translation id="8630903300770275248">Importa utente controllato</translation>
 <translation id="8631032106121706562">Petalo</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index 36961955..b2f0255d 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">יש להזין את קוד האימות של מפתח האבטחה</translation>
 <translation id="457386861538956877">עוד...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">‏התאמת מכשיר Bluetooth</translation>
 <translation id="4579581181964204535">לא ניתן להעביר את <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">‏שגיאה בזמן השחזור של Linux</translation>
 <translation id="4582563038311694664">אפס את כל ההגדרות</translation>
@@ -4865,7 +4864,6 @@
 <translation id="7974936243149753750">סריקת יתר</translation>
 <translation id="7978412674231730200">מפתח פרטי</translation>
 <translation id="7978450511781612192">‏הפעולה הזאת תוציא אותך מחשבונות Google שלך. הסימניות, ההיסטוריה, הסיסמאות ופרטים אחרים יפסיקו לעבור סנכרון.</translation>
-<translation id="7979036127916589816">שגיאת סנכרון</translation>
 <translation id="7980084013673500153">מזהה נכס: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">טעינה מראש של דפים כדי לאפשר גלישה וחיפוש מהירים יותר</translation>
 <translation id="798145602633458219">הצמדת ההצעה <ph name="SUGGESTION_NAME" /> לתיבת החיפוש</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;תוספים</translation>
 <translation id="862727964348362408">מושעה</translation>
 <translation id="862750493060684461">‏מטמון של CSS</translation>
+<translation id="8627706565932943526">שגיאת סנכרון</translation>
 <translation id="8627795981664801467">התחברויות בטוחות בלבד</translation>
 <translation id="8630903300770275248">יבא משתמש בפיקוח</translation>
 <translation id="8631032106121706562">עלי כותרת</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index e9476f0..42e73c03 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">セキュリティ キーの PIN を入力してください</translation>
 <translation id="457386861538956877">その他...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth デバイスのペア設定</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> をキャストできません。</translation>
 <translation id="4581774856936278355">Linux の復元中にエラーが発生しました</translation>
 <translation id="4582563038311694664">すべての設定をリセット</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">オーバースキャン</translation>
 <translation id="7978412674231730200">秘密鍵</translation>
 <translation id="7978450511781612192">この操作を行うと Google アカウントからログアウトし、ブックマーク、履歴、パスワードなどの設定は同期されなくなります。</translation>
-<translation id="7979036127916589816">同期エラー</translation>
 <translation id="7980084013673500153">アセット ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ページをプリロードして、閲覧と検索をすばやく行えるようにします</translation>
 <translation id="798145602633458219">検索ボックスに候補<ph name="SUGGESTION_NAME" />を追加します</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">拡張機能(&amp;E)</translation>
 <translation id="862727964348362408">停止中</translation>
 <translation id="862750493060684461">CSS キャッシュ</translation>
+<translation id="8627706565932943526">同期エラー</translation>
 <translation id="8627795981664801467">セキュリティで保護された接続のみ</translation>
 <translation id="8630903300770275248">監視対象ユーザーをインポート</translation>
 <translation id="8631032106121706562">デイジー</translation>
diff --git a/chrome/app/resources/generated_resources_ka.xtb b/chrome/app/resources/generated_resources_ka.xtb
index ae823c6..868cdfd 100644
--- a/chrome/app/resources/generated_resources_ka.xtb
+++ b/chrome/app/resources/generated_resources_ka.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">შეიყვანეთ PIN-კოდი თქვენი უსაფრთხოების გასაღებისთვის</translation>
 <translation id="457386861538956877">მეტი…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth მოწყობილობის დაწყვილება</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> ვერ ტრანსლირდება.</translation>
 <translation id="4581774856936278355">შეცდომა Linux-ის აღდგენისას</translation>
 <translation id="4582563038311694664">ყველა პარამეტრის აღდგენა</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">ეკრანის არშია</translation>
 <translation id="7978412674231730200">პირადი გასაღები</translation>
 <translation id="7978450511781612192">ამ ქმედებით გამოხვალთ თქვენი Google ანგარიშებიდან. თქვენი სანიშნეები, ისტორია, პაროლები და სხვა კონტენტი აღარ იქნება სინქრონიზებული.</translation>
-<translation id="7979036127916589816">სინქრონიზაციის შეცდომა</translation>
 <translation id="7980084013673500153">საინვენტარო ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">გვერდების წინასწარ ჩატვირთვა დათვალიერებისა და ძიების პროცესების დასაჩქარებლად</translation>
 <translation id="798145602633458219">შემოთავაზების „<ph name="SUGGESTION_NAME" />“ დართვა საძიებო ველისთვის</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">&amp;გაფართოებები</translation>
 <translation id="862727964348362408">შეჩერებულია</translation>
 <translation id="862750493060684461">CSS ქეში</translation>
+<translation id="8627706565932943526">სინქრონიზაციის შეცდომა</translation>
 <translation id="8627795981664801467">მხოლოდ დაცული კავშირები</translation>
 <translation id="8630903300770275248">კონტროლის ქვეშ მყოფი მომხმარებლის იმპორტი</translation>
 <translation id="8631032106121706562">ფურცლები</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb
index 7b93946..fc91c7ce 100644
--- a/chrome/app/resources/generated_resources_kk.xtb
+++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Қауіпсіздік кілтінің PIN кодын енгізіңіз.</translation>
 <translation id="457386861538956877">Тағы…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth құрылғысын жұптау</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> трансляциялау мүмкін емес.</translation>
 <translation id="4581774856936278355">Linux жүйесін қалпына келтіру кезінде қате шықты.</translation>
 <translation id="4582563038311694664">Барлық параметрлерді қалпына келтіру</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">Экран жиегі</translation>
 <translation id="7978412674231730200">Жеке кілт</translation>
 <translation id="7978450511781612192">Google есептік жазбаларыңыздан шығарыласыз. Бетбелгілер, тарих, құпия сөздер, т.б. синхрондалмайтын болады.</translation>
-<translation id="7979036127916589816">Синхрондау қатесі</translation>
 <translation id="7980084013673500153">Актив идентификаторы: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Интернетте жылдамырақ шарлау және іздеу үшін беттерді алдын ала жүктеу</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> ұсынысын іздеу өрісіне қою</translation>
@@ -5314,6 +5312,7 @@
 <translation id="862542460444371744">&amp;Кеңейтімдер</translation>
 <translation id="862727964348362408">Тоқтатылған</translation>
 <translation id="862750493060684461">CSS кэші</translation>
+<translation id="8627706565932943526">Синхрондау қатесі</translation>
 <translation id="8627795981664801467">Тек қауіпсіз байланыстар</translation>
 <translation id="8630903300770275248">Бақыланатын пайдаланушыны импорттау</translation>
 <translation id="8631032106121706562">Гүл</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb
index db8f189..dc082603 100644
--- a/chrome/app/resources/generated_resources_km.xtb
+++ b/chrome/app/resources/generated_resources_km.xtb
@@ -351,6 +351,7 @@
 <translation id="1493892686965953381">កំពុងរង់ចាំ <ph name="LOAD_STATE_PARAMETER" />...</translation>
 <translation id="1495486559005647033">មាន <ph name="NUM_PRINTERS" /> ឧបករណ៍ទៀត។</translation>
 <translation id="1495677929897281669">ត្រឡប់ទៅ​ផ្ទាំងវិញ</translation>
+<translation id="1499271269825557605">ប្រសិនបើ​អ្នក​មិន​ស្គាល់​កម្មវិធី​បន្ថែម ឬ​ប្រសិនបើ​កម្មវិធី​រុករក​តាមអ៊ីនធឺណិត​របស់អ្នក​មិន​ដំណើរការ​ដូច​ការរំពឹងទុក​ទេ អ្នក​អាច​បិទ ឬ​ប្ដូរ​កម្មវិធី​បន្ថែម​តាមបំណង​នៅទីនេះ​។</translation>
 <translation id="1500297251995790841">ឧបករណ៍មិនស្គាល់ [<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />]</translation>
 <translation id="1503394326855300303">ម្ចាស់គណនីត្រូវចូលគណនីជាមុនសិននៅក្នុងវេនចូលច្រើន.</translation>
 <translation id="150411034776756821">លុប <ph name="SITE" /></translation>
@@ -358,6 +359,7 @@
 <translation id="1507170440449692343">ទំព័រនេះត្រូវបានរារាំងពីការចូលប្រើកាមេរ៉ារបស់អ្នក។</translation>
 <translation id="1507246803636407672">កម្ចាត់</translation>
 <translation id="1508491105858779599">ដាក់​ម្រាមដៃ​របស់អ្នក​នៅលើ​ឧបករណ៍​ចាប់​ស្នាម​ម្រាមដៃ ដើម្បី​ដោះសោ​ឧបករណ៍​នេះ។</translation>
+<translation id="1508575541972276599">កំណែ​បច្ចុប្បន្ន​គឺ Debian 9 (Stretch)</translation>
 <translation id="1509281256533087115">ចូលប្រើ <ph name="DEVICE_NAME_AND_VENDOR" /> ណាមួយតាមរយៈ USB</translation>
 <translation id="150962533380566081">PUK មិនត្រឹមត្រូវ។</translation>
 <translation id="1510030919967934016">ទំព័រនេះត្រូវបានរារាំងពីការតាមដានទីតាំងរបស់អ្នក។</translation>
@@ -433,6 +435,7 @@
 <translation id="1601560923496285236">អនុវត្ត</translation>
 <translation id="1603914832182249871">(អនាមិក)</translation>
 <translation id="1604432177629086300">​មិន​អាចបោះពុម្ព​បានទេ។ សូមពិនិត្យ​​ម៉ាស៊ីនបោះពុម្ព រួច​ព្យាយាម​ម្ដងទៀត។</translation>
+<translation id="1605544918554600534"><ph name="PROFILE_NAME" />៖ សមកាល​កម្ម​ពាក្យសម្ងាត់​មិន​ដំណើរការ​ទេ</translation>
 <translation id="1607139524282324606">សម្អាតធាតុ</translation>
 <translation id="1608626060424371292">ដកអ្នកប្រើចេញ</translation>
 <translation id="1608668830839595724">សកម្មភាពច្រើនជាងមុន​សម្រាប់​ធាតុដែលបានជ្រើសរើស</translation>
@@ -559,6 +562,8 @@
 <translation id="177336675152937177">ទិន្នន័យកម្មវិធីតំឡើងលើអ៊ីនធឺណិត</translation>
 <translation id="1776712937009046120">បន្ថែមអ្នកប្រើ</translation>
 <translation id="1776883657531386793"><ph name="OID" />: <ph name="INFO" /></translation>
+<translation id="1777310661937894236">ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />​។
+    សូម​ចុច "បន្ទាប់" ដើម្បី​បន្ត​ចូល​គណនី <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> របស់អ្នក​។</translation>
 <translation id="1779652936965200207">សូមបញ្ចូលលេខសម្ងាត់នេះនៅលើ "<ph name="DEVICE_NAME" />"។</translation>
 <translation id="1780152987505130652">បិទក្រុម</translation>
 <translation id="1781291988450150470">កូដ PIN បច្ចុប្បន្ន</translation>
@@ -746,6 +751,7 @@
 <translation id="2048653237708779538">មិនមាន​សកម្មភាពទេ</translation>
 <translation id="2050339315714019657">បញ្ឈរ</translation>
 <translation id="2053312383184521053">ទិន្នន័យក្នុងស្ថានភាពទុកចោល</translation>
+<translation id="2055585478631012616">អ្នក​នឹង​ត្រូវ​នាំចេញ​ពី​គេហទំព័រ​ទាំងនេះ រួមទាំង​នៅក្នុង​ផ្ទាំង​បើក​ផងដែរ</translation>
 <translation id="205560151218727633">រូបសញ្ញា Google ជំនួយការ</translation>
 <translation id="2058456167109518507">បាន​រកឃើញ​ឧបករណ៍</translation>
 <translation id="2059913712424898428">តំបន់​ម៉ោង</translation>
@@ -761,6 +767,7 @@
 <translation id="2079545284768500474">បកក្រោយ</translation>
 <translation id="2080070583977670716">ការកំណត់ច្រើនទៀត</translation>
 <translation id="2087822576218954668">បោះពុម្ព៖ <ph name="PRINT_NAME" /></translation>
+<translation id="2088690981887365033">បណ្ដាញ VPN</translation>
 <translation id="2089566709556890888">រុករក​ដោយសុវត្ថិភាពជាមួយ Google Chrome</translation>
 <translation id="2089795179672254991">សួរនៅពេល​ដែល​ទំព័រ​ចង់​មើល​អត្ថបទ និង​រូបភាព​ដែល​បាន​ចម្លង​ទៅ​អង្គចងចាំ (បាន​ណែ​នាំ)</translation>
 <translation id="2090165459409185032">ដើម្បីសង្គ្រោះទិន្នន័យគណនីរបស់អ្នក សូមចូលទៅកាន់៖ google.com/accounts/recovery</translation>
@@ -984,6 +991,7 @@
 <translation id="2379232090534544565">គេហទំព័រមួយកំពុង​ចូលប្រើ​ការបញ្ចូលសំឡេង និងវីដេអូ</translation>
 <translation id="2379281330731083556">បោះពុម្ពដោយប្រើប្រអប់ប្រព័ន្ធ... <ph name="SHORTCUT_KEY" /></translation>
 <translation id="2381756643783702095">សួរមុនពេលផ្ញើ (បានណែនាំ)</translation>
+<translation id="2382818385048255866">ពិនិត្យមើល​កម្មវិធី​បន្ថែម​របស់អ្នក</translation>
 <translation id="2384436799579181135">មានបញ្ហាកើតឡើង។ សូម​ពិនិត្យ​ម៉ាស៊ីន​បោះពុម្ព​របស់អ្នក រួច​ព្យាយាម​ម្តងទៀត។</translation>
 <translation id="2387458720915042159">ប្រភេទ​នៃការ​តភ្ជាប់​ប្រូកស៊ី</translation>
 <translation id="2391419135980381625">ពុម្ពអក្សរបទដ្ឋាន</translation>
@@ -1035,6 +1043,7 @@
 <translation id="2462724976360937186">លេខសម្គាល់សោអាជ្ញាធរវិញ្ញាបនប័ត្រ</translation>
 <translation id="2462752602710430187">បានបន្ថែម <ph name="PRINTER_NAME" /></translation>
 <translation id="2464089476039395325">ប្រូកស៊ី HTTP</translation>
+<translation id="2467267713099745100">បណ្ដាញ <ph name="NETWORK_TYPE" />, ត្រូវបាន​បិទ</translation>
 <translation id="2468205691404969808">ប្រើ​ខូគី​ដើម្បី​ចងចាំ​ចំណូលចិត្ត​របស់អ្នក បើ​ទោះ​បី​ជា​អ្នក​​មិន​ចូលទៅកាន់​ទំព័រ​ទាំងនោះ​ក៏ដោយ</translation>
 <translation id="2468402215065996499">ថាម៉ាហ្គោឈី</translation>
 <translation id="2469259292033957819">អ្នក​មិនមាន​ម៉ាស៊ីន​បោះពុម្ព​ដែលបាន​រក្សាទុក​ទេ​។</translation>
@@ -1289,6 +1298,7 @@
 <translation id="2800760947029405028">បង្ហោះ​រូបភាព</translation>
 <translation id="2803375539583399270">បញ្ចូលកូដ PIN</translation>
 <translation id="2804043232879091219">មិនអាចបើក​កម្មវិធីរុករកតាម​អ៊ីនធឺណិត​ផ្សេងបានទេ</translation>
+<translation id="2804667941345577550">អ្នក​នឹង​ត្រូវនាំចេញ​ពី​គេហទំព័រ​នេះ រួមទាំង​នៅក្នុង​ផ្ទាំង​បើក​ផងដែរ</translation>
 <translation id="2804680522274557040">បានបិទ​កាមេរ៉ា</translation>
 <translation id="2805646850212350655">ប្រព័ន្ធឯកសារអ៊ីនគ្រីប Microsoft</translation>
 <translation id="2805756323405976993">កម្មវិធី</translation>
@@ -1296,6 +1306,7 @@
 <translation id="2806891468525657116">ផ្លូវកាត់មានរួចហើយ</translation>
 <translation id="2807517655263062534">ឯកសារដែលអ្នកទាញយកបង្ហាញនៅទីនេះ</translation>
 <translation id="2809586584051668049">និង <ph name="NUMBER_ADDITIONAL_DISABLED" /> ទៀត</translation>
+<translation id="2810390687497823527">ប្រសិនបើ​អ្នក​មិន​ស្គាល់​កម្មវិធី​បន្ថែម ឬ​ប្រសិនបើ​កម្មវិធី​រុករក​តាមអ៊ីនធឺណិត​របស់អ្នក​មិន​ដំណើរការ​ដូច​ការរំពឹងទុក​ទេ អ្នក​អាច​បិទ ឬ​ប្ដូរ​កម្មវិធី​បន្ថែម​តាមបំណង​នៅទីនេះ​។</translation>
 <translation id="2812049959647166806">មិនអាចប្រើ Thunderbolt បានទេ</translation>
 <translation id="2812944337881233323">សាកល្បងចាកចេញពីគណនី ហើយចូលមកវិញម្តងទៀត</translation>
 <translation id="2812989263793994277">កុំបង្ហាញរូបភាពណាមួយ</translation>
@@ -1335,6 +1346,7 @@
 <translation id="2861941300086904918">កម្មវិធីគ្រប់គ្រងសុវត្ថិភាពអតិថិជនដើម</translation>
 <translation id="2864601841139725659">កំណត់​រូបភាព​កម្រងព័ត៌មាន​របស់អ្នក</translation>
 <translation id="2865919525181940183">រូបថតអេក្រង់របស់កម្មវិធី ដែលបង្ហាញនៅលើអេក្រង់ក្នុងពេលនេះ</translation>
+<translation id="286674810810214575">កំពុង​ពិនិត្យមើល​ប្រភព​ថាមពល...</translation>
 <translation id="2867768963760577682">បើកជាផ្ទាំងដែលបានដៅ</translation>
 <translation id="2868746137289129307">ផ្នែកបន្ថែមនេះហួសសម័យហើយ ហើយបានបិទដំណើរការដោយគោលការណ៍សហគ្រាស។ វាអាចបើកដំណើរការដោយស្វ័យប្រវត្តិ នៅពេលមានកំណែថ្មីជាងនេះ។</translation>
 <translation id="2870560284913253234">គេហទំព័រ</translation>
@@ -1412,6 +1424,7 @@
 <translation id="2972581237482394796">ធ្វើវិញ</translation>
 <translation id="2973324205039581528">បិទសំឡេង​ទំព័រ</translation>
 <translation id="2977480621796371840">លុបចេញ​ពីក្រុម</translation>
+<translation id="2979520980928493164">Chrome ដែលមាន​សុវត្ថិភាព និង​ដំណើរការ​លឿន​ជាងមុន</translation>
 <translation id="2979639724566107830">បើក​នៅក្នុង​វិនដូថ្មី</translation>
 <translation id="2981113813906970160">បង្ហាញព្រួញកណ្តុរធំ</translation>
 <translation id="2982970937345031">រាយការណ៍​ជាលក្ខណៈ​អនាមិក</translation>
@@ -1518,6 +1531,7 @@
 <translation id="3143515551205905069">បោះបង់​ការ​ធ្វើ​សម​កាល​កម្ម</translation>
 <translation id="3143754809889689516">ចាក់​ពីដំបូង</translation>
 <translation id="3144647712221361880">បើកដំណជា</translation>
+<translation id="3145187901750964977">មិនអាច​ដំឡើង​ម៉ាស៊ីន​និម្មិត​បានទេ​។ សូមព្យាយាម​ម្ដងទៀត ឬទាក់ទង​អ្នកគ្រប់គ្រង​ឧបករណ៍​របស់​ស្ថាប័ន​អ្នក។ លេខកូដ​មានបញ្ហា​៖ <ph name="ERROR_CODE" />​។</translation>
 <translation id="3149477159749171726">កំណែ៖
     <ph name="LINUX_VERSION" />
 
@@ -1556,6 +1570,7 @@
 <translation id="3192947282887913208">ឯកសារសម្លេង</translation>
 <translation id="3194737229810486521"><ph name="URL" /> ចង់ផ្ទុក​ទិន្នន័យ​នៅលើ​ឧបករណ៍​របស់អ្នក​ជាអចិន្ត្រៃយ៍</translation>
 <translation id="3199127022143353223">ម៉ាស៊ីនមេ</translation>
+<translation id="3201306578844503970">មិនអាច​ដំឡើង​ម៉ាស៊ីន​និម្មិត​បានទេ ដោយសារ​មាន​បញ្ហា​បណ្ដាញ​។ សូមព្យាយាម​ម្ដងទៀត ឬទាក់ទង​អ្នកគ្រប់គ្រង​ឧបករណ៍​របស់​ស្ថាប័ន​អ្នក។ លេខកូដ​មានបញ្ហា​៖ <ph name="ERROR_CODE" />​។</translation>
 <translation id="3201422919974259695">ឧបករណ៍ USB ដែលអាចប្រើបាននឹងបង្ហាញនៅទីនេះ។</translation>
 <translation id="3202131003361292969">ផ្លូវ</translation>
 <translation id="3202173864863109533">សម្លេងរបស់ផ្ទាំងនេះកំពុងត្រូវបានបិទ។</translation>
@@ -2065,6 +2080,7 @@
 <translation id="389589731200570180">ចែករំលែកជាមួយភ្ញៀវ</translation>
 <translation id="389901847090970821">ជ្រើសរើសក្តារចុច</translation>
 <translation id="3899879303189199559">ក្រៅបណ្ដាញច្រើនជាងមួយឆ្នាំ</translation>
+<translation id="3900789207771372462">កម្មវិធី​បន្ថែម​មួយចំនួន​អាច​មើលឃើញ​សកម្មភាព​រុករក​តាមអ៊ីនធឺណិត​របស់អ្នក រួមទាំង​ព័ត៌មាន​ផ្ទាល់ខ្លួន​ផងដែរ​។</translation>
 <translation id="3900966090527141178">នាំចេញ​ពាក្យសម្ងាត់</translation>
 <translation id="3901991538546252627">កំពុងភ្ជាប់ទៅ <ph name="NAME" /></translation>
 <translation id="3905761538810670789">ជួសជុលកម្មវិធី</translation>
@@ -2192,6 +2208,7 @@
 <translation id="407520071244661467">មាត្រដ្ឋាន</translation>
 <translation id="4075639477629295004">មិនអាច​ភ្ជាប់ទៅ <ph name="FILE_NAME" /> បានទេ។</translation>
 <translation id="4077917118009885966">បាន​ទប់ស្កាត់​ការផ្សាយពាណិជ្ជកម្មនៅលើទំព័រនេះ</translation>
+<translation id="4077919383365622693">ទិន្នន័យ និង​ខូគី​ទាំងអស់​ដែល <ph name="SITE" /> បានរក្សាទុក​នឹង​ត្រូវសម្អាត​។</translation>
 <translation id="4079140982534148664">ប្រើការពិនិត្យ​អក្ខរាវិរុទ្ធដែលបាន​កែលម្អ</translation>
 <translation id="4081242589061676262">មិនអាច​ភ្ជាប់​ឯកសារ​បានទេ។</translation>
 <translation id="4084682180776658562">ចំណាំ</translation>
@@ -2266,6 +2283,7 @@
 <translation id="4181841719683918333">ភាសា</translation>
 <translation id="4184885522552335684">អូសដើម្បីផ្លាស់ទីអេក្រង់</translation>
 <translation id="4194570336751258953">បើកដំណើរការ ប៉ះ ដើម្បី ចុច</translation>
+<translation id="4194595472342532425">មិន​អាច​រៀបចំ Plugin VM បានទេ ដោយសារ​មាន​បញ្ហា​ក្នុងការកំណត់​រចនា​សម្ព័ន្ធ​។ សូម​ទាក់ទង​អ្នកគ្រប់គ្រង​ឧបករណ៍​របស់​ស្ថាប័ន​អ្នក​។ លេខកូដ​មានបញ្ហា​៖ <ph name="ERROR_CODE" />​។</translation>
 <translation id="4195643157523330669">បើកនៅក្នុងផ្ទាំងថ្មី</translation>
 <translation id="4195814663415092787">បន្តកន្លែងដែលអ្នកបានចាកចេញ</translation>
 <translation id="4198146608511578238">គ្រាន់តែ​ចុចរូបកម្មវិធីចាប់ផ្តើមឲ្យជាប់ នោះអ្នកនឹងអាចនិយាយទៅកាន់ Google ជំនួយការរបស់អ្នកបាន។</translation>
@@ -2489,6 +2507,7 @@
 <translation id="4549791035683739768">គ្មានស្នាម​ម្រាមដៃ​ត្រូវបាន​រក្សាទុក​នៅលើ​សោសុវត្ថិភាព​របស់អ្នកទេ</translation>
 <translation id="4551763574344810652">ចុច <ph name="MODIFIER_KEY_DESCRIPTION" /> ដើម្បី​ត្រឡប់​វិញ</translation>
 <translation id="4552089082226364758">Flash</translation>
+<translation id="4552759165874948005">បណ្ដាញ <ph name="NETWORK_TYPE" />, កម្លាំង​រលកសញ្ញា <ph name="SIGNAL_STRENGTH" />%</translation>
 <translation id="4554591392113183336">កម្មវិធីបន្ថែមខាងក្រៅស្ថិតនៅក្នុងកំណែដូចគ្នា ឬទាបជាងបើប្រៀបនឺងកំណែដែលមានស្រាប់។</translation>
 <translation id="4555769855065597957">ស្រមោល</translation>
 <translation id="4555863373929230635">ដើម្បី​រក្សាទុកពាក្យសម្ងាត់​ទៅក្នុងគណនី Google របស់អ្នក សូមចូលគណនី រួចបើក "សមកាលកម្ម"។</translation>
@@ -2510,7 +2529,6 @@
 <translation id="4572779512957829735">បញ្ចូលកូដ PIN សម្រាប់​សោសុវត្ថិភាព​របស់អ្នក</translation>
 <translation id="457386861538956877">ច្រើនទៀត...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ផ្គូផ្គង​ឧបករណ៍​ប៊្លូធូស</translation>
 <translation id="4579581181964204535">មិនអាចខាស <ph name="HOST_NAME" /> បានទេ</translation>
 <translation id="4581774856936278355">មានបញ្ហា​ខណៈពេល​កំពុងស្ដារ Linux</translation>
 <translation id="4582563038311694664">កំណត់ការកំណត់ទាំងអស់ឡើងវិញ</translation>
@@ -2566,6 +2584,7 @@
 <translation id="4665446389743427678">ទិន្នន័យ​ទាំងអស់​ដែលបាន​រក្សាទុក​ដោយ <ph name="SITE" /> នឹង​ត្រូវបានលុប។</translation>
 <translation id="4668721319092543482">ចុចដើម្បីបើកដំណើរការ <ph name="PLUGIN_NAME" /></translation>
 <translation id="4672657274720418656">ឌីសស្ទៀលទំព័រ</translation>
+<translation id="46733273239502219">​ទិន្នន័យ​ដែលបានផ្ទុកក្នុងឧបករណ៍របស់កម្មវិធី​ដែលបាន​ដំឡើង​ក៏នឹង​ត្រូវ​សម្អាត​ផងដែរ</translation>
 <translation id="4673442866648850031">បើកឧបករណ៍ប៊ិច នៅពេលលុបប៊ិចនោះ</translation>
 <translation id="4677585247300749148"><ph name="URL" /> ចង់ឆ្លើយតប​នឹងព្រឹត្តិការណ៍​ភាពងាយស្រួល</translation>
 <translation id="4677772697204437347">មេម៉ូរី GPU</translation>
@@ -2697,6 +2716,7 @@
 <translation id="4876273079589074638">ជួយ​វិស្វករ​របស់​យើង​ក្នុងការ​ស៊ើប​អង្កេត និងដោះស្រាយ​ការ​គាំង​នេះ។ សូម​ធ្វើ​បញ្ជី​ជំហាន​ជាក់ស្តែង ប្រសិន​បើអ្នក​អាច​ធ្វើ​បាន។ ព័ត៌មាន​លម្អិតគួរតែមានព័ត៌មានច្រើន!</translation>
 <translation id="4876895919560854374">ចាក់សោ ឬដោះសោអេក្រង់</translation>
 <translation id="4877276003880815204">ត្រួតពិនិត្យ​ធាតុ</translation>
+<translation id="4878653975845355462">អ្នកគ្រប់គ្រង​របស់អ្នក​បានបិទ​ផ្ទៃខាងក្រោយ​ផ្ទាល់ខ្លួន</translation>
 <translation id="4879491255372875719">ស្វ័យប្រវត្តិ (លំនាំដើម)</translation>
 <translation id="4880328057631981605">ឈ្មោះចំណុចចូលប្រើ</translation>
 <translation id="4880827082731008257">ប្រវត្តិស្វែងរក</translation>
@@ -2752,6 +2772,7 @@
 <translation id="4943691134276646401">"<ph name="CHROME_EXTENSION_NAME" />" ចង់ភ្ជាប់​ទៅរន្ធស៊េរី</translation>
 <translation id="4944310289250773232">សេវាកម្មផ្ទៀងផ្ទាត់នេះត្រូវបានបង្ហោះ​ដោយ <ph name="SAML_DOMAIN" /></translation>
 <translation id="495170559598752135">សកម្មភាព</translation>
+<translation id="4952981627953231344">មិន​អនុញ្ញាតឱ្យប្រើ Plugin VM ​នៅលើ​ឧបករណ៍​នេះ​ទេ​។ សូមទាក់ទង​អ្នកគ្រប់គ្រង​ឧបករណ៍​របស់​ស្ថាប័ន​អ្នក​។</translation>
 <translation id="4953689047182316270">ឆ្លើយតប​នឹងព្រឹត្តិការណ៍​ភាពងាយស្រួល</translation>
 <translation id="4953808748584563296">រូបតំណាងពណ៌ទឹកក្រូចលំនាំដើម</translation>
 <translation id="4955710816792587366">ជ្រើសរើសកូដ PIN របស់អ្នក</translation>
@@ -3252,6 +3273,7 @@
 <translation id="5687326903064479980">ល្វែងម៉ោង</translation>
 <translation id="5689516760719285838">ទីតាំង</translation>
 <translation id="56907980372820799">ភ្ជាប់ទិន្នន័យ</translation>
+<translation id="5691180005790455277">ទិន្នន័យ និង​ខូគី​ទាំងអស់​ដែល <ph name="SITE_GROUP_NAME" /> រក្សាទុក និង​គេហទំព័រ​ទាំងឡាយ​ដែល​ស្ថិតក្រោម​ការគ្រប់គ្រង​របស់វា​នឹង​ត្រូវ​សម្អាត​។</translation>
 <translation id="5691511426247308406">គ្រួសារ</translation>
 <translation id="5692183275898619210">បាន​បញ្ចប់​ការ​បោះពុម្ព​​</translation>
 <translation id="5696143504434933566">រាយការណ៍​ពី​ការបំពាន​ពី "<ph name="EXTENSION_NAME" />"</translation>
@@ -3473,6 +3495,7 @@
 <translation id="6007240208646052708">មិនមាន​ការស្វែង​រកតាម​សំឡេង​ជាភាសា​របស់អ្នក​ទេ។</translation>
 <translation id="6009781704028455063">ឧបករណ៍ចាប់សញ្ញា​ដែលភ្ជាប់​មកជាមួយ</translation>
 <translation id="6010869025736512584">ការចូលប្រើការបញ្ចូលវីដេអូ</translation>
+<translation id="6011074160056912900">បណ្ដាញ​អ៊ីសឺរណិត</translation>
 <translation id="6011193465932186973">ស្នាម​ម្រាមដៃ</translation>
 <translation id="6011449291337289699">ជម្រះទិន្នន័យគេហទំព័រ</translation>
 <translation id="6015266928248016057">PUK មិនត្រឹមត្រូវ។ ការសាកល្បងឡើងវិញ​នៅសល់៖ <ph name="RETRIES" />។</translation>
@@ -3509,6 +3532,7 @@
 <translation id="6053401458108962351">ជម្រះទិន្នន័យរុករក</translation>
 <translation id="6055171183283175969">ពាក្យសម្ងាត់​ដែលអ្នក​បានបញ្ចូល​មិនត្រឹមត្រូវ​ទេ។</translation>
 <translation id="6055392876709372977">PKCS #1 SHA-256 ជាមួយនឹងការអ៊ិនគ្រីប RSA</translation>
+<translation id="6055907707645252013">បណ្ដាញ <ph name="NETWORK_TYPE" />, មិនបាន​ភ្ជាប់</translation>
 <translation id="6056710589053485679">ដំណើរការឡើងវិញធម្មតា</translation>
 <translation id="6057381398996433816">គេហទំព័រ​នេះ​ត្រូវបាន​ទប់ស្កាត់​មិនឱ្យ​ប្រើប្រាស់ឧបករណ៍​ចាប់ពន្លឺ និងឧបករណ៍​ចាប់ចលនា។</translation>
 <translation id="6058567592298841668">ម៉ាស៊ីន​និម្មិត​របស់កម្មវិធីជំនួយ៖ <ph name="PLUGIN_VM_NAME" /></translation>
@@ -3572,6 +3596,7 @@
 <translation id="6136114942382973861">បិទ​របារ​ទាញយក</translation>
 <translation id="6137767437444130246">វិញ្ញាបនបត្រ​អ្នក​ប្រើប្រាស់</translation>
 <translation id="6138680304137685902">ហត្ថលេខា X9.62 ECDSA ជាមួយ SHA-384</translation>
+<translation id="6138894911715675297"><ph name="NETWORK_TYPE" />, គ្មាន​បណ្ដាញ</translation>
 <translation id="6141988275892716286">បញ្ជាក់​ការទាញយក</translation>
 <translation id="6143186082490678276">ទទួលយកជំនួយ</translation>
 <translation id="6144938890088808325">ជួយពួកយើងក្នុងការកែលម្អ Chromebooks</translation>
@@ -3878,6 +3903,7 @@
 <translation id="6602956230557165253">ប្រើប៊ូតុងព្រួញខាងស្តាំ និងខាងឆ្វេងដើម្បីរុករក។</translation>
 <translation id="6605847144724004692">មិនទាន់​មាន​អ្នកប្រើប្រាស់ណា​ធ្វើការវាយតម្លៃ​នៅឡើយទេ។</translation>
 <translation id="6607831829715835317">ឧបករណ៍ច្រើនទៀត</translation>
+<translation id="6611972847767394631">ស្វែងរកផ្ទាំងរបស់អ្នកនៅទីនេះ</translation>
 <translation id="6612358246767739896">មាតិកាដែលបានការពារ</translation>
 <translation id="6615455863669487791">បង្ហាញខ្ញុំ</translation>
 <translation id="6618097958368085618">មិនអី​ទេ​រក្សាទុក​ចុះ</translation>
@@ -3946,6 +3972,7 @@
 <translation id="6709133671862442373">ព័ត៌មាន</translation>
 <translation id="6709357832553498500">ភ្ជាប់ដោយប្រើ <ph name="EXTENSIONNAME" /></translation>
 <translation id="6710213216561001401">មុន</translation>
+<translation id="6715803357256707211">មាន​បញ្ហាកើតឡើង អំឡុង​ពេល​ដំឡើង​កម្មវិធី Linux របស់អ្នក។ សូមចុច​លើ​ការជូន​ដំណឹង​សម្រាប់​ព័ត៌មាន​លម្អិត​។</translation>
 <translation id="6721678857435001674">មើល​ម៉ាក និង​ម៉ូដែល​សោ​សុវត្ថិភាព​របស់អ្នក</translation>
 <translation id="6721972322305477112">ឯកសារ</translation>
 <translation id="672213144943476270">សូមដោះសោប្រវត្តិរូបរបស់អ្នកមុនពេលធ្វើការរុករកជារបៀបភ្ញៀវ</translation>
@@ -3979,6 +4006,7 @@
 <translation id="6769712124046837540">កំពុងបន្ថែមម៉ាស៊ីនបោះពុម្ព...</translation>
 <translation id="6770664076092644100">ផ្ទៀងផ្ទាត់​តាមរយៈ NFC</translation>
 <translation id="6771503742377376720">គឺជាអាជ្ញាធរវិញ្ញាបនប័ត្រ</translation>
+<translation id="6772339735733515807">គ្រប់គ្រង​កម្មវិធី​បន្ថែម​របស់​អ្នក</translation>
 <translation id="6775163072363532304">ឧបករណ៍ដែលអាចប្រើ​បាននឹងបង្ហាញ​នៅទីនេះ។</translation>
 <translation id="6777817260680419853">​បាន​ទប់ស្កាត់​ការបញ្ជូន​បន្ត</translation>
 <translation id="6778737459546443941">មាតាបិតារបស់អ្នកមិនទាន់យល់ព្រមនៅឡើយទេ</translation>
@@ -4117,6 +4145,7 @@
 <translation id="6972180789171089114">សំឡេង/វីដេអូ</translation>
 <translation id="6972553992270299730"><ph name="ORIGIN" /> មិនអាច​បើក​ឯកសារ​នៅក្នុង​ថតនេះ​បានទេ ដោយសារ​ថតនេះមាន​ឯកសារ​ប្រព័ន្ធ</translation>
 <translation id="6972754398087986839">ចាប់ផ្ដើម</translation>
+<translation id="6973611239564315524">មានកំណែថ្មី​សម្រាប់ដំឡើង​ទៅ Debian 10 (Buster)</translation>
 <translation id="6974609594866392343">មុខងារ​សាកល្បង​គ្មាន​អ៊ីនធឺណិត</translation>
 <translation id="6977381486153291903">ការកែប្រែកម្មវិធីបង្កប់</translation>
 <translation id="6978121630131642226">ម៉ាស៊ីនស្វែងរក</translation>
@@ -4576,6 +4605,7 @@
 <translation id="7644543211198159466">ពណ៌ និង​រចនាប័ទ្ម</translation>
 <translation id="7645176681409127223"><ph name="USER_NAME" /> (ម្ចាស់)</translation>
 <translation id="7645681574855902035">កំពុងបោះបង់​ការបម្រុងទុក Linux</translation>
+<translation id="7646772052135772216">សមកាល​កម្ម​ពាក្យសម្ងាត់​មិន​ដំណើរការ​ទេ</translation>
 <translation id="7647403192093989392">មិនមាន​សកម្មភាពថ្មីៗទេ</translation>
 <translation id="7648992873808071793">ផ្ទុកឯកសារនៅលើឧបករណ៍នេះ</translation>
 <translation id="7649070708921625228">ជំនួយ</translation>
@@ -4764,6 +4794,7 @@
 <translation id="7877451762676714207">កំហុសឆ្គងម៉ាស៊ីនមេមិនស្គាល់។ សូូមព្យាយាមម្តងទៀត ឬទំនាក់ទំនងអ្នកគ្រប់គ្រងម៉ាស៊ីនមេ។</translation>
 <translation id="7877680364634660272">ស្វែងយល់</translation>
 <translation id="7878562273885520351">ពាក្យសម្ងាត់​របស់អ្នក​អាចត្រូវ​បានគេលួចប្រើ​</translation>
+<translation id="7879631849810108578">បានកំណត់​ផ្លូវកាត់​៖ <ph name="IDS_SHORT_SET_COMMAND" /></translation>
 <translation id="7880823633812189969">ទិន្នន័យ​មូលដ្ឋាន​នឹងលុប នៅពេលអ្នក​ចាប់ផ្ដើម​ឡើងវិញ</translation>
 <translation id="7881483672146086348">មើលគណនី</translation>
 <translation id="7882358943899516840">ប្រភេទអ្នកផ្តល់សេវាកម្ម</translation>
@@ -4838,7 +4869,6 @@
 <translation id="7974936243149753750">ពង្រីកជ្រុល</translation>
 <translation id="7978412674231730200">សោឯកជន</translation>
 <translation id="7978450511781612192">សកម្មភាព​នេះនឹង​នាំ​អ្នកចេញ​ពីគណនី Google របស់អ្នក។ ចំណាំ ប្រវត្តិ ពាក្យសម្ងាត់ និង​អ្វីៗជា​ច្រើនទៀត​របស់អ្នកនឹងលែង​ធ្វើសមកាលកម្ម​ទៀតហើយ។</translation>
-<translation id="7979036127916589816">កំហុសឆ្គងសមកម្ម</translation>
 <translation id="7980084013673500153">លេខសម្គាល់ទ្រព្យសកម្ម៖ <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ផ្ទុក​ទំព័រ​ជាមុន​ដើម្បី​ឱ្យ​ការ​រុករក​ និង​ការ​ស្វែង​រក​កាន់តែ​លឿន​ជាងមុន</translation>
 <translation id="798145602633458219">បន្ថែម​ការណែនាំ <ph name="SUGGESTION_NAME" /> ទៅក្នុងប្រអប់​ស្វែងរក</translation>
@@ -4850,6 +4880,7 @@
 <translation id="7987814697832569482">ភ្ជាប់​តាមរយៈ VPN នេះជានិច្ច</translation>
 <translation id="7988355189918024273">បើកដំណើរការមុខងារលទ្ធភាពប្រើប្រាស់</translation>
 <translation id="7991296728590311172">ការកំណត់ការប្រើប៊ូតុងចុច</translation>
+<translation id="7994350303002908848">មិនអាច​ដំឡើង Plugin VM បានទេ​។ សូមព្យាយាម​ម្ដងទៀត ឬទាក់ទង​អ្នកគ្រប់គ្រង​ឧបករណ៍​របស់​ស្ថាប័ន​អ្នក។ លេខកូដ​មានបញ្ហា​៖ <ph name="ERROR_CODE" />​។</translation>
 <translation id="7994702968232966508">វិធីសាស្ត្រ EAP</translation>
 <translation id="7997826902155442747">ដំណើរការអាទិភាព</translation>
 <translation id="7999229196265990314">បានបង្កើតឯកសារខាងក្រោម៖
@@ -5097,6 +5128,7 @@
 <translation id="8327039559959785305">មានបញ្ហា​ក្នុងការភ្ជាប់​ឯកសារ Linux ។ សូមព្យាយាម​ម្ដងទៀត។</translation>
 <translation id="8335587457941836791">ដកការដៅចេញពីធ្នើ</translation>
 <translation id="8336407002559723354">ការផ្ដល់កំណែថ្មីបញ្ចប់នៅខែ <ph name="MONTH_AND_YEAR" /></translation>
+<translation id="8336721153892716270">ចាប់ផ្ដើម​ឧបករណ៍​ឡើងវិញ ដើម្បី​បង្ហាញ​អក្សរ​ប្រព័ន្ធ​ជា​ភាសា​<ph name="LANGUAGE" /></translation>
 <translation id="8336739000755212683">ប្ដូរ​រូបភាពគណនីរបស់​ឧបករណ៍</translation>
 <translation id="8337047789441383384">អ្នកបានចុះឈ្មោះ​សោសុវត្ថិភាពនេះ​រួចហើយ។ អ្នកមិនចាំបាច់​ចុះឈ្មោះសោសុវត្ថិភាព​នេះម្ដងទៀតទេ។</translation>
 <translation id="8338952601723052325">គេហទំព័រអ្នកអភិវឌ្ឍន៍</translation>
@@ -5140,6 +5172,7 @@
 <translation id="8400146488506985033">គ្រប់គ្រងមនុស្ស</translation>
 <translation id="8401432541486058167">ផ្ដល់កូដ PIN ដែលពាក់ព័ន្ធនឹង​កាតឆ្លាតវៃរបស់អ្នក។</translation>
 <translation id="8405046151008197676">ទទួលបានការរំលេច​ពីកំណែ​ថ្មីបំផុត</translation>
+<translation id="8408068190360279472">បណ្ដាញ <ph name="NETWORK_TYPE" />, កំពុង​ភ្ជាប់</translation>
 <translation id="8410775397654368139">Google Play</translation>
 <translation id="8413385045638830869">សួរជាមុនសិន (បានណែនាំ)</translation>
 <translation id="8418445294933751433">បង្ហាញជាផ្ទាំង</translation>
@@ -5283,6 +5316,7 @@
 <translation id="862542460444371744">កម្មវិធីបន្ថែម</translation>
 <translation id="862727964348362408">ត្រូវបានបញ្ឈប់</translation>
 <translation id="862750493060684461">ឃ្លាំងសម្ងាត់ CSS</translation>
+<translation id="8627706565932943526">កំហុសឆ្គងសមកម្ម</translation>
 <translation id="8627795981664801467">ការភ្ជាប់ដែលមានសុវត្ថិភាពប៉ុណ្ណោះ</translation>
 <translation id="8630903300770275248">នាំចូលអ្នកប្រើដែលបានចាត់</translation>
 <translation id="8631032106121706562">ត្របកផ្កា</translation>
@@ -5429,6 +5463,7 @@
 <translation id="8807632654848257479">ថេរ</translation>
 <translation id="8808478386290700967">Web Store</translation>
 <translation id="8808686172382650546">ឆ្មា</translation>
+<translation id="8808744862003883508">នៅលើ​ទំព័រ​នេះ អ្នក​អាច​មើលឃើញ​កម្មវិធី​បន្ថែម​ទាំងអស់​ដែលដំឡើង​នៅក្នុង Chrome​។</translation>
 <translation id="8809147117840417135">បៃតង​ស្រាល</translation>
 <translation id="8813698869395535039">មិនអាចចូល <ph name="USERNAME" /> បានទេ</translation>
 <translation id="8813811964357448561">ផ្ទាំងក្រដាស</translation>
@@ -5694,6 +5729,7 @@
 <translation id="9188732951356337132">បញ្ជូន​ទិន្នន័យ​ប្រើប្រាស់ និង​វិភាគ។ បច្ចុប្បន្ននេះ ឧបករណ៍នេះ​កំពុងបញ្ជូន​ទិន្នន័យនៃការ​វិភាគ ឧបករណ៍ និងការ​ប្រើប្រាស់​កម្មវិធី​ទៅ Google ដោយស្វ័យប្រវត្តិ។ សកម្មភាពនេះ​នឹងមិនត្រូវ​បានធ្វើឡើង ដើម្បី​កំណត់​អត្តសញ្ញាណ​កូន​របស់អ្នក​នោះទេ តែការធ្វើបែបនេះ​នឹងជួយដល់ស្ថិរភាពកម្មវិធី និងប្រព័ន្ធ ព្រមទាំង​ការកែលម្អ​ផ្សេងទៀត។ ទិន្នន័យ​ប្រមូលបាន​មួយចំនួន​ក៏នឹង​ជួយដល់​កម្មវិធី និង​ដៃគូ Google ដូចជា​អ្នកអភិវឌ្ឍន៍ Android ផងដែរ។ ប្រសិនបើ​ការកំណត់​សកម្មភាព​កម្មវិធី និង​គេហទំព័រ​បន្ថែម​ត្រូវបាន​បើកសម្រាប់​កូនរបស់អ្នក នោះ​ទិន្នន័យនេះ​អាចត្រូវ​បានរក្សាទុក​ទៅក្នុង​គណនី Google របស់គាត់។ <ph name="BEGIN_LINK2" />ស្វែងយល់​បន្ថែម<ph name="END_LINK2" /></translation>
 <translation id="9190063653747922532">L2TP/IPsec + ប៊ូតុង pre-shared</translation>
 <translation id="920045321358709304">ស្វែងរក <ph name="SEARCH_ENGINE" /></translation>
+<translation id="9201023452444595544">រាល់​​ទិន្នន័យ​ដែលបានផ្ទុកក្នុងឧបករណ៍​នឹង​ត្រូវបាន​សម្អាត</translation>
 <translation id="9201220332032049474">ជម្រើស​ចាក់សោអេក្រង់</translation>
 <translation id="9203398526606335860">បើកដំណើរការទម្រង់</translation>
 <translation id="9203904171912129171">ជ្រើសរើស​ឧបករណ៍</translation>
@@ -5706,6 +5742,7 @@
 <translation id="9220525904950070496">ដកគណនីចេញ</translation>
 <translation id="9220820413868316583">លើកម្រាមដៃ​ រួច​ព្យាយាម​ម្ដងទៀត។</translation>
 <translation id="923467487918828349">បង្ហាញទាំងអស់</translation>
+<translation id="929117907539171075">​ទិន្នន័យ​ដែលបានផ្ទុកក្នុងឧបករណ៍​របស់កម្មវិធី​ដែលបាន​ដំឡើង​ក៏នឹង​ត្រូវ​សម្អាត​ផងដែរ</translation>
 <translation id="930268624053534560">តែមពេលវេលាលម្អិត</translation>
 <translation id="932327136139879170">ទំព័រដើម</translation>
 <translation id="932508678520956232">មិនអាចផ្តួចផ្តើមការបោះពុម្ពទេ។</translation>
@@ -5731,6 +5768,7 @@
 <translation id="960719561871045870">លេខកូដប្រតិបត្តិករ</translation>
 <translation id="960987915827980018">នៅសល់ប្រហែលមួយម៉ោងទៀត</translation>
 <translation id="962802172452141067">មែកធាង​ថត​ចំណាំ</translation>
+<translation id="964057662886721376">កម្មវិធី​បន្ថែម​មួយចំនួន​អាច​ធ្វើឱ្យ​ដំណើរការ​យឺត ជាពិសេស​កម្មវិធី​បន្ថែម​ដែល​អ្នក​មិនមាន​បំណង​ដំឡើង​។</translation>
 <translation id="964286338916298286">អ្នកគ្រប់គ្រង IT របស់អ្នកបានបិទដំណើរការផ្តល់ជូនពិសេសរបស់ Chrome សម្រាប់ឧបករណ៍របស់អ្នក។</translation>
 <translation id="964439421054175458">{NUM_APLLICATIONS,plural, =1{កម្មវិធី}other{កម្មវិធី}}</translation>
 <translation id="965211523698323809">ផ្ញើ និង​ទទួលសារ​ជា​អក្សរពី <ph name="DEVICE_TYPE" /> របស់អ្នក។ <ph name="LINK_BEGIN" />ស្វែងយល់​បន្ថែម<ph name="LINK_END" /></translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb
index 2e28fa6..6262dceb 100644
--- a/chrome/app/resources/generated_resources_kn.xtb
+++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">ನಿಮ್ಮ ಭದ್ರತೆ ಕೀಗಾಗಿ ಪಿನ್ ನಮೂದಿಸಿ</translation>
 <translation id="457386861538956877">ಇನ್ನಷ್ಟು...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ಬ್ಲೂಟೂತ್‌ ಸಾಧನವನ್ನು ಜೋಡಿ ಮಾಡಿ</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> ಬಿತ್ತರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ.</translation>
 <translation id="4581774856936278355">Linux ಮರುಸ್ಥಾಪಿಸುತ್ತಿರುವಾಗ ದೋಷ ಸಂಭವಿಸಿದೆ</translation>
 <translation id="4582563038311694664">ಎಲ್ಲ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮರುಹೊಂದಿಸಿ</translation>
@@ -4871,7 +4870,6 @@
 <translation id="7974936243149753750">ಓವರ್‌ಸ್ಕ್ಯಾನ್</translation>
 <translation id="7978412674231730200">ಖಾಸಗಿ ಕೀಲಿ</translation>
 <translation id="7978450511781612192">ಇದು ನಿಮ್ಮ Google ಖಾತೆಗಳಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುತ್ತದೆ. ನಿಮ್ಮ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು, ಇತಿಹಾಸ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಹಾಗೂ ಹೆಚ್ಚಿನವುಗಳನ್ನು ಇನ್ನು ಮುಂದೆ ಸಿಂಕ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
-<translation id="7979036127916589816">ಸಿಂಕ್ ದೋಷ</translation>
 <translation id="7980084013673500153">ಸ್ವತ್ತು ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ವೇಗವಾದ ಬ್ರೌಸಿಂಗ್ ಮತ್ತು ಹುಡುಕಾಟಕ್ಕಾಗಿ ಪುಟಗಳನ್ನು ಮುಂಚಿತವಾಗಿ ಲೋಡ್ ಮಾಡಿ</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> ಸಲಹೆಯನ್ನು ಹುಡುಕಾಟ ಬಾಕ್ಸ್‌ನಲ್ಲಿ ನಮೂದಿಸಿ</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;ವಿಸ್ತರಣೆಗಳು</translation>
 <translation id="862727964348362408">ತಡೆಹಿಡಿಯಲಾಗಿದೆ</translation>
 <translation id="862750493060684461">CSS ಕ್ಯಾಷ್</translation>
+<translation id="8627706565932943526">ಸಿಂಕ್ ದೋಷ</translation>
 <translation id="8627795981664801467">ಸುರಕ್ಷಿತ ಸಂಪರ್ಕಗಳು ಮಾತ್ರ</translation>
 <translation id="8630903300770275248">ಮೇಲ್ವಿಚಾರಣೆಯ ಬಳಕೆದಾರರನ್ನು ಆಮದು ಮಾಡು</translation>
 <translation id="8631032106121706562">ಪೆಟಲ್ಸ್</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index 308dc90..d9ac969c 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -1103,7 +1103,7 @@
 <translation id="2534460670861217804">보안 HTTP 프록시</translation>
 <translation id="253557089021624350">프로그램 사용자 수</translation>
 <translation id="2535799430745250929">모바일 네트워크가 없습니다.</translation>
-<translation id="2537178555904266562">비밀번호 동기화 중 오류</translation>
+<translation id="2537178555904266562">비밀번호 동기화 중 오류 발생</translation>
 <translation id="2537296579376733324">모든 쿠키, 이 사이트에서만</translation>
 <translation id="2537395079978992874"><ph name="ORIGIN" />에서 다음 파일과 폴더를 보고 수정할 수 있습니다.</translation>
 <translation id="2538361623464451692">동기화 사용중지됨</translation>
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">보안 키의 PIN을 입력하세요.</translation>
 <translation id="457386861538956877">더보기...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">블루투스 기기 페어링</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />을(를) 전송할 수 없습니다.</translation>
 <translation id="4581774856936278355">Linux 복원 중 오류 발생</translation>
 <translation id="4582563038311694664">모든 설정 초기화</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">오버스캔</translation>
 <translation id="7978412674231730200">비공개 키</translation>
 <translation id="7978450511781612192">Google 계정에서 로그아웃됩니다. 북마크, 방문 기록, 비밀번호 등이 더 이상 동기화되지 않습니다.</translation>
-<translation id="7979036127916589816">동기화 오류</translation>
 <translation id="7980084013673500153">애셋 ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">더 빠른 인터넷 사용과 검색을 위해 페이지 미리 로드</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> 추천 검색어를 검색창에 추가</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">확장 프로그램(&amp;E)</translation>
 <translation id="862727964348362408">일시중지됨</translation>
 <translation id="862750493060684461">CSS 캐시</translation>
+<translation id="8627706565932943526">동기화 오류</translation>
 <translation id="8627795981664801467">보안 연결만</translation>
 <translation id="8630903300770275248">관리 대상 사용자 가져오기</translation>
 <translation id="8631032106121706562">꽃잎</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb
index 7208f49..7b34844 100644
--- a/chrome/app/resources/generated_resources_ky.xtb
+++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Коопсуздук ачкычыңыздын PIN кодун киргизиңиз</translation>
 <translation id="457386861538956877">Дагы…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth түзмөгүн жупташтыруу</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> тышкы экранга чыгарылбай жатат.</translation>
 <translation id="4581774856936278355">Linux'ту калыбына келтирүүдө ката кетти</translation>
 <translation id="4582563038311694664">Бардык жөндөөлөрдү кайра коюу</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Камтылбаган аймак</translation>
 <translation id="7978412674231730200">Жеке ачкыч</translation>
 <translation id="7978450511781612192">Сиз Google аккаунтуңуздан чыгарыласыз. Кыстармаларыңыз, таржымалыңыз, сырсөздөрүңүз жана башка жөндөөлөр мындан ары шайкештирилбейт.</translation>
-<translation id="7979036127916589816">Шайкештештирүү катасы</translation>
 <translation id="7980084013673500153">Мүлк ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Тезирээк серептөө жана издөө үчүн барактарды алдын ала жүктөп алыңыз</translation>
 <translation id="798145602633458219">Төмөнкү сунушту издөө кутучасына кошуу: <ph name="SUGGESTION_NAME" /></translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Кеңейтүүлөр</translation>
 <translation id="862727964348362408">Убактылуу токтотулду</translation>
 <translation id="862750493060684461">CSS кэши</translation>
+<translation id="8627706565932943526">Шайкештештирүү катасы</translation>
 <translation id="8627795981664801467">Коопсуз туташуулар гана</translation>
 <translation id="8630903300770275248">Көзөмөлдөнгөн колдонуучуну импорттоо</translation>
 <translation id="8631032106121706562">Гүлдүн желекчелери</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb
index 661ddeab..a49e352 100644
--- a/chrome/app/resources/generated_resources_lo.xtb
+++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">ປ້ອນ PIN ສຳລັບກະແຈຄວາມປອດໄພຂອງທ່ານ</translation>
 <translation id="457386861538956877">ເພີ່ມເຕີມ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ຈັບຄູ່ອຸປະກອນ Bluetooth</translation>
 <translation id="4579581181964204535">ບໍ່ສາມາດສົ່ງສັນຍານ <ph name="HOST_NAME" /> ໄດ້.</translation>
 <translation id="4581774856936278355">ເກີດຄວາມຜິດພາດໃນຂະນະທີ່ກູ້ຄືນ Linux</translation>
 <translation id="4582563038311694664">ຕັ້ງທຸກການຕັ້ງຄ່າ​ຄືນໃໝ່</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">ສະແກນເກີນ</translation>
 <translation id="7978412674231730200">ປຸ່ມສ່ວນຕົວ</translation>
 <translation id="7978450511781612192">ນີ້ຈະນຳທ່ານອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ. ບຸກມາກ, ປະຫວັດ ແລະ ອື່ນໆອີກຂອງທ່ານຈະບໍ່ຊິ້ງຂໍ້ມູນອີກຕໍ່ໄປ.</translation>
-<translation id="7979036127916589816">ຊິງຄ໌ຜິດພາດ</translation>
 <translation id="7980084013673500153">ລະ​ຫັດຊັບ​ສິນ​: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ໂຫຼດໜ້າກ່ອນສຳລັບການທ່ອງເວັບ ແລະ ການຊອກຫາທີ່ໄວກວ່າ</translation>
 <translation id="798145602633458219">ຄັດຕິດການແນະນຳ <ph name="SUGGESTION_NAME" /> ໃສ່ກ່ອງຊອກຫາ</translation>
@@ -5314,6 +5312,7 @@
 <translation id="862542460444371744">ສ່ວນຂະຫຍາຍ</translation>
 <translation id="862727964348362408">ໂຈະແລ້ວ</translation>
 <translation id="862750493060684461">ແຄຊ໌ CSS</translation>
+<translation id="8627706565932943526">ຊິງຄ໌ຜິດພາດ</translation>
 <translation id="8627795981664801467">ການເຊື່ອມຕໍ່ທີ່ປອດໄພເທົ່ານັ້ນ</translation>
 <translation id="8630903300770275248">ນໍາເຂົ້າຜູ້ໃຊ້ທີ່ມີການຄວບຄຸມດູແລ</translation>
 <translation id="8631032106121706562">ກີບ​ດອກ</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index 3fedbdc..b4927fe 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Įveskite saugos rakto PIN kodą</translation>
 <translation id="457386861538956877">Daugiau...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">„Bluetooth“ įrenginio susiejimas</translation>
 <translation id="4579581181964204535">Nepavyko perduoti <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Atkuriant „Linux“ įvyko klaida</translation>
 <translation id="4582563038311694664">Nustatyti visus nustatymus iš naujo</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Sritis aplink vaizdo kraštus</translation>
 <translation id="7978412674231730200">Asmeninis raktas</translation>
 <translation id="7978450511781612192">Atlikę šį veiksmą būsite atjungti nuo „Google“ paskyrų. Žymės, istorija, slaptažodžiai ir kt. nebebus sinchronizuojama.</translation>
-<translation id="7979036127916589816">Sinchronizavimo klaida</translation>
 <translation id="7980084013673500153">Ištekliaus ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Iš anksto įkelti puslapius, kad naršymo ir paieškos procesai vyktų greičiau</translation>
 <translation id="798145602633458219">Pridėti pasiūlymą „<ph name="SUGGESTION_NAME" />“ prie paieškos laukelio</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;Plėtiniai</translation>
 <translation id="862727964348362408">Laikinai sustabdyta</translation>
 <translation id="862750493060684461">CSS talpykla</translation>
+<translation id="8627706565932943526">Sinchronizavimo klaida</translation>
 <translation id="8627795981664801467">Tik saugus ryšys</translation>
 <translation id="8630903300770275248">Importuoti prižiūrimą naudotoją</translation>
 <translation id="8631032106121706562">Vainiklapiai</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb
index 1c2eaee..50d9f48c 100644
--- a/chrome/app/resources/generated_resources_lv.xtb
+++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Ievadiet drošības atslēgas PIN</translation>
 <translation id="457386861538956877">Vēl...</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth ierīces savienošana pārī</translation>
 <translation id="4579581181964204535">Nevar apraidīt <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Linux atjaunošanas kļūda</translation>
 <translation id="4582563038311694664">Atiestatīt visus iestatījumus</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Attēla izvērse</translation>
 <translation id="7978412674231730200">Privātā atslēga</translation>
 <translation id="7978450511781612192">Tādējādi tiksiet izrakstīsiet no sava Google konta. Jūsu grāmatzīmes, vēsture, paroles, kā arī cita informācija vairs netiks sinhronizēta.</translation>
-<translation id="7979036127916589816">Sinhronizācijas kļūda</translation>
 <translation id="7980084013673500153">Līdzekļa ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Veikt lapu pirmsielādi, lai paātrinātu pārlūkošanu un meklēšanu</translation>
 <translation id="798145602633458219">Pievienot ieteikumu <ph name="SUGGESTION_NAME" /> meklēšanas lodziņam</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">Paplašināju&amp;mi</translation>
 <translation id="862727964348362408">Atlikts</translation>
 <translation id="862750493060684461">CSS kešatmiņa</translation>
+<translation id="8627706565932943526">Sinhronizācijas kļūda.</translation>
 <translation id="8627795981664801467">Tikai droši savienojumi</translation>
 <translation id="8630903300770275248">Importēt uzraudzīto lietotāju</translation>
 <translation id="8631032106121706562">Puķīte</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb
index caa35b8..108dbab 100644
--- a/chrome/app/resources/generated_resources_mk.xtb
+++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Внесете го PIN-кодот за вашиот безбедносен клуч</translation>
 <translation id="457386861538956877">Повеќе…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Спари уред со Bluetooth</translation>
 <translation id="4579581181964204535">Не може да се емитува <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Грешка при враќањето на Linux</translation>
 <translation id="4582563038311694664">Ресетирај ги сите поставки</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Прелевање</translation>
 <translation id="7978412674231730200">Приватен клуч</translation>
 <translation id="7978450511781612192">Ова ќе ве одјави од вашите сметки на Google. Обележувачите, историјата, лозинките и друго веќе нема да се синхронизираат.</translation>
-<translation id="7979036127916589816">Грешка при синхронизирање</translation>
 <translation id="7980084013673500153">ИД на средство: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Претходно вчитувај страници за побрзо прелистување и пребарување</translation>
 <translation id="798145602633458219">Прилепи го предлогов „<ph name="SUGGESTION_NAME" />“ во полето за пребарување</translation>
@@ -5320,6 +5318,7 @@
 <translation id="862542460444371744">&amp;Наставки</translation>
 <translation id="862727964348362408">Суспендирано</translation>
 <translation id="862750493060684461">CSS кеш</translation>
+<translation id="8627706565932943526">Грешка при синхронизирање</translation>
 <translation id="8627795981664801467">Само безбедни врски</translation>
 <translation id="8630903300770275248">Увези надгледуван корисник</translation>
 <translation id="8631032106121706562">Цвеќе</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index f9d34088..d99eac0 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -2506,7 +2506,6 @@
 <translation id="4572779512957829735">നിങ്ങളുടെ സുരക്ഷാ കോഡിനുള്ള പിൻ നൽകുക</translation>
 <translation id="457386861538956877">കൂടുതൽ‍‌...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth ഉപകരണം ജോടിയാക്കുക</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> കാസ്‌റ്റ് ചെയ്യാനാവുന്നില്ല.</translation>
 <translation id="4581774856936278355">Linux പുനഃസ്ഥാപിക്കുന്നതിൽ പിശക്</translation>
 <translation id="4582563038311694664">എല്ലാ ക്രമീകരണങ്ങളും റീസെറ്റ് ചെയ്യുക</translation>
@@ -4835,7 +4834,6 @@
 <translation id="7974936243149753750">ഓവർസ്‌കാൻ</translation>
 <translation id="7978412674231730200">സ്വകാര്യ കീ</translation>
 <translation id="7978450511781612192">ഇത് നിങ്ങളെ Google അക്കൗണ്ടുകളിൽ നിന്ന് സൈൻ ഔട്ട് ചെയ്യിക്കും. നിങ്ങളുടെ ബുക്ക്‌മാർക്കുകൾ, ചരിത്രം, പാ‌സ്‌വേഡുകൾ എന്നിവയും മറ്റും ഇനിയങ്ങോട്ട് സമന്വയിക്കില്ല.</translation>
-<translation id="7979036127916589816">സമന്വയ പിശക്</translation>
 <translation id="7980084013673500153">അസറ്റ് ഐഡി: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">കൂടുതൽ വേഗത്തിൽ ബ്രൗസ് ചെയ്യാനും തിരയാനും പേജുകൾ റീലോഡ് ചെയ്യുക</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> നിർദ്ദേശം സെർച്ച് ബോക്‌സിലേക്ക് ചേർക്കുക</translation>
@@ -5281,6 +5279,7 @@
 <translation id="862542460444371744">&amp;വിപുലീകരണങ്ങള്‍</translation>
 <translation id="862727964348362408">താൽക്കാലികമായി നിർത്തി</translation>
 <translation id="862750493060684461">CSS കാഷേ</translation>
+<translation id="8627706565932943526">സമന്വയ പിശക്</translation>
 <translation id="8627795981664801467">കണക്ഷനുകള്‍ മാത്രം സുരക്ഷിതമാക്കുക</translation>
 <translation id="8630903300770275248">മേൽനോട്ടത്തിലുള്ള ഉപയോക്താവിനെ ഇമ്പോർട്ട് ചെയ്യുക</translation>
 <translation id="8631032106121706562">പെറ്റൽസ്</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb
index 6b2e08a..4e7f673 100644
--- a/chrome/app/resources/generated_resources_mn.xtb
+++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -2523,7 +2523,6 @@
 <translation id="4572779512957829735">Аюулгүй байдлын түлхүүрээ ашиглахын тулд ПИН-ээ оруулна уу</translation>
 <translation id="457386861538956877">Илүү ихийг ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth төхөөрөмж холбох</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />-д дамжуулах боломжгүй.</translation>
 <translation id="4581774856936278355">Linux-г сэргээхэд алдаа гарлаа</translation>
 <translation id="4582563038311694664">Бүх тохиргоог дахин тохируулах</translation>
@@ -4862,7 +4861,6 @@
 <translation id="7974936243149753750">Дэлгэцийн дүрсийг бүтнээр нь гаргахгүй байх</translation>
 <translation id="7978412674231730200">Хувийн түлхүүр</translation>
 <translation id="7978450511781612192">Энэ нь таныг Google Бүртгэлүүдээс тань гаргах болно. Таны хавчуурга, түүх, нууц үгнүүд болон бусад зүйлийг синк хийхээ зогсооно.</translation>
-<translation id="7979036127916589816">Sync алдаа</translation>
 <translation id="7980084013673500153">Хөрөнгийн ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Хурдан хөтлөх болон хайхын тулд хуудсыг урьдчилан ачаалах</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> зөвлөмжийг хайх хэсэгт нэмэх</translation>
@@ -5308,6 +5306,7 @@
 <translation id="862542460444371744">&amp; Өргөтгөлүүд</translation>
 <translation id="862727964348362408">Түр саатуулсан</translation>
 <translation id="862750493060684461">CSS-ийн кэш</translation>
+<translation id="8627706565932943526">Sync алдаа</translation>
 <translation id="8627795981664801467">Зөвхөн аюулгүй холболтууд</translation>
 <translation id="8630903300770275248">Хяналт бүхий хэрэглэгчийг оруулах</translation>
 <translation id="8631032106121706562">Petals</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb
index 8f65c11..65ae0d4 100644
--- a/chrome/app/resources/generated_resources_mr.xtb
+++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -2508,7 +2508,6 @@
 <translation id="4572779512957829735">तुमच्या सिक्युरिटी कीसाठी पिन एंटर करा</translation>
 <translation id="457386861538956877">अधिक...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ब्लूटूथ डिव्हाइस जोडा</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> कास्ट करण्यात अक्षम.</translation>
 <translation id="4581774856936278355">Linux रिस्टोअर करताना एरर आली</translation>
 <translation id="4582563038311694664">सर्व सेटिंग्ज रीसेट करा</translation>
@@ -4834,7 +4833,6 @@
 <translation id="7974936243149753750">ओव्हरस्कॅन</translation>
 <translation id="7978412674231730200">खाजगी की</translation>
 <translation id="7978450511781612192">हे तुम्हाला तुमच्या Google खात्यामधून साइन आउट करेल. तुमचे बुकमार्क, इतिहास, पासवर्ड आणि बरेच काही आता सिंक होणार नाही.</translation>
-<translation id="7979036127916589816">सिंक एरर</translation>
 <translation id="7980084013673500153">मालमत्ता आयडी: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">जलद ब्राउझिंग आणि शोधाकरता पेज आधीच लोड करा</translation>
 <translation id="798145602633458219">सूचना <ph name="SUGGESTION_NAME" /> सर्च बॉक्समध्ये जोडा</translation>
@@ -5280,6 +5278,7 @@
 <translation id="862542460444371744">&amp;विस्तार</translation>
 <translation id="862727964348362408">निलंबित</translation>
 <translation id="862750493060684461">CSS कॅशे</translation>
+<translation id="8627706565932943526">संकालन एरर</translation>
 <translation id="8627795981664801467">केवळ सुरक्षित कनेक्शन</translation>
 <translation id="8630903300770275248">पर्यवेक्षित वापरकर्ता इंपोर्ट करा</translation>
 <translation id="8631032106121706562">पाकळ्या</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 07ba86a2..7c973961f 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Masukkan PIN untuk kunci keselamatan anda</translation>
 <translation id="457386861538956877">Lagi...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Gandingkan peranti Bluetooth</translation>
 <translation id="4579581181964204535">Tidak dapat menghantar <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Ralat semasa memulihkan Linux</translation>
 <translation id="4582563038311694664">Tetapkan semula semua tetapan</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Terlebih imbas</translation>
 <translation id="7978412674231730200">Kunci persendirian</translation>
 <translation id="7978450511781612192">Tindakan ini akan menyebabkan anda log keluar daripada Akaun Google anda. Penanda halaman, sejarah, kata laluan dan pelbagai lagi tidak akan disegerakkan lagi.</translation>
-<translation id="7979036127916589816">Ralat Segerak</translation>
 <translation id="7980084013673500153">ID Aset: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pramuat halaman untuk penyemakan imbas dan pencarian yang lebih cepat</translation>
 <translation id="798145602633458219">Tambahkan cadangan <ph name="SUGGESTION_NAME" /> pada kotak carian</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;Sambungan</translation>
 <translation id="862727964348362408">Digantung</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Ralat penyegerakan</translation>
 <translation id="8627795981664801467">Sambungan selamat sahaja</translation>
 <translation id="8630903300770275248">Import pengguna diselia</translation>
 <translation id="8631032106121706562">Kelopak</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb
index c711567a..aba72ee9 100644
--- a/chrome/app/resources/generated_resources_my.xtb
+++ b/chrome/app/resources/generated_resources_my.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">သင့်လုံခြုံရေးကီးအတွက် ပင်နံပါတ် ထည့်ပါ</translation>
 <translation id="457386861538956877">နောက်ထပ်...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ဘလူးတုသ်စက်ပစ္စည်းကို တွဲချိတ်ပါ</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />ကို ကာစ်တ်မလုပ်နိုင်ပါ။</translation>
 <translation id="4581774856936278355">Linux ပြန်ယူနေစဉ်တွင် အမှားဖြစ်သွားသည်</translation>
 <translation id="4582563038311694664">ဆက်တင်များ အားလုံး ပြင်ဆင်သတ်မှတ်ရန်</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">ချဲ့ခြင်း</translation>
 <translation id="7978412674231730200">ကိုယ်ပိုင် သော့</translation>
 <translation id="7978450511781612192">၎င်းသည် သင့်ကို သင်၏ 'Google အကောင့်များ' မှထွက်သွားစေမည်ဖြစ်သည်။ သင်၏ ဝဘ်လိပ်စာ၊ မှတ်တမ်း၊ စကားဝှက်နှင့် အခြားအရာများစွာတို့ကို စင့်ခ်လုပ်ထားတော့မည် မဟုတ်ပါ။</translation>
-<translation id="7979036127916589816">စင့်က် အမှား</translation>
 <translation id="7980084013673500153">ပိုင်ဆိုင်မှုပြ ID- <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ပိုမိုမြန်ဆန်စွာဖွင့်ခြင်းနှင့် ရှာဖွေခြင်းအတွက် စာမျက်နှာများကို ကြိုဖွင့်ရန်</translation>
 <translation id="798145602633458219">ရှာဖွေရန် ကွက်လပ်တွင် <ph name="SUGGESTION_NAME" /> အကြံပြုချက်ကို ဖြည့်စွက်ရန်</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">&amp;တိုးချဲ့မှုများ</translation>
 <translation id="862727964348362408">ဆိုင်းငံ့ထား</translation>
 <translation id="862750493060684461">CSS ကက်ရှ</translation>
+<translation id="8627706565932943526">စင့်က် အမှား</translation>
 <translation id="8627795981664801467">လုံခြုံသည့် ချိတ်ဆက်မှုများသာ</translation>
 <translation id="8630903300770275248">ကြီးကြပ်ခံ အသုံးပြုသူကို ရွှေ့ယူခြင်း</translation>
 <translation id="8631032106121706562">ပန်းဖူး</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index ee064c34..78a2c91 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -2525,7 +2525,6 @@
 <translation id="4572779512957829735">तपाईंको सुरक्षा साँचो प्रयोग गर्नका लागि उक्त PIN प्रविष्टि गर्नुहोस्</translation>
 <translation id="457386861538956877">थप...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ब्लुटुथ यन्त्रको जोडा बनाउनुहोस्</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> लाई cast गर्न असमर्थ।</translation>
 <translation id="4581774856936278355">Linux पुनर्स्थापना गर्ने क्रममा त्रुटि भयो</translation>
 <translation id="4582563038311694664">सबै सेटिङहरू रिसेट गर्नुहोस्</translation>
@@ -4864,7 +4863,6 @@
 <translation id="7974936243149753750">ओभरस्क्यान</translation>
 <translation id="7978412674231730200">निजी कुञ्जी</translation>
 <translation id="7978450511781612192">यस कार्यले तपाईंलाई आफ्ना Google खाताहरूबाट साइन आउट गराउने छ। तपाईंका पुस्तक चिन्ह, इतिहास, पासवर्ड र अन्य सेटिङहरू अब उप्रान्त सिंक‍ हुने छैनन्।</translation>
-<translation id="7979036127916589816">समक्रमण त्रुटि</translation>
 <translation id="7980084013673500153">सम्पत्ति ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ब्राउजिङ र खोजी कार्यलाई अझ छिटो बनाउन पृष्ठहरू पूर्वलोड गर्नुहोस्</translation>
 <translation id="798145602633458219">सुझाव <ph name="SUGGESTION_NAME" /> लाई खोज बाकसमा जोड्नुहोस्</translation>
@@ -5312,6 +5310,7 @@
 <translation id="862542460444371744">&amp;विस्तारहरू</translation>
 <translation id="862727964348362408">निलम्बित</translation>
 <translation id="862750493060684461">CSS क्यास</translation>
+<translation id="8627706565932943526">समक्रमण त्रुटि</translation>
 <translation id="8627795981664801467">सुरक्षित जडानहरू मात्र</translation>
 <translation id="8630903300770275248">निरीक्षण गरिएको प्रयोगकर्ता आयात गर्नुहोस्</translation>
 <translation id="8631032106121706562">पेटल</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index b1126817..a1b4065 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Geef de pincode van je beveiligingssleutel op</translation>
 <translation id="457386861538956877">Meer...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth-apparaat koppelen</translation>
 <translation id="4579581181964204535">Kan <ph name="HOST_NAME" /> niet casten.</translation>
 <translation id="4581774856936278355">Fout bij het herstellen van Linux</translation>
 <translation id="4582563038311694664">Alle instellingen opnieuw instellen</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Privésleutel</translation>
 <translation id="7978450511781612192">Hiermee word je uitgelogd van je Google-accounts. Onder meer je bladwijzers, geschiedenis en wachtwoorden worden niet meer gesynchroniseerd.</translation>
-<translation id="7979036127916589816">Synchronisatiefout</translation>
 <translation id="7980084013673500153">Item-ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pagina's vooraf laden voor sneller browsen en zoeken</translation>
 <translation id="798145602633458219">De suggestie <ph name="SUGGESTION_NAME" /> toevoegen aan het zoekvak</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Extensies</translation>
 <translation id="862727964348362408">Opgeschort</translation>
 <translation id="862750493060684461">CSS-cachegeheugen</translation>
+<translation id="8627706565932943526">Synchronisatiefout</translation>
 <translation id="8627795981664801467">Alleen beveiligde verbindingen</translation>
 <translation id="8630903300770275248">Gebruiker met beperkte rechten importeren</translation>
 <translation id="8631032106121706562">Madeliefje</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb
index 5ba408db..930f740 100644
--- a/chrome/app/resources/generated_resources_no.xtb
+++ b/chrome/app/resources/generated_resources_no.xtb
@@ -2524,7 +2524,6 @@
 <translation id="4572779512957829735">Skriv inn PIN-koden for sikkerhetsnøkkelen din</translation>
 <translation id="457386861538956877">Mer</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Koble til Bluetooth-enhet</translation>
 <translation id="4579581181964204535">Kunne ikke caste <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Feil under gjenoppretting av Linux</translation>
 <translation id="4582563038311694664">Tilbakestill alle innstillingene</translation>
@@ -4864,7 +4863,6 @@
 <translation id="7974936243149753750">Overskanning</translation>
 <translation id="7978412674231730200">Privatnøkkel</translation>
 <translation id="7978450511781612192">Dette logger deg av Google-kontoene dine. Bokmerkene dine, loggen din, passordene dine med mer blir ikke lenger synkronisert.</translation>
-<translation id="7979036127916589816">Feil ved synkronisering</translation>
 <translation id="7980084013673500153">Ressurs-ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Last inn sider på forhånd for raskere nettlesing og søk</translation>
 <translation id="798145602633458219">Legger til forslaget <ph name="SUGGESTION_NAME" /> i søkefeltet.</translation>
@@ -5313,6 +5311,7 @@
 <translation id="862542460444371744">&amp;Utvidelser</translation>
 <translation id="862727964348362408">Stanset</translation>
 <translation id="862750493060684461">CSS-buffer</translation>
+<translation id="8627706565932943526">Synkroniseringsfeil</translation>
 <translation id="8627795981664801467">Bare sikre tilkoblinger</translation>
 <translation id="8630903300770275248">Importér den administrerte brukeren</translation>
 <translation id="8631032106121706562">Tusenfryd</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb
index 5f72329..04f3ae9 100644
--- a/chrome/app/resources/generated_resources_or.xtb
+++ b/chrome/app/resources/generated_resources_or.xtb
@@ -2522,7 +2522,6 @@
 <translation id="4572779512957829735">ଆପଣଙ୍କର ସୁରକ୍ଷା କୀ ପାଇଁ ପିନ୍ ଲେଖନ୍ତୁ</translation>
 <translation id="457386861538956877">ଅଧିକ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସ୍ ପେୟାର୍‌ କରନ୍ତୁ</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />କୁ କାଷ୍ଟ କରିବାରେ ଅକ୍ଷମ।</translation>
 <translation id="4581774856936278355">Linux ରିଷ୍ଟୋର୍ ସମୟରେ ତ୍ରୁଟି</translation>
 <translation id="4582563038311694664">ସମସ୍ତ ସେଟିଂ ରିସେଟ୍‍ କରନ୍ତୁ</translation>
@@ -4864,7 +4863,6 @@
 <translation id="7974936243149753750">ଓଭରସ୍କାନ୍‌</translation>
 <translation id="7978412674231730200">ବ୍ୟକ୍ତିଗତ କୀ</translation>
 <translation id="7978450511781612192">ଏହା ଆପଣଙ୍କୁ Google ଆକାଉଣ୍ଟରୁ ସାଇନ୍ ଆଉଟ୍ କରିଦେବ। ଆଉ ଆପଣଙ୍କର ବୁକ୍‍ମାର୍କ, ଇତିବୃତ୍ତି, ପାସ୍‌ୱାର୍ଡ ଏବଂ ଆହୁରି ଅନେକ କିଛି ସିଙ୍କ୍ କରାଯିବ ନାହିଁ।</translation>
-<translation id="7979036127916589816">ସିଙ୍କ ତ୍ରୁଟି</translation>
 <translation id="7980084013673500153">ଆସେଟ୍ ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ଦ୍ରୁତତର ବ୍ରାଉଜିଂ ଓ ସନ୍ଧାନ ପାଇଁ ପୃଷ୍ଠା ପ୍ରିଲୋଡ୍ କରନ୍ତୁ</translation>
 <translation id="798145602633458219">ସନ୍ଧାନ ବକ୍ସ ପାଇଁ <ph name="SUGGESTION_NAME" />ରେ ପରାମର୍ଶ ଯୋଡ଼ନ୍ତୁ</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb
index 44fa30b..6c43cee 100644
--- a/chrome/app/resources/generated_resources_pa.xtb
+++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -2508,7 +2508,6 @@
 <translation id="4572779512957829735">ਆਪਣੀ ਸੁਰੱਖਿਆ ਕੁੰਜੀ ਲਈ ਪਿੰਨ ਦਾਖਲ ਕਰੋ</translation>
 <translation id="457386861538956877">ਹੋਰ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">ਬਲੂਟੁੱਥ ਡੀਵਾਈਸ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> ਨੂੰ ਕਾਸਟ ਕਰਨ ਵਿੱਚ ਅਸਮਰੱਥ।</translation>
 <translation id="4581774856936278355">Linux ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ</translation>
 <translation id="4582563038311694664">ਸਾਰੀਆਂ ਸੈਟਿੰਗਾਂ ਰੀਸੈੱਟ ਕਰੋ</translation>
@@ -4834,7 +4833,6 @@
 <translation id="7974936243149753750">ਓਵਰਸਕੈਨ</translation>
 <translation id="7978412674231730200">ਨਿੱਜੀ ਕੁੰਜੀ</translation>
 <translation id="7978450511781612192">ਇਸ ਨਾਲ ਤੁਸੀਂ ਆਪਣੇ 'Google ਖਾਤੇ' ਤੋਂ ਸਾਈਨ-ਆਊਟ ਹੋ ਜਾਵੋਗੇ। ਤੁਹਾਡੇ ਬੁੱਕਮਾਰਕ, ਇਤਿਹਾਸ, ਪਾਸਵਰਡ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਨੂੰ ਹੁਣ ਸਮਕਾਲੀਕਿਰਤ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</translation>
-<translation id="7979036127916589816">ਸਮਕਾਲੀਕਰਨ ਗੜਬੜ</translation>
 <translation id="7980084013673500153">ਸੰਪਤੀ ਆਈ.ਡੀ.: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">ਵਧੇਰੇ ਤੇਜ਼ੀ ਨਾਲ ਬ੍ਰਾਊਜ਼ਿੰਗ ਅਤੇ ਖੋਜ ਕਰਨ ਲਈ ਪੰਨੇ ਪਹਿਲਾਂ ਤੋਂ ਲੋਡ ਕਰੋ</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> ਸੁਝਾਅ ਨੂੰ ਖੋਜ ਬਾਕਸ ਦੇ ਅਖੀਰ 'ਤੇ ਸ਼ਾਮਲ ਕਰੋ</translation>
@@ -5278,6 +5276,7 @@
 <translation id="862542460444371744">&amp;ਐਕਸਟੈਂਸ਼ਨਾਂ</translation>
 <translation id="862727964348362408">ਮੁਅੱਤਲ ਕੀਤਾ</translation>
 <translation id="862750493060684461">CSS ਕੈਸ਼ੇ</translation>
+<translation id="8627706565932943526">ਸਿੰਕ ਅਸ਼ੁੱਧੀ</translation>
 <translation id="8627795981664801467">ਕੇਵਲ ਸੁਰੱਖਿਅਤ ਕਨੈਕਸ਼ਨ</translation>
 <translation id="8630903300770275248">ਨਿਗਰਾਨੀ ਕੀਤਾ ਵਰਤੋਂਕਾਰ ਆਯਾਤ ਕਰੋ</translation>
 <translation id="8631032106121706562">ਫੁੱਲ-ਪੱਤੀਆਂ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index d8fcec7..afdaba6 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Wpisz PIN klucza bezpieczeństwa</translation>
 <translation id="457386861538956877">Więcej</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Sparuj urządzenie Bluetooth</translation>
 <translation id="4579581181964204535">Nie udało się przesłać <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Błąd podczas przywracania Linuksa</translation>
 <translation id="4582563038311694664">Zresetuj wszystkie ustawienia</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Nadmiarowość obrazu</translation>
 <translation id="7978412674231730200">Klucz prywatny</translation>
 <translation id="7978450511781612192">Spowoduje to wylogowanie Cię z Twoich kont Google. Twoje zakładki, historia, hasła i inne dane przestaną być synchronizowane.</translation>
-<translation id="7979036127916589816">Błąd synchronizacji</translation>
 <translation id="7980084013673500153">Identyfikator zasobu: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Ładuj wstępnie strony, by przyspieszyć przeglądanie i wyszukiwanie</translation>
 <translation id="798145602633458219">Dodaj sugestię <ph name="SUGGESTION_NAME" /> do pola wyszukiwania</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Rozszerzenia</translation>
 <translation id="862727964348362408">Zawieszona</translation>
 <translation id="862750493060684461">Pamięć podręczna CSS</translation>
+<translation id="8627706565932943526">Błąd synchronizacji</translation>
 <translation id="8627795981664801467">Tylko bezpieczne połączenia</translation>
 <translation id="8630903300770275248">Zaimportuj użytkownika nadzorowanego</translation>
 <translation id="8631032106121706562">Płatki</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb
index d627a33..5a6639ee 100644
--- a/chrome/app/resources/generated_resources_pt-BR.xtb
+++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Insira o PIN da sua chave de segurança</translation>
 <translation id="457386861538956877">Mais...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Parear dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">Não foi possível transmitir <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Erro ao restaurar o Linux</translation>
 <translation id="4582563038311694664">Redefinir todas as configurações</translation>
@@ -4871,7 +4870,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Chave privada</translation>
 <translation id="7978450511781612192">Isso desconectará você das suas Contas do Google. Seus favoritos, histórico, senhas e outras configurações não serão mais sincronizados.</translation>
-<translation id="7979036127916589816">Erro de sincronização</translation>
 <translation id="7980084013673500153">Código do recurso: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pré-carregar páginas para possibilitar navegação e pesquisa mais rápidas</translation>
 <translation id="798145602633458219">Anexar a sugestão <ph name="SUGGESTION_NAME" /> à caixa de pesquisa</translation>
@@ -5320,6 +5318,7 @@
 <translation id="862542460444371744">&amp;Extensões</translation>
 <translation id="862727964348362408">Em suspensão</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Erro de sincronização</translation>
 <translation id="8627795981664801467">Somente conexões seguras</translation>
 <translation id="8630903300770275248">Importar usuário supervisionado</translation>
 <translation id="8631032106121706562">Bem-me-quer</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb
index b41e8f8..52ada072 100644
--- a/chrome/app/resources/generated_resources_pt-PT.xtb
+++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Introduza o PIN para a sua chave de segurança.</translation>
 <translation id="457386861538956877">Mais...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Sincronizar dispositivo Bluetooth</translation>
 <translation id="4579581181964204535">Não é possível transmitir <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Erro ao restaurar o Linux</translation>
 <translation id="4582563038311694664">Repor todas as definições</translation>
@@ -4870,7 +4869,6 @@
 <translation id="7974936243149753750">Overscan</translation>
 <translation id="7978412674231730200">Chave privada</translation>
 <translation id="7978450511781612192">Deste modo, termina sessão nas suas Contas Google. Os marcadores, o histórico, as palavras-passe e muito mais deixam de ser sincronizados.</translation>
-<translation id="7979036127916589816">Erro de sincronização</translation>
 <translation id="7980084013673500153">ID do recurso: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pré-carregar as páginas para uma navegação e uma pesquisa mais rápidas</translation>
 <translation id="798145602633458219">Anexar a sugestão <ph name="SUGGESTION_NAME" /> à caixa de pesquisa</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Extensões</translation>
 <translation id="862727964348362408">Suspenso</translation>
 <translation id="862750493060684461">Cache CSS</translation>
+<translation id="8627706565932943526">Erro de sincronização</translation>
 <translation id="8627795981664801467">Apenas ligações seguras</translation>
 <translation id="8630903300770275248">Importar utilizador supervisionado</translation>
 <translation id="8631032106121706562">Pétalas</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index 89ef46a..4a8bec5d 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -503,7 +503,7 @@
 <translation id="1697150536837697295">Artă</translation>
 <translation id="1698122934742150150">Numai sesiunea incognito actuală</translation>
 <translation id="1698650002254827833">Lista de aplicații nu se poate încărca. Reîncearcă.</translation>
-<translation id="1701062906490865540">Elimină această persoană</translation>
+<translation id="1701062906490865540">Exclude această persoană</translation>
 <translation id="1703331064825191675">Nu-ți face griji în privința parolelor</translation>
 <translation id="1706586824377653884">Adăugat de administrator</translation>
 <translation id="1706625117072057435">Niveluri de zoom</translation>
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Introdu codul PIN pentru cheia de securitate</translation>
 <translation id="457386861538956877">Mai multe...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Asociază dispozitivul Bluetooth</translation>
 <translation id="4579581181964204535">Nu se poate proiecta <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Eroare la restabilirea Linux</translation>
 <translation id="4582563038311694664">Restabilește toate setările</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Suprascanare</translation>
 <translation id="7978412674231730200">Cheie privată</translation>
 <translation id="7978450511781612192">Astfel, te vei deconecta de la Conturile Google. Marcajele, istoricul, parolele și alte setări nu vor mai fi sincronizate.</translation>
-<translation id="7979036127916589816">Eroare de sincronizare</translation>
 <translation id="7980084013673500153">ID articol: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Preîncarcă paginile pentru navigare și căutare mai rapide</translation>
 <translation id="798145602633458219">Atașează sugestia <ph name="SUGGESTION_NAME" /> la caseta de căutare</translation>
@@ -5042,7 +5040,7 @@
 <translation id="8213449224684199188">Modul foto a fost activat</translation>
 <translation id="8213577208796878755">Încă un dispozitiv disponibil.</translation>
 <translation id="8214489666383623925">Deschide fișierul...</translation>
-<translation id="8214962590150211830">Elimină această persoană</translation>
+<translation id="8214962590150211830">Exclude această persoană</translation>
 <translation id="8215295261562449873">Fă backup aplicațiilor și fișierelor în dosarul Descărcări înainte să faci upgrade la Linux.</translation>
 <translation id="8217399928341212914">Blocați în continuare descărcarea automată a mai multor fișiere</translation>
 <translation id="8221491193165283816">De obicei blochezi notificările. Ca să-i permiți acestui site să îți trimită notificări, dă clic aici.</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Extensii</translation>
 <translation id="862727964348362408">Suspendat</translation>
 <translation id="862750493060684461">Memorie cache CSS</translation>
+<translation id="8627706565932943526">Eroare de sincronizare</translation>
 <translation id="8627795981664801467">Numai conexiuni sigure</translation>
 <translation id="8630903300770275248">Importați un utilizator monitorizat</translation>
 <translation id="8631032106121706562">Petale</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index 3e5e94f..a82431d 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">Введите PIN-код для электронного ключа.</translation>
 <translation id="457386861538956877">Ещё...</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Подключение устройства Bluetooth</translation>
 <translation id="4579581181964204535">Трансляция с сайта <ph name="HOST_NAME" /> невозможна</translation>
 <translation id="4581774856936278355">Не удалось восстановить данные Linux</translation>
 <translation id="4582563038311694664">Сбросить все настройки</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">Каемка экрана</translation>
 <translation id="7978412674231730200">Закрытый ключ</translation>
 <translation id="7978450511781612192">Вы выйдете из аккаунта Google. Закладки, история, пароли и другие параметры перестанут синхронизироваться с ним.</translation>
-<translation id="7979036127916589816">Ошибка синхронизации</translation>
 <translation id="7980084013673500153">Идентификатор объекта: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Разрешить предзагрузку страниц для повышения скорости работы браузера и поиска</translation>
 <translation id="798145602633458219">Добавить подсказку "<ph name="SUGGESTION_NAME" />" в окно поиска</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">Расширения</translation>
 <translation id="862727964348362408">Приостановлено</translation>
 <translation id="862750493060684461">Кеш CSS</translation>
+<translation id="8627706565932943526">Ошибка синхронизации</translation>
 <translation id="8627795981664801467">только при защищенном подключении</translation>
 <translation id="8630903300770275248">Импортировать контролируемый профиль</translation>
 <translation id="8631032106121706562">Цветок</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb
index a0c4706..93347691 100644
--- a/chrome/app/resources/generated_resources_si.xtb
+++ b/chrome/app/resources/generated_resources_si.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">ඔබේ ආරක්‍ෂක යතුර සඳහා රහස් අංකය ඇතුළත් කරන්න</translation>
 <translation id="457386861538956877">තව...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">බ්ලූටූත් උපාංගය යුගල කරන්න</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> විකාශය කිරීමට නොහැකිය.</translation>
 <translation id="4581774856936278355">ලිනක්ස් ප්‍රතිසාධන කරන විට දෝෂයක් සිදු විය</translation>
 <translation id="4582563038311694664">සියලු සැකසුම් යළි සකසන්න</translation>
@@ -4865,7 +4864,6 @@
 <translation id="7974936243149753750">ඕවර්ස්කෑන්</translation>
 <translation id="7978412674231730200">පුද්ගලික යතුර</translation>
 <translation id="7978450511781612192">මෙය ඔබව ඔබේ Google ගිණුම්වලින් වරනු ඇත. ඔබගේ පිටුසන්, ඉතිහාසය, මුරපද සහ තවත් දේ තව දුරටත් සමමුහුර්ත නොවනු ඇත.</translation>
-<translation id="7979036127916589816">සමමුහුර්ත දෝෂයකි</translation>
 <translation id="7980084013673500153">වත්කම් ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">වේගවත් බ්‍රවුස් කිරීම සහ සෙවීම සඳහා පිටු පෙර පූරණය කරන්න</translation>
 <translation id="798145602633458219">යෝජනාව <ph name="SUGGESTION_NAME" /> සෙවුම් පෙට්ටියට එකුත කරන්න</translation>
@@ -5313,6 +5311,7 @@
 <translation id="862542460444371744">දිගු (&amp;E)</translation>
 <translation id="862727964348362408">අත්හිටුවන ලදි</translation>
 <translation id="862750493060684461">CSS කෑශ්</translation>
+<translation id="8627706565932943526">සම්මුහු දෝශයක්</translation>
 <translation id="8627795981664801467">ආරක්ෂිත සබඳතා පමණි</translation>
 <translation id="8630903300770275248">අධීක්ෂණය කළ පරිශීලක ආයාත කරන්න</translation>
 <translation id="8631032106121706562">පෙති</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index 27e6389..589de89 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">Zadajte kód PIN bezpečnostného kľúča</translation>
 <translation id="457386861538956877">Viac...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Párovanie zariadenia Bluetooth</translation>
 <translation id="4579581181964204535">Nie je možné prenášať hostiteľskú službu <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Chyba pri obnovovaní systému Linux</translation>
 <translation id="4582563038311694664">Resetovať všetky nastavenia</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Presah obsahu</translation>
 <translation id="7978412674231730200">Súkromný kľúč</translation>
 <translation id="7978450511781612192">Táto možnosť vás odhlási z účtov Google. Záložky, história, heslá a ďalší obsah sa prestanú synchronizovať.</translation>
-<translation id="7979036127916589816">Chyba synchronizácie</translation>
 <translation id="7980084013673500153">ID prvku: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Vopred načítavať stránky na zrýchlenie prehliadania a vyhľadávania</translation>
 <translation id="798145602633458219">Pripojiť návrh <ph name="SUGGESTION_NAME" /> k výrazu vo vyhľadávacom poli</translation>
@@ -5316,6 +5314,7 @@
 <translation id="862542460444371744">&amp;Rozšírenia</translation>
 <translation id="862727964348362408">Pozastavené</translation>
 <translation id="862750493060684461">Vyrovnávacia pamäť CSS</translation>
+<translation id="8627706565932943526">Chyba synchronizácie</translation>
 <translation id="8627795981664801467">Len bezpečné pripojenia</translation>
 <translation id="8630903300770275248">Importovať kontrolovaného používateľa</translation>
 <translation id="8631032106121706562">Lupienky</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index a349c977..f5829bc 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Vnesite kodo PIN za varnostni ključ</translation>
 <translation id="457386861538956877">Več ...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Seznanitev naprave Bluetooth</translation>
 <translation id="4579581181964204535">Ni mogoče predvajati <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Napaka pri obnavljanju Linuxa</translation>
 <translation id="4582563038311694664">Ponastavi vse nastavitve</translation>
@@ -4871,7 +4870,6 @@
 <translation id="7974936243149753750">Upodabljanje čez rob zaslona</translation>
 <translation id="7978412674231730200">Zasebni ključ</translation>
 <translation id="7978450511781612192">S tem boste odjavljeni iz Google Računov. Zaznamki, zgodovina, gesla in drugi podatki ne bodo več sinhronizirani.</translation>
-<translation id="7979036127916589816">Sinhronizacijska napaka</translation>
 <translation id="7980084013673500153">ID sredstva: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Vnaprejšnje nalaganje strani zaradi hitrejšega brskanja in iskanja</translation>
 <translation id="798145602633458219">Pripni predlog <ph name="SUGGESTION_NAME" /> iskalnemu polju</translation>
@@ -5320,6 +5318,7 @@
 <translation id="862542460444371744">&amp;Razširitve</translation>
 <translation id="862727964348362408">Onemogočeno</translation>
 <translation id="862750493060684461">Predpomnilnik CSS</translation>
+<translation id="8627706565932943526">Napaka pri sinhronizaciji</translation>
 <translation id="8627795981664801467">Samo varne povezave</translation>
 <translation id="8630903300770275248">Uvoz zaščitenega uporabnika</translation>
 <translation id="8631032106121706562">Rožica</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb
index caf2065..c61a662 100644
--- a/chrome/app/resources/generated_resources_sq.xtb
+++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Fut kodin PIN për çelësin e sigurisë</translation>
 <translation id="457386861538956877">Më shumë...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Çifto pajisje me "Bluetooth"</translation>
 <translation id="4579581181964204535">Nuk mund të transmetojë <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Gabim gjatë restaurimit të Linux</translation>
 <translation id="4582563038311694664">Rivendos të gjitha cilësimet</translation>
@@ -4865,7 +4864,6 @@
 <translation id="7974936243149753750">Kapërcimi i ekranit</translation>
 <translation id="7978412674231730200">Çelës privat</translation>
 <translation id="7978450511781612192">Kjo do të të nxjerrë nga llogaritë e Google. Faqeshënuesit, historiku, fjalëkalimet dhe shumë të tjera nuk do të sinkronizohen më.</translation>
-<translation id="7979036127916589816">Gabim në sinkronizim</translation>
 <translation id="7980084013673500153">ID-ja e punës: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Ngarkoji paraprakisht faqet për shfletim dhe kërkim më të shpejtë</translation>
 <translation id="798145602633458219">Bashkëngjite sugjerimin <ph name="SUGGESTION_NAME" /> te kutia e kërkimit</translation>
@@ -5313,6 +5311,7 @@
 <translation id="862542460444371744">&amp;Shtesat</translation>
 <translation id="862727964348362408">Pezulluar</translation>
 <translation id="862750493060684461">Memoria specifike e CSS-së</translation>
+<translation id="8627706565932943526">Gabim në sinkronizim</translation>
 <translation id="8627795981664801467">Siguro vetëm lidhjet.</translation>
 <translation id="8630903300770275248">Importo përdorues të kontrolluar</translation>
 <translation id="8631032106121706562">Petale</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index 05ee7bb9..376c9a6 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Унесите PIN за безбедносни кључ</translation>
 <translation id="457386861538956877">Још...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Упарите Bluetooth уређај</translation>
 <translation id="4579581181964204535">Није успело пребацивање за <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Грешка при враћању Linux-а</translation>
 <translation id="4582563038311694664">Ресетуј сва подешавања</translation>
@@ -4868,7 +4867,6 @@
 <translation id="7974936243149753750">Ивично подручје екрана</translation>
 <translation id="7978412674231730200">Приватни кључ</translation>
 <translation id="7978450511781612192">Овим ћете се одјавити са Google налога. Обележивачи, историја, лозинке и додатни садржај се више неће синхронизовати.</translation>
-<translation id="7979036127916589816">Грешка у синхронизацији</translation>
 <translation id="7980084013673500153">ИД елемента: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Странице се учитавају унапред ради бржег прегледања и претраживања</translation>
 <translation id="798145602633458219">Додај предлог <ph name="SUGGESTION_NAME" /> у оквир за претрагу</translation>
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Додаци</translation>
 <translation id="862727964348362408">Обустављено</translation>
 <translation id="862750493060684461">CSS кеш</translation>
+<translation id="8627706565932943526">Грешка при синхронизацији</translation>
 <translation id="8627795981664801467">Само безбедне везе</translation>
 <translation id="8630903300770275248">Увези корисника под надзором</translation>
 <translation id="8631032106121706562">Латице</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb
index 2be70c6a..26253d7 100644
--- a/chrome/app/resources/generated_resources_sv.xtb
+++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Ange säkerhetsnyckelns pinkod</translation>
 <translation id="457386861538956877">Mer...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Koppla Bluetooth-enhet</translation>
 <translation id="4579581181964204535">Det gick inte att casta <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Ett fel uppstod när Linux skulle återställas</translation>
 <translation id="4582563038311694664">Återställ alla inställningar</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Överskanning</translation>
 <translation id="7978412674231730200">Privat nyckel</translation>
 <translation id="7978450511781612192">Du loggas ut från dina Google-konton. Bokmärken, historik, lösenord och annan information synkroniseras inte längre.</translation>
-<translation id="7979036127916589816">Synkroniseringsfel</translation>
 <translation id="7980084013673500153">Tillgångs-id: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Läs in sidor i förväg så att det går snabbare att surfa och söka</translation>
 <translation id="798145602633458219">Lägg till förslaget <ph name="SUGGESTION_NAME" /> sist i sökrutan</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Tillägg</translation>
 <translation id="862727964348362408">Tillfälligt avstängd</translation>
 <translation id="862750493060684461">CSS-cacheminne</translation>
+<translation id="8627706565932943526">Synkroniseringsfel</translation>
 <translation id="8627795981664801467">Endast säkra anslutningar</translation>
 <translation id="8630903300770275248">Importera hanterad användare</translation>
 <translation id="8631032106121706562">Blomster</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb
index b22761eb..53f0acc 100644
--- a/chrome/app/resources/generated_resources_sw.xtb
+++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -2524,7 +2524,6 @@
 <translation id="4572779512957829735">Weka PIN kwa ya ufunguo wako wa usalama</translation>
 <translation id="457386861538956877">Zaidi...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Oanisha kifaa cha Bluetooth</translation>
 <translation id="4579581181964204535">Haijatuma <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Hitilafu imetokea wakati wa kurejesha Linux</translation>
 <translation id="4582563038311694664">Weka upya mipangilio yote</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">Angalia kwa ujumla</translation>
 <translation id="7978412674231730200">Ufunguo binafsi</translation>
 <translation id="7978450511781612192">Hatua hii itakuondoa kwenye Akaunti za Google. Alamisho, historia, manenosiri yako na mengineyo hayatasawazishwa tena.</translation>
-<translation id="7979036127916589816">Hitilafu ya Usawazishaji</translation>
 <translation id="7980084013673500153">Kitambulisho cha Kipengee: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Pakia mapema kurasa ili upate huduma ya haraka ya kuvinjari na kutafuta</translation>
 <translation id="798145602633458219">Weka pendekezo la <ph name="SUGGESTION_NAME" /> kwenye kisanduku cha kutafutia</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">Vi&amp;endelezi</translation>
 <translation id="862727964348362408">Imesitishwa</translation>
 <translation id="862750493060684461">Akiba ya CSS</translation>
+<translation id="8627706565932943526">Hitilafu ya usawazishaji</translation>
 <translation id="8627795981664801467">Miunganisho salama pekee</translation>
 <translation id="8630903300770275248">Ingiza mtumiaji anayesimamiwa</translation>
 <translation id="8631032106121706562">Petali</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb
index eba89ea..ad993af 100644
--- a/chrome/app/resources/generated_resources_ta.xtb
+++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -2510,7 +2510,6 @@
 <translation id="4572779512957829735">உங்கள் பாதுகாப்பு விசைக்கான பின்னை உள்ளிடவும்</translation>
 <translation id="457386861538956877">மேலும்...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">புளூடூத் சாதனத்தை இணை</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />ஐ அலைபரப்ப முடியவில்லை.</translation>
 <translation id="4581774856936278355">Linuxசை மீட்டமைக்கும் பொழுது பிழை நேர்ந்தது</translation>
 <translation id="4582563038311694664">எல்லா அமைப்புகளையும் மீட்டமை</translation>
@@ -4838,7 +4837,6 @@
 <translation id="7974936243149753750">ஓவர்ஸ்கேன்</translation>
 <translation id="7978412674231730200">தனிப்பட்ட விசை</translation>
 <translation id="7978450511781612192">உங்கள் Google கணக்குகளிலிருந்து வெளியேற்றப்படுவீர்கள். இனி உங்கள் புக்மார்க்குகள், வரலாறு, கடவுச்சொற்கள் மற்றும் பிற அமைப்புகள் ஒத்திசைக்கப்படாது.</translation>
-<translation id="7979036127916589816">ஒத்திசைவு பிழை</translation>
 <translation id="7980084013673500153">பண்புக்கூறு ஐடி: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">மிக விரைவான உலாவலுக்காகவும் தேடலிற்காகவும் பக்கங்களை முன்னதாக ஏற்றும்</translation>
 <translation id="798145602633458219">தேடல் பெட்டியில் <ph name="SUGGESTION_NAME" /> பரிந்துரையைச் சேர்க்கும்</translation>
@@ -5284,6 +5282,7 @@
 <translation id="862542460444371744">&amp;நீட்சிகள்</translation>
 <translation id="862727964348362408">இடைநீக்கப்பட்டது</translation>
 <translation id="862750493060684461">CSS தற்காலிக சேமிப்பு</translation>
+<translation id="8627706565932943526">ஒத்திசைவு பிழை</translation>
 <translation id="8627795981664801467">பாதுகாப்பான இணைப்புகள் மட்டும்</translation>
 <translation id="8630903300770275248">மேற்பார்வையிடப்படும் பயனரை இறக்குமதிசெய்</translation>
 <translation id="8631032106121706562">பெட்டல்ஸ்</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb
index c8e1f3f..e128c1e 100644
--- a/chrome/app/resources/generated_resources_te.xtb
+++ b/chrome/app/resources/generated_resources_te.xtb
@@ -2528,7 +2528,6 @@
 <translation id="4572779512957829735">మీ సెక్యూరిటీ కీ కోసం పిన్‌ని నమోదు చేయండి</translation>
 <translation id="457386861538956877">మరిన్ని...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">బ్లూటూత్ పరికరాన్ని జత చేయండి</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" />ని ప్రసారం చేయడం సాధ్యపడలేదు.</translation>
 <translation id="4581774856936278355">Linuxని పునరుద్ధరిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది</translation>
 <translation id="4582563038311694664">అన్ని సెట్టింగ్‌లను రీసెట్ చేయి</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">ఓవర్‌స్కాన్ సర్దుబాటు</translation>
 <translation id="7978412674231730200">వ్యక్తిగత కీ</translation>
 <translation id="7978450511781612192">ఇది మిమ్మల్ని మీ Google ఖాతాల నుండి సైన్ అవుట్ చేస్తుంది. మీ బుక్‌మార్క్‌లు, చరిత్ర, పాస్‌వర్డ్‌లు మరియు మరిన్ని ఇకపై సమకాలీకరించబడవు.</translation>
-<translation id="7979036127916589816">సింక్ ఎర్రర్</translation>
 <translation id="7980084013673500153">అసెట్ ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">వేగవంతమైన బ్రౌజింగ్ మరియు శోధన కోసం పేజీలను ముందస్తుగా లోడ్ చేస్తుంది</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> సూచనను శోధన పెట్టెకు అనుబంధించండి</translation>
@@ -5313,6 +5311,7 @@
 <translation id="862542460444371744">&amp;పొడిగింపులు</translation>
 <translation id="862727964348362408">తాత్కాలికంగా రద్దు చేయబడింది</translation>
 <translation id="862750493060684461">CSS కాష్</translation>
+<translation id="8627706565932943526">సమకాలీకరణ లోపం</translation>
 <translation id="8627795981664801467">సురక్షిత కనెక్షన్‌ల మాత్రమే</translation>
 <translation id="8630903300770275248">పర్యవేక్షించబడే వినియోగదారును దిగుమతి చేయి</translation>
 <translation id="8631032106121706562">పూరేకులు</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb
index 2d435aae..fea9b74f 100644
--- a/chrome/app/resources/generated_resources_th.xtb
+++ b/chrome/app/resources/generated_resources_th.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">ป้อน PIN ของคีย์ความปลอดภัย</translation>
 <translation id="457386861538956877">เพิ่มเติม...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">จับคู่อุปกรณ์บลูทูธ</translation>
 <translation id="4579581181964204535">ไม่สามารถแคสต์ <ph name="HOST_NAME" /></translation>
 <translation id="4581774856936278355">เกิดข้อผิดพลาดขณะคืนค่า Linux</translation>
 <translation id="4582563038311694664">รีเซ็ตการตั้งค่าทั้งหมด</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">โอเวอร์สแกน</translation>
 <translation id="7978412674231730200">กุญแจส่วนตัว</translation>
 <translation id="7978450511781612192">การดำเนินการนี้จะนำคุณออกจากบัญชี Google บุ๊กมาร์ก ประวัติการเข้าชม รหัสผ่าน และข้อมูลอื่นๆ จะไม่ซิงค์อีกต่อไป</translation>
-<translation id="7979036127916589816">เกิดข้อผิดพลาดในการทำให้ข้อมูลตรงกัน</translation>
 <translation id="7980084013673500153">รหัสเนื้อหา: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">โหลดหน้าเว็บล่วงหน้าเพื่อให้เรียกดูและค้นหาได้เร็วขึ้น</translation>
 <translation id="798145602633458219">เพิ่มคำแนะนำ <ph name="SUGGESTION_NAME" /> ต่อท้ายช่องค้นหา</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;ส่วนขยาย</translation>
 <translation id="862727964348362408">ระงับไว้ชั่วคราว</translation>
 <translation id="862750493060684461">แคช CSS</translation>
+<translation id="8627706565932943526">ข้อผิดพลาดในการซิงค์</translation>
 <translation id="8627795981664801467">สำหรับการเชื่อมต่อที่ปลอดภัยเท่านั้น</translation>
 <translation id="8630903300770275248">นำเข้าผู้ใช้ภายใต้การดูแล</translation>
 <translation id="8631032106121706562">พีทอล</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb
index 55d05580..4c1d374 100644
--- a/chrome/app/resources/generated_resources_tr.xtb
+++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Güvenlik anahtarınızın PIN'ini girin</translation>
 <translation id="457386861538956877">Diğer...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth cihazı eşle</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> yayınlanamıyor.</translation>
 <translation id="4581774856936278355">Linux geri yüklenirken hata oluştu</translation>
 <translation id="4582563038311694664">Tüm ayarları sıfırla</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Fazla tarama</translation>
 <translation id="7978412674231730200">Özel anahtar</translation>
 <translation id="7978450511781612192">Bu işlem Google hesaplarınızın oturumunu kapatacak. Yer işaretleriniz, şifreleriniz ve diğer içerikler artık senkronize edilmeyecek.</translation>
-<translation id="7979036127916589816">Senkronizasyon Hatası</translation>
 <translation id="7980084013673500153">Öğe kimliği: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Daha hızlı göz atmak ve arama yapmak için sayfaları önceden yükle</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> önerisini arama kutusuna ekle</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Uzantılar</translation>
 <translation id="862727964348362408">Askıya alındı</translation>
 <translation id="862750493060684461">CSS önbelleği</translation>
+<translation id="8627706565932943526">Senkronizasyon hatası</translation>
 <translation id="8627795981664801467">Yalnızca güvenli bağlantılar</translation>
 <translation id="8630903300770275248">Denetlenen kullanıcıyı içe aktar</translation>
 <translation id="8631032106121706562">Çiçek</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb
index ce8e5cd43..e451a54 100644
--- a/chrome/app/resources/generated_resources_uk.xtb
+++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -2529,7 +2529,6 @@
 <translation id="4572779512957829735">Введіть PIN-код для ключа безпеки</translation>
 <translation id="457386861538956877">Інші...</translation>
 <translation id="4574741712540401491">• <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Підключити пристрій Bluetooth</translation>
 <translation id="4579581181964204535">Не вдається транслювати з <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Сталася помилка під час відновлення Linux</translation>
 <translation id="4582563038311694664">Скинути всі налаштування</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Облямівка екрана</translation>
 <translation id="7978412674231730200">Секретний ключ</translation>
 <translation id="7978450511781612192">Ви вийдете з облікових записів Google. Закладки, історія, паролі тощо більше не синхронізуватимуться.</translation>
-<translation id="7979036127916589816">Помилка синхронізації</translation>
 <translation id="7980084013673500153">Ідентифікатор об’єкта: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Попередньо завантажувати сторінки, щоб швидше переглядати та шукати</translation>
 <translation id="798145602633458219">Додати пропозицію "<ph name="SUGGESTION_NAME" />" у вікно пошуку</translation>
@@ -5318,6 +5316,7 @@
 <translation id="862542460444371744">&amp;Розширення</translation>
 <translation id="862727964348362408">Призупинено</translation>
 <translation id="862750493060684461">Кеш CSS</translation>
+<translation id="8627706565932943526">Помилка синхронізації</translation>
 <translation id="8627795981664801467">Лише захищені з’єднання</translation>
 <translation id="8630903300770275248">Імпортувати контрольованого користувача</translation>
 <translation id="8631032106121706562">Ромашка</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb
index 750044a9..94ade47 100644
--- a/chrome/app/resources/generated_resources_ur.xtb
+++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -2530,7 +2530,6 @@
 <translation id="4572779512957829735">‏اپنی سیکورٹی کلید کے لئے PIN درج کریں</translation>
 <translation id="457386861538956877">مزید…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">بلوٹوتھ آلہ کا جوڑا بنائیں</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> کاسٹ کرنے سے قاصر۔</translation>
 <translation id="4581774856936278355">‏Linux کو بحال کرنے کے دوران خرابی</translation>
 <translation id="4582563038311694664">سبھی ترتیبات کو دوبارہ سیٹ کریں</translation>
@@ -4871,7 +4870,6 @@
 <translation id="7974936243149753750">اوور سکین</translation>
 <translation id="7978412674231730200">نجی کلید</translation>
 <translation id="7978450511781612192">اس سے آپ اپنے اکاؤنٹ سے سائن آؤٹ ہو جائیں گے۔ آپ کے بُک مارکس، سرگزشت، پاس ورڈز اور بھی بہت کـچھ کی اب مطابقت پذیری نہیں کی جائے گی۔</translation>
-<translation id="7979036127916589816">مطابقت پذیری کی خرابی</translation>
 <translation id="7980084013673500153">‏اثاثہ ID: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">زیادہ تیز براؤزنگ اور تلاش کرنے کے لیے صفحات پہلے سے لوڈ کر لیں</translation>
 <translation id="798145602633458219">تجویز <ph name="SUGGESTION_NAME" /> کو تلاش کے خانے میں ملحق کریں</translation>
@@ -5319,6 +5317,7 @@
 <translation id="862542460444371744">&amp;ایکسٹینشنز</translation>
 <translation id="862727964348362408">معطل</translation>
 <translation id="862750493060684461">‏CSS کیش</translation>
+<translation id="8627706565932943526">مطابقت پذیری میں خرابی</translation>
 <translation id="8627795981664801467">صرف محفوظ کنکشنز</translation>
 <translation id="8630903300770275248">تحفظ یافتہ صارف درآمد کریں</translation>
 <translation id="8631032106121706562">پنکھڑیاں</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb
index 1342dc6..a7b9f3ef 100644
--- a/chrome/app/resources/generated_resources_uz.xtb
+++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">Elektron kalit PIN kodini kiriting</translation>
 <translation id="457386861538956877">Yana...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Bluetooth qurilma ulash</translation>
 <translation id="4579581181964204535"><ph name="HOST_NAME" /> translatsiya qilinmadi.</translation>
 <translation id="4581774856936278355">Linux tiklanmadi</translation>
 <translation id="4582563038311694664">Barcha sozlamalarni dastlabki holatga qaytarish</translation>
@@ -4866,7 +4865,6 @@
 <translation id="7974936243149753750">Ekran hoshiyasi</translation>
 <translation id="7978412674231730200">Xususiy kalit</translation>
 <translation id="7978450511781612192">Google hisobingizdan chiqarilasiz. Xatcho‘p, tarix va parollaringiz boshqa sinxronlanmaydi.</translation>
-<translation id="7979036127916589816">Sinxronlash xatoligi</translation>
 <translation id="7980084013673500153">Obyekt identifikatori: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Saytlarni kezish va qidiruv tezroq bajarilishi uchun sahifalar oldindan yuklansin</translation>
 <translation id="798145602633458219"><ph name="SUGGESTION_NAME" /> taklifi qidiruv qatoriga kiritilsin</translation>
@@ -5314,6 +5312,7 @@
 <translation id="862542460444371744">&amp;Kengaytmalar</translation>
 <translation id="862727964348362408">To‘xtatib qo‘yildi</translation>
 <translation id="862750493060684461">CSS kesh</translation>
+<translation id="8627706565932943526">Sinxronlash xatoligi</translation>
 <translation id="8627795981664801467">Faqat havfsiz ulanish vaqtida</translation>
 <translation id="8630903300770275248">Kuzatuvdagi foydalanuvchini import qilish</translation>
 <translation id="8631032106121706562">Gul</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb
index f0f00d1..5c8e4a2 100644
--- a/chrome/app/resources/generated_resources_vi.xtb
+++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -2510,7 +2510,6 @@
 <translation id="4572779512957829735">Nhập mã PIN cho khóa bảo mật của bạn</translation>
 <translation id="457386861538956877">Thêm...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Ghép nối thiết bị Bluetooth</translation>
 <translation id="4579581181964204535">Không thể truyền <ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Lỗi khi khôi phục Linux</translation>
 <translation id="4582563038311694664">Đặt lại tất cả cài đặt</translation>
@@ -4837,7 +4836,6 @@
 <translation id="7974936243149753750">Quét thừa</translation>
 <translation id="7978412674231730200">Khoá cá nhân</translation>
 <translation id="7978450511781612192">Việc này này sẽ đăng xuất bạn khỏi các Tài khoản Google. Dấu trang, lịch sử, mật khẩu và các dữ liệu khác của bạn sẽ không còn đồng bộ hóa nữa.</translation>
-<translation id="7979036127916589816">Lỗi Đồng bộ hóa</translation>
 <translation id="7980084013673500153">ID phần tử: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Tải trước các trang để tìm kiếm và duyệt web nhanh hơn</translation>
 <translation id="798145602633458219">Thêm đề xuất <ph name="SUGGESTION_NAME" /> vào hộp tìm kiếm</translation>
@@ -5283,6 +5281,7 @@
 <translation id="862542460444371744">&amp;Tiện ích mở rộng</translation>
 <translation id="862727964348362408">Bị tạm ngưng</translation>
 <translation id="862750493060684461">Bộ nhớ đệm CSS</translation>
+<translation id="8627706565932943526">Lỗi đồng bộ hóa</translation>
 <translation id="8627795981664801467">Chỉ kết nối an toàn</translation>
 <translation id="8630903300770275248">Nhập người dùng được giám sát</translation>
 <translation id="8631032106121706562">Cánh hoa</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index 30da71b..a50d8f7 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -2524,7 +2524,6 @@
 <translation id="4572779512957829735">为您的安全密钥输入 PIN 码</translation>
 <translation id="457386861538956877">更多...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">配对蓝牙设备</translation>
 <translation id="4579581181964204535">无法投射 <ph name="HOST_NAME" />。</translation>
 <translation id="4581774856936278355">恢复 Linux 容器时出错</translation>
 <translation id="4582563038311694664">重置所有设置</translation>
@@ -4864,7 +4863,6 @@
 <translation id="7974936243149753750">过扫描</translation>
 <translation id="7978412674231730200">私有密钥</translation>
 <translation id="7978450511781612192">执行此操作会使您退出 Google 帐号。您的书签、历史记录、密码及其他设置将不再保持同步。</translation>
-<translation id="7979036127916589816">同步错误</translation>
 <translation id="7980084013673500153">资源 ID:<ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">预加载网页,以便实现更快速的浏览和搜索</translation>
 <translation id="798145602633458219">将“<ph name="SUGGESTION_NAME" />”这项推荐内容附加到搜索框中</translation>
@@ -5312,6 +5310,7 @@
 <translation id="862542460444371744">扩展程序(&amp;E)</translation>
 <translation id="862727964348362408">已暂停</translation>
 <translation id="862750493060684461">CSS 缓存</translation>
+<translation id="8627706565932943526">同步错误</translation>
 <translation id="8627795981664801467">仅限安全连接</translation>
 <translation id="8630903300770275248">导入受监管用户</translation>
 <translation id="8631032106121706562">花朵</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb
index 22e1210..9dad372 100644
--- a/chrome/app/resources/generated_resources_zh-HK.xtb
+++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">輸入安全密鑰的 PIN</translation>
 <translation id="457386861538956877">更多語言…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">配對藍牙裝置</translation>
 <translation id="4579581181964204535">無法投放 <ph name="HOST_NAME" />。</translation>
 <translation id="4581774856936278355">還原 Linux 時發生錯誤</translation>
 <translation id="4582563038311694664">重設所有設定</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">溢出掃描</translation>
 <translation id="7978412674231730200">私密金鑰</translation>
 <translation id="7978450511781612192">此操作會將您登出 Google 帳戶。系統將不會繼續將書籤、記錄、密碼和其他同步至您的 Google 帳戶。</translation>
-<translation id="7979036127916589816">同步功能發生錯誤</translation>
 <translation id="7980084013673500153">資產識別碼:<ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">預先載入網頁,以加快瀏覽和搜尋速度</translation>
 <translation id="798145602633458219">將「<ph name="SUGGESTION_NAME" />」呢項建議附加去搜尋框度</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">擴充功能(&amp;E)</translation>
 <translation id="862727964348362408">暫停</translation>
 <translation id="862750493060684461">CSS 快取</translation>
+<translation id="8627706565932943526">同步處理發生錯誤</translation>
 <translation id="8627795981664801467">只傳送安全性連線的 Cookie</translation>
 <translation id="8630903300770275248">匯入受管使用者</translation>
 <translation id="8631032106121706562">朵朵</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb
index 666db7fe..c946433 100644
--- a/chrome/app/resources/generated_resources_zh-TW.xtb
+++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -2527,7 +2527,6 @@
 <translation id="4572779512957829735">輸入安全金鑰的 PIN 碼</translation>
 <translation id="457386861538956877">更多…</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">配對藍牙裝置</translation>
 <translation id="4579581181964204535">無法投放 <ph name="HOST_NAME" />。</translation>
 <translation id="4581774856936278355">還原 Linux 時發生錯誤</translation>
 <translation id="4582563038311694664">重設所有設定</translation>
@@ -4867,7 +4866,6 @@
 <translation id="7974936243149753750">遮視區域</translation>
 <translation id="7978412674231730200">秘密金鑰</translation>
 <translation id="7978450511781612192">你將登出自己的 Google 帳戶。你的書籤、歷史記錄、密碼和其他設定將不再保持同步。</translation>
-<translation id="7979036127916589816">同步功能發生錯誤</translation>
 <translation id="7980084013673500153">資產 ID:<ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">預先載入網頁,以加快瀏覽及搜尋速度</translation>
 <translation id="798145602633458219">將「<ph name="SUGGESTION_NAME" />」這項建議附加到搜尋框內</translation>
@@ -5315,6 +5313,7 @@
 <translation id="862542460444371744">擴充功能(&amp;E)</translation>
 <translation id="862727964348362408">已暫停</translation>
 <translation id="862750493060684461">CSS 快取</translation>
+<translation id="8627706565932943526">同步處理發生錯誤</translation>
 <translation id="8627795981664801467">僅傳送安全性連線的 Cookie</translation>
 <translation id="8630903300770275248">匯入受監管的使用者</translation>
 <translation id="8631032106121706562">朵朵</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb
index 1de81d0..093936a 100644
--- a/chrome/app/resources/generated_resources_zu.xtb
+++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -1529,7 +1529,7 @@
 <translation id="3143515551205905069">Khansela ukuvumelanisa</translation>
 <translation id="3143754809889689516">Dlala kusukela ekuqaleni</translation>
 <translation id="3144647712221361880">Vula isixhumanisi njenge-</translation>
-<translation id="3145187901750964977">Ayikwazanga ukufaka umshini ngokubuka Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangnao yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
+<translation id="3145187901750964977">Ayikwazanga ukufaka umshini ngokubuka Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangano yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
 <translation id="3149477159749171726">Inguqulo:
     <ph name="LINUX_VERSION" />
 
@@ -1568,7 +1568,7 @@
 <translation id="3192947282887913208">Amafayela womsindo</translation>
 <translation id="3194737229810486521">I-<ph name="URL" /> ifuna ukugcina unaphakade idatha kudivayisi yakho</translation>
 <translation id="3199127022143353223">Amaseva</translation>
-<translation id="3201306578844503970">Ayikwazi ukufaka umshini wokubuka ngenxa yephutha lenethiwekhi. Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangnao yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
+<translation id="3201306578844503970">Ayikwazi ukufaka umshini wokubuka ngenxa yephutha lenethiwekhi. Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangano yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
 <translation id="3201422919974259695">Amadivayisi atholakalayo e-USB azovela lapha.</translation>
 <translation id="3202131003361292969">Indlela</translation>
 <translation id="3202173864863109533">Le thebhu yomsindo iyathuliswa.</translation>
@@ -2526,7 +2526,6 @@
 <translation id="4572779512957829735">Faka i-PIN yokhiye wakho wokuqinisekia ubunikazi</translation>
 <translation id="457386861538956877">Okuningi...</translation>
 <translation id="4574741712540401491">•  <ph name="LIST_ITEM_TEXT" /></translation>
-<translation id="4576541033847873020">Matanisa idivayisi ye-Bluetooth</translation>
 <translation id="4579581181964204535">Ayikwazi ukusakaza ku-<ph name="HOST_NAME" />.</translation>
 <translation id="4581774856936278355">Iphutha ngenkathi ibuyisa i-Linux</translation>
 <translation id="4582563038311694664">Setha kabusha zonke uzulungiselelo</translation>
@@ -4869,7 +4868,6 @@
 <translation id="7974936243149753750">Skena ngaphezulu</translation>
 <translation id="7978412674231730200">Ukhiye oyimfihlo</translation>
 <translation id="7978450511781612192">Lokhu kuzokukhipha kuwo wonke ama-akhawunti akho e-Google. Amabhukhimakhi akho, umlando, amaphasiwedi, nokuningi ngeke kusavumelaniswa.</translation>
-<translation id="7979036127916589816">Iphutha lokuvumelanisa</translation>
 <translation id="7980084013673500153">I-ID yefa: <ph name="ASSET_ID" /></translation>
 <translation id="7981313251711023384">Layisha ngaphambili amakhasi ukuze uphequlule ngokuphephile uphinde useshe</translation>
 <translation id="798145602633458219">Namathisela isiphakamiso <ph name="SUGGESTION_NAME" /> ebhokisini losesho</translation>
@@ -4881,7 +4879,7 @@
 <translation id="7987814697832569482">Njalo xhuma ngale VPN</translation>
 <translation id="7988355189918024273">Nika amandla izici zokufinyeleleka</translation>
 <translation id="7991296728590311172">Izilungiselelo zokufinyelela zeswishi</translation>
-<translation id="7994350303002908848">Ayikwazanga ukufaka i-Plugin VM. Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangnao yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
+<translation id="7994350303002908848">Ayikwazanga ukufaka i-Plugin VM. Sicela uzame, noma uxhumane nomlawuli wedivayisi wenhlangano yakho. Ikhodi yephutha: <ph name="ERROR_CODE" />.</translation>
 <translation id="7994702968232966508">Indlela ye-EAP</translation>
 <translation id="7997826902155442747">Ukukhetha kwenqubo</translation>
 <translation id="7999229196265990314">Idale amafayela alandelayo:
@@ -5317,6 +5315,7 @@
 <translation id="862542460444371744">&amp;Izandiso</translation>
 <translation id="862727964348362408">Kumiswe okwesikhashana</translation>
 <translation id="862750493060684461">Inqolobane ye-CSS</translation>
+<translation id="8627706565932943526">Iphutha lokuvumelanisa</translation>
 <translation id="8627795981664801467">Ukuxhumeka okuvikelekile kuphela</translation>
 <translation id="8630903300770275248">Ngenisa umsebenzisi ogadiwe</translation>
 <translation id="8631032106121706562">Amaphethali</translation>
@@ -5463,7 +5462,7 @@
 <translation id="8807632654848257479">Izinzile</translation>
 <translation id="8808478386290700967">Isitolo sewebhu</translation>
 <translation id="8808686172382650546">Ikati</translation>
-<translation id="8808744862003883508">Kulei khasi ungabona zonke izandiso ezifakiwe ku-Chrome.</translation>
+<translation id="8808744862003883508">Kuleli khasi ungabona zonke izandiso ezifakiwe ku-Chrome.</translation>
 <translation id="8809147117840417135">I-teal ekhanyayo</translation>
 <translation id="8813698869395535039">Ayikwazi ukungena ngemvume ku-<ph name="USERNAME" /></translation>
 <translation id="8813811964357448561">ishidi lephepha</translation>
diff --git a/chrome/app/resources/google_chrome_strings_af.xtb b/chrome/app/resources/google_chrome_strings_af.xtb
index db8d7158..39bfc5f 100644
--- a/chrome/app/resources/google_chrome_strings_af.xtb
+++ b/chrome/app/resources/google_chrome_strings_af.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Stel Google Chrome as jou verstekblaaier</translation>
 <translation id="495931528404527476">In Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Kanarie</translation>
-<translation id="5028489144783860647">Google Chrome kon nie jou data sinkroniseer nie. Dateer asseblief jou sinkroniseringwagfrase op.</translation>
 <translation id="5062123544085870375">Herbegin Chrome OS</translation>
 <translation id="5132929315877954718">Ontdek wonderlike programme, speletjies, uitbreidings en temas vir Google Chrome.</translation>
 <translation id="5170938038195470297">Jou profiel kan nie gebruik word nie, want dit kom van 'n nuwer weergawe van Google Chrome af.
diff --git a/chrome/app/resources/google_chrome_strings_am.xtb b/chrome/app/resources/google_chrome_strings_am.xtb
index 6fe6098..eff65d3 100644
--- a/chrome/app/resources/google_chrome_strings_am.xtb
+++ b/chrome/app/resources/google_chrome_strings_am.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chromeን እንደ ነባሪ አሳሽዎ አድርገው ያቀናብሩ</translation>
 <translation id="495931528404527476">በChrome ውስጥ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome የእርስዎን ውሂብ ማመሳሰል አልቻለም። እባክዎ የእርስዎን የማመሳሰያ የይለፍ ሐረግ ያዘምኑ።</translation>
 <translation id="5062123544085870375">Chrome OSን ዳግም አስጀምር</translation>
 <translation id="5132929315877954718">ለGoogle Chrome ምርጥ መተግበሪያዎችን፣ ጨዋታዎችን፣ ቅጥያዎችን እና ገጽታዎችን ያግኙ።</translation>
 <translation id="5170938038195470297">መገለጫዎ የአዲስ Google Chrome ስሪት አካል ስለሆነ መጠቀም አይቻልም።
diff --git a/chrome/app/resources/google_chrome_strings_ar.xtb b/chrome/app/resources/google_chrome_strings_ar.xtb
index 3920fd88..a641634 100644
--- a/chrome/app/resources/google_chrome_strings_ar.xtb
+++ b/chrome/app/resources/google_chrome_strings_ar.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">‏تعيين Google Chrome المتصفح التلقائي</translation>
 <translation id="495931528404527476">‏في Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">‏تعذر على Google Chrome مزامنة البيانات. يُرجى تحديث عبارة مرور المزامنة.</translation>
 <translation id="5062123544085870375">‏إعادة تشغيل نظام التشغيل Chrome</translation>
 <translation id="5132929315877954718">‏يمكنك اكتشاف تطبيقات، وألعاب، وإضافات، ومظاهر رائعة لمتصفح Google Chrome.</translation>
 <translation id="5170938038195470297">‏لا يمكن استخدام ملفك الشخصي نظرًا لأنه من إصدار أحدث من Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_as.xtb b/chrome/app/resources/google_chrome_strings_as.xtb
index 34440f2..19b6c53 100644
--- a/chrome/app/resources/google_chrome_strings_as.xtb
+++ b/chrome/app/resources/google_chrome_strings_as.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">আপোনাৰ ডিফ'ল্ট ব্ৰাউজাৰ হিচাপে Google Chromeক ছেট কৰক</translation>
 <translation id="495931528404527476">Chromeত</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chromeএ আপোনাৰ ডেটা ছিংক কৰিব নোৱাৰিলে। অনুগ্ৰহ কৰি আপোনাৰ ছিংক পাছফ্ৰে’জটো আপডে’ট কৰক।</translation>
 <translation id="5062123544085870375">Chrome OS ৰিষ্টার্ট কৰক</translation>
 <translation id="5132929315877954718">Google Chromeৰ বাবে উত্তম এপ্, গে’ম, এক্সটেনশ্বন আৰু থীম বিচাৰক৷</translation>
 <translation id="5170938038195470297">আপোনাৰ প্ৰ’ফাইল ব্যৱহাৰ কৰিব নোৱাৰি কাৰণ এয়া Google Chromeৰ এক নতুন সংস্কৰণ।
diff --git a/chrome/app/resources/google_chrome_strings_az.xtb b/chrome/app/resources/google_chrome_strings_az.xtb
index 33526ff..deda84e3 100644
--- a/chrome/app/resources/google_chrome_strings_az.xtb
+++ b/chrome/app/resources/google_chrome_strings_az.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Google Chrome'u defolt brauzer təyin edin</translation>
 <translation id="495931528404527476">Chrome'da</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome datanızı sinxronizasiya edə bilmədi. Lütfən, Sinxronizasiya parol ifadəsini güncəlləşdirin.</translation>
 <translation id="5062123544085870375">Chrome ƏS-ni yenidən başladın</translation>
 <translation id="5132929315877954718">Google Chrome üçün möhtəşəm tətbiqlər, artırmalar və temalar kəşf edin.</translation>
 <translation id="5170938038195470297">Profiliniz yeni versiya Google Chrome'dan olduğu üçün istifadə edilə bilməz.
diff --git a/chrome/app/resources/google_chrome_strings_be.xtb b/chrome/app/resources/google_chrome_strings_be.xtb
index e82f193..194ce45 100644
--- a/chrome/app/resources/google_chrome_strings_be.xtb
+++ b/chrome/app/resources/google_chrome_strings_be.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Зрабіць Google Chrome стандартным браўзерам</translation>
 <translation id="495931528404527476">У браўзеры Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Сінхранізаваць даныя ў браўзеры Google Chrome не ўдалося. Абнавіце фразу-пароль для сінхранізацыі.</translation>
 <translation id="5062123544085870375">Перазапусціце Chrome OS</translation>
 <translation id="5132929315877954718">Адкрывайце для сябе выдатныя праграмы, гульні, пашырэнні і тэмы для Google Chrome.</translation>
 <translation id="5170938038195470297">Ваш профіль нельга выкарыстоўваць, бо ён з навейшай версіі Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_bg.xtb b/chrome/app/resources/google_chrome_strings_bg.xtb
index 8b489d3..8722284 100644
--- a/chrome/app/resources/google_chrome_strings_bg.xtb
+++ b/chrome/app/resources/google_chrome_strings_bg.xtb
@@ -128,7 +128,6 @@
 <translation id="4953650215774548573">Задаване на Google Chrome като браузър по подразбиране</translation>
 <translation id="495931528404527476">В Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome не можа да синхронизира данните ви. Моля, актуализирайте пропуска си за синхронизиране.</translation>
 <translation id="5062123544085870375">Рестартиране на Chrome OS</translation>
 <translation id="5132929315877954718">Открийте отлични приложения, игри, разширения и теми за Google Chrome.</translation>
 <translation id="5170938038195470297">Потребителският ви профил не може да се използва, защото е от по-нова версия на Google Chrome. Някои функции може да не са налице. Моля, посочете друга директория в потребителския профил или използвайте по-нова версия на Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bn.xtb b/chrome/app/resources/google_chrome_strings_bn.xtb
index 704546a..2c2c288 100644
--- a/chrome/app/resources/google_chrome_strings_bn.xtb
+++ b/chrome/app/resources/google_chrome_strings_bn.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">আপনার ডিফল্ট ব্রাউজার হিসাবে Google Chrome-কে সেট করুন</translation>
 <translation id="495931528404527476">Chrome-এ</translation>
 <translation id="4990567037958725628">Google Chrome  ক্যানারি</translation>
-<translation id="5028489144783860647">Google Chrome আপনার ডেটা সিঙ্ক করতে পারেনি৷ দয়া করে আপনার সিঙ্ক পাসফ্রেজ আপডেট করুন৷</translation>
 <translation id="5062123544085870375">Chrome OS রিস্টার্ট করুন</translation>
 <translation id="5132929315877954718">Google Chrome-এর দুর্দান্ত অ্যাপ্লিকেশান, গেম, এক্সটেনশান এবং থিম আবিষ্কার করুন৷</translation>
 <translation id="5170938038195470297">আপনার প্রোফাইল ব্যবহার করা যাবে কারণ এটি Google Chrome-এর একটি নতুন ভার্সনে গঠিত৷ 
diff --git a/chrome/app/resources/google_chrome_strings_bs.xtb b/chrome/app/resources/google_chrome_strings_bs.xtb
index 4eec321..f4e1668 100644
--- a/chrome/app/resources/google_chrome_strings_bs.xtb
+++ b/chrome/app/resources/google_chrome_strings_bs.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Postavi Google Chrome kao zadani preglednik</translation>
 <translation id="495931528404527476">Iz Chromea</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nije mogao sinhronizirati vaše podatke. Ažurirajte pristupni izraz za sinhronizaciju.</translation>
 <translation id="5062123544085870375">Ponovo pokrenite Chrome OS</translation>
 <translation id="5132929315877954718">Otkrijte odlične aplikacije, igre, ekstenzije i teme za Google Chrome.</translation>
 <translation id="5170938038195470297">Ne možete koristiti profil jer je s novije verzije Google Chromea.
diff --git a/chrome/app/resources/google_chrome_strings_ca.xtb b/chrome/app/resources/google_chrome_strings_ca.xtb
index a73292c..3e0a598 100644
--- a/chrome/app/resources/google_chrome_strings_ca.xtb
+++ b/chrome/app/resources/google_chrome_strings_ca.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Defineix Google Chrome com a navegador predeterminat</translation>
 <translation id="495931528404527476">A Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome no ha pogut sincronitzar les dades. Actualitzeu la frase de contrasenya de sincronització.</translation>
 <translation id="5062123544085870375">Reinicia Chrome OS</translation>
 <translation id="5132929315877954718">Descobriu aplicacions, jocs, extensions i temes genials per a Google Chrome.</translation>
 <translation id="5170938038195470297">El vostre perfil no es pot utilitzar perquè prové d'una versió més nova de Google Chrome. Pot ser que algunes funcions no estiguin disponibles. Especifiqueu un directori de perfil diferent o utilitzeu una versió més nova de Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_cs.xtb b/chrome/app/resources/google_chrome_strings_cs.xtb
index 5038cb3..37dea037 100644
--- a/chrome/app/resources/google_chrome_strings_cs.xtb
+++ b/chrome/app/resources/google_chrome_strings_cs.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Nastavit Google Chrome jako výchozí prohlížeč</translation>
 <translation id="495931528404527476">V Chromu</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome vaše data nemohl synchronizovat. Aktualizujte prosím heslovou frázi pro synchronizaci.</translation>
 <translation id="5062123544085870375">Restartujte systém Chrome OS</translation>
 <translation id="5132929315877954718">Objevte skvělé aplikace, hry, rozšíření a motivy prohlížeče Google Chrome.</translation>
 <translation id="5170938038195470297">Nelze použít váš profil, protože byl vytvořen v novější verzi aplikace Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_da.xtb b/chrome/app/resources/google_chrome_strings_da.xtb
index cf3eb3c..e2b9c4eb 100644
--- a/chrome/app/resources/google_chrome_strings_da.xtb
+++ b/chrome/app/resources/google_chrome_strings_da.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Angiv Google Chrome som din standardbrowser</translation>
 <translation id="495931528404527476">I Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome kunne ikke synkronisere dine data. Opdater din adgangssætning til synkronisering.</translation>
 <translation id="5062123544085870375">Genstart Chrome OS</translation>
 <translation id="5132929315877954718">Find fantastiske apps, spil, udvidelser og temaer til Google Chrome.</translation>
 <translation id="5170938038195470297">Din profil kan ikke bruges, fordi den stammer fra en nyere version af Google Chrome. Nogle funktioner er muligvis ikke tilgængelige. Angiv en anden profilmappe, eller brug en nyere version af Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_de.xtb b/chrome/app/resources/google_chrome_strings_de.xtb
index 400eb8ef..f14ac46 100644
--- a/chrome/app/resources/google_chrome_strings_de.xtb
+++ b/chrome/app/resources/google_chrome_strings_de.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Google Chrome als Standardbrowser festlegen</translation>
 <translation id="495931528404527476">In Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome konnte Ihre Daten nicht synchronisieren. Bitte aktualisieren Sie Ihre Passphrase für die Synchronisierung.</translation>
 <translation id="5062123544085870375">Chrome OS neu starten</translation>
 <translation id="5132929315877954718">Entdecken Sie tolle Apps, Spiele, Erweiterungen und Designs für Google Chrome.</translation>
 <translation id="5170938038195470297">Ihr Profil kann nicht verwendet werden, da es von einer neueren Version von Google Chrome stammt. Einige Funktionen stehen möglicherweise nicht zur Verfügung. Geben Sie bitte ein anderes Profilverzeichnis an oder verwenden Sie eine neuere Version von Google Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_el.xtb b/chrome/app/resources/google_chrome_strings_el.xtb
index 31b4bc9..db6a530 100644
--- a/chrome/app/resources/google_chrome_strings_el.xtb
+++ b/chrome/app/resources/google_chrome_strings_el.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Ορίστε το Google Chrome ως προεπιλεγμένο πρόγραμμα περιήγησης</translation>
 <translation id="495931528404527476">Στο Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Το Google Chrome δεν κατάφερε να συγχρονίσει τα δεδομένα σας. Ενημερώστε τη φράση πρόσβασης συγχρονισμού.</translation>
 <translation id="5062123544085870375">Επανεκκίνηση Chrome OS</translation>
 <translation id="5132929315877954718">Ανακαλύψτε υπέροχες εφαρμογές, παιχνίδια, επεκτάσεις και θέματα για το Google Chrome.</translation>
 <translation id="5170938038195470297">Το προφίλ σας δεν μπορεί να χρησιμοποιηθεί επειδή προέρχεται από μια νεότερη έκδοση του Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_en-GB.xtb b/chrome/app/resources/google_chrome_strings_en-GB.xtb
index b1dfd37b..395bc25 100644
--- a/chrome/app/resources/google_chrome_strings_en-GB.xtb
+++ b/chrome/app/resources/google_chrome_strings_en-GB.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Set Google Chrome as your default browser</translation>
 <translation id="495931528404527476">In Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome could not sync your data. Please update your Sync passphrase.</translation>
 <translation id="5062123544085870375">Restart Chrome OS</translation>
 <translation id="5132929315877954718">Discover great apps, games, extensions and themes for Google Chrome.</translation>
 <translation id="5170938038195470297">Your profile cannot be used because it is from a newer version of Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_es-419.xtb b/chrome/app/resources/google_chrome_strings_es-419.xtb
index d3c957e..6b07c33 100644
--- a/chrome/app/resources/google_chrome_strings_es-419.xtb
+++ b/chrome/app/resources/google_chrome_strings_es-419.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Establecer Google Chrome como navegador predeterminado</translation>
 <translation id="495931528404527476">En Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canario</translation>
-<translation id="5028489144783860647">Google Chrome no pudo sincronizar los datos. Actualiza la frase de contraseña de sincronización.</translation>
 <translation id="5062123544085870375">Reiniciar el Sistema operativo Chrome</translation>
 <translation id="5132929315877954718">Descubre aplicaciones, juegos, extensiones y temas geniales para Google Chrome.</translation>
 <translation id="5170938038195470297">No se puede usar tu perfil porque pertenece a una nueva versión de Google Chrome. Es posible que algunas características no estén disponibles. Especifica un directorio de perfil diferente o usa una nueva versión de Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_es.xtb b/chrome/app/resources/google_chrome_strings_es.xtb
index b4aa304..f2a0913 100644
--- a/chrome/app/resources/google_chrome_strings_es.xtb
+++ b/chrome/app/resources/google_chrome_strings_es.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Establecer Google Chrome como navegador predeterminado</translation>
 <translation id="495931528404527476">En Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome no ha podido sincronizar los datos. Actualiza la frase de contraseña de sincronización.</translation>
 <translation id="5062123544085870375">Reiniciar Chrome OS</translation>
 <translation id="5132929315877954718">Descubre formidables aplicaciones, juegos, extensiones y temas para Google Chrome.</translation>
 <translation id="5170938038195470297">No se puede usar tu perfil porque se corresponde con una versión más reciente de Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_et.xtb b/chrome/app/resources/google_chrome_strings_et.xtb
index 93a0a0a..4879dc8 100644
--- a/chrome/app/resources/google_chrome_strings_et.xtb
+++ b/chrome/app/resources/google_chrome_strings_et.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Määra Google Chrome vaikebrauseriks</translation>
 <translation id="495931528404527476">Chrome'is</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ei saanud teie andmeid sünkroonida. Värskendage oma sünkroonimisparooli.</translation>
 <translation id="5062123544085870375">Taaskäivitage Chrome OS</translation>
 <translation id="5132929315877954718">Avastage Google Chrome'i jaoks suurepäraseid rakendusi, mänge, laiendusi ja teemasid.</translation>
 <translation id="5170938038195470297">Teie profiili ei saa kasutada, kuna see pärineb Google Chrome'i uuemast versioonist.
diff --git a/chrome/app/resources/google_chrome_strings_eu.xtb b/chrome/app/resources/google_chrome_strings_eu.xtb
index f200820c..2ad1faf 100644
--- a/chrome/app/resources/google_chrome_strings_eu.xtb
+++ b/chrome/app/resources/google_chrome_strings_eu.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Ezarri Google Chrome arakatzaile lehenetsi gisa</translation>
 <translation id="495931528404527476">Chrome-n</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Chrome Chrome-k ezin izan ditu zure datuak sinkronizatu. Aldatu sinkronizatzeko pasaesaldia.</translation>
 <translation id="5062123544085870375">Berrabiarazi Chrome OS</translation>
 <translation id="5132929315877954718">Ezagutu Google Chrome-rako aplikazio, joko, luzapen eta gai bikainak.</translation>
 <translation id="5170938038195470297">Ezin da profila erabili Google Chrome-ren bertsio berriago batekoa delako.
diff --git a/chrome/app/resources/google_chrome_strings_fa.xtb b/chrome/app/resources/google_chrome_strings_fa.xtb
index 665d1b0..878e1a6 100644
--- a/chrome/app/resources/google_chrome_strings_fa.xtb
+++ b/chrome/app/resources/google_chrome_strings_fa.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">‏تنظیم Google Chrome به عنوان مرورگر پیش‌فرضتان</translation>
 <translation id="495931528404527476">‏در Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">‏Google Chrome قادر به همگام‌سازی داده‌های شما نبود. لطفاً رمز عبارتی همگام‌سازی خود را به‌روز کنید.</translation>
 <translation id="5062123544085870375">‏بازراه‌اندازی سیستم‌عامل Chrome</translation>
 <translation id="5132929315877954718">‏برنامه‌های کاربردی، بازی‌ها، افزونه‌ها و طرح‌های زمینه فوق‌العاده را برای Google Chrome کاوش کنید.</translation>
 <translation id="5170938038195470297">‏نمایهٔ شما نمی‌تواند استفاده شود زیرا مربوط به یک نسخه جدیدتر از Google Chrome است. بعضی از ویژگی‌ها ممکن است موجود نباشند. لطفاً یک مسیر دیگر برای نمایه تعیین کنید یا از نسخه جدیدتر Chrome استفاده کنید.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fi.xtb b/chrome/app/resources/google_chrome_strings_fi.xtb
index adce79f..5698dd5 100644
--- a/chrome/app/resources/google_chrome_strings_fi.xtb
+++ b/chrome/app/resources/google_chrome_strings_fi.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Aseta Google Chrome oletusselaimeksi</translation>
 <translation id="495931528404527476">Chromessa</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ei voinut synkronoida tietoja. Päivitä synkronoinnin tunnuslause.</translation>
 <translation id="5062123544085870375">Käynnistä Chrome OS uudelleen</translation>
 <translation id="5132929315877954718">Löydät hienoja sovelluksia, pelejä ja teemoja Google Chromelle.</translation>
 <translation id="5170938038195470297">Profiiliasi ei voi käyttää, koska se on peräisin uudemmasta Google Chromen versiosta. Kaikkia toimintoja ei välttämättä voi käyttää. Määritä toinen profiilihakemisto tai käytä uudempaa Chromen versiota.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fil.xtb b/chrome/app/resources/google_chrome_strings_fil.xtb
index 268ef17e..b5ec2e1 100644
--- a/chrome/app/resources/google_chrome_strings_fil.xtb
+++ b/chrome/app/resources/google_chrome_strings_fil.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Itakda ang Google Chrome bilang iyong default na browser</translation>
 <translation id="495931528404527476">Sa Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Hindi mai-sync ng Google Chrome ang iyong data. Paki-update ang iyong passphrase sa Pag-sync.</translation>
 <translation id="5062123544085870375">I-restart ang Chrome OS</translation>
 <translation id="5132929315877954718">Tumuklas ng mahuhusay na app, laro, extension at tema para sa Google Chrome.</translation>
 <translation id="5170938038195470297">Hindi magagamit ang iyong profile dahil mula ito sa isang mas bagong bersyon ng Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_fr-CA.xtb b/chrome/app/resources/google_chrome_strings_fr-CA.xtb
index 56dce3ea..877fe5a 100644
--- a/chrome/app/resources/google_chrome_strings_fr-CA.xtb
+++ b/chrome/app/resources/google_chrome_strings_fr-CA.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Sélectionner Google Chrome comme navigateur par défaut</translation>
 <translation id="495931528404527476">Dans Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Échec de synchronisation de vos données dans Google Chrome. Veuillez mettre à jour votre phrase de passe de synchronisation.</translation>
 <translation id="5062123544085870375">Redémarrer Chrome OS</translation>
 <translation id="5132929315877954718">Découvrez des applications, des jeux, des extensions et des thèmes exceptionnels conçus pour Google Chrome.</translation>
 <translation id="5170938038195470297">Votre profil ne peut pas être utilisé parce qu'il provient d'une version plus récente de Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_fr.xtb b/chrome/app/resources/google_chrome_strings_fr.xtb
index 7250969..6a6e846 100644
--- a/chrome/app/resources/google_chrome_strings_fr.xtb
+++ b/chrome/app/resources/google_chrome_strings_fr.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Définir Google Chrome en tant que navigateur par défaut</translation>
 <translation id="495931528404527476">Dans Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Impossible de synchroniser vos données dans Google Chrome. Veuillez mettre à jour votre phrase secrète de synchronisation.</translation>
 <translation id="5062123544085870375">Redémarrer Chrome OS</translation>
 <translation id="5132929315877954718">Découvrez des applications, des jeux, des extensions et des thèmes exceptionnels pour Google Chrome.</translation>
 <translation id="5170938038195470297">Votre profil ne peut pas être utilisé parce qu'il vient d'une version plus récente de Google Chrome. 
diff --git a/chrome/app/resources/google_chrome_strings_gl.xtb b/chrome/app/resources/google_chrome_strings_gl.xtb
index 0b414ee..69d7011 100644
--- a/chrome/app/resources/google_chrome_strings_gl.xtb
+++ b/chrome/app/resources/google_chrome_strings_gl.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Establecer Google Chrome como navegador predeterminado</translation>
 <translation id="495931528404527476">En Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome non puido sincronizar os teus datos. Actualiza a túa frase de acceso de sincronización.</translation>
 <translation id="5062123544085870375">Reinicia Chrome OS</translation>
 <translation id="5132929315877954718">Descubre aplicacións, xogos, extensións e temas fantásticos para Google Chrome.</translation>
 <translation id="5170938038195470297">Non se pode utilizar o teu perfil porque pertence a unha versión máis recente de Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_gu.xtb b/chrome/app/resources/google_chrome_strings_gu.xtb
index 1e69115..d9d2389d 100644
--- a/chrome/app/resources/google_chrome_strings_gu.xtb
+++ b/chrome/app/resources/google_chrome_strings_gu.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome ને તમારા ડિફોલ્ટ બ્રાઉઝર તરીકે સેટ કરો</translation>
 <translation id="495931528404527476">Chrome માં</translation>
 <translation id="4990567037958725628">Google Chrome કૅનેરી</translation>
-<translation id="5028489144783860647">Google Chrome તમારા ડેટાને સમન્વયિત કરી શક્યું નથી. કૃપા કરીને તમારા સમન્વયન પાસફ્રેઝને અપડેટ કરો.</translation>
 <translation id="5062123544085870375">Chrome OS ફરી શરૂ કરો</translation>
 <translation id="5132929315877954718">Google Chrome માટે શ્રેષ્ઠ ઍપ્લિકેશનો, રમતો, એક્સટેન્શન્સ અને થીમ્સ શોધો</translation>
 <translation id="5170938038195470297">તમારી પ્રોફાઇલનો ઉપયોગ કરી શકાતો નથી કારણ કે તે Google Chromeના નવા વર્ઝન તરફથી છે.
diff --git a/chrome/app/resources/google_chrome_strings_hi.xtb b/chrome/app/resources/google_chrome_strings_hi.xtb
index 965962e..71bbf5d 100644
--- a/chrome/app/resources/google_chrome_strings_hi.xtb
+++ b/chrome/app/resources/google_chrome_strings_hi.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Google Chrome को अपने डिफ़ॉल्ट ब्राउज़र के रूप में सेट करना</translation>
 <translation id="495931528404527476">Chrome में</translation>
 <translation id="4990567037958725628">Google Chrome कैनरी</translation>
-<translation id="5028489144783860647">Google Chrome आपका डेटा सिंक नहीं कर सका. कृपया अपना सिंक 'पासफ़्रेज़' अपडेट करें.</translation>
 <translation id="5062123544085870375">Chrome OS को रीस्टार्ट करें</translation>
 <translation id="5132929315877954718">Google Chrome के लिए बेहतरीन ऐप्स ,गेम, एक्सटेंशन और थीम खोजें.</translation>
 <translation id="5170938038195470297">आपकी प्रोफ़ाइल का उपयोग नहीं किया जा सकता क्‍योंकि यह Google Chrome के किसी नए वर्शन से है.
diff --git a/chrome/app/resources/google_chrome_strings_hr.xtb b/chrome/app/resources/google_chrome_strings_hr.xtb
index d4d4829..9e4fdb97 100644
--- a/chrome/app/resources/google_chrome_strings_hr.xtb
+++ b/chrome/app/resources/google_chrome_strings_hr.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Postavite Google Chrome kao svoj zadani preglednik</translation>
 <translation id="495931528404527476">U Chromeu</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nije mogao sinkronizirati vaše podatke. Ažurirajte zaporku za sinkronizaciju.</translation>
 <translation id="5062123544085870375">Ponovo pokrenite OS Chrome</translation>
 <translation id="5132929315877954718">Otkrijte sjajne aplikacije, igre, proširenja i teme za Google Chrome.</translation>
 <translation id="5170938038195470297">Vaš se profil ne može upotrijebiti jer pripada novijoj verziji proizvoda Google Chrome. Neke značajke možda nisu dostupne. Navedite drugi direktorij profila ili upotrijebite noviju verziju proizvoda Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hu.xtb b/chrome/app/resources/google_chrome_strings_hu.xtb
index 029ca010..a3132f7 100644
--- a/chrome/app/resources/google_chrome_strings_hu.xtb
+++ b/chrome/app/resources/google_chrome_strings_hu.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">A Google Chrome beállítása alapértelmezett böngészőként</translation>
 <translation id="495931528404527476">A Chrome-ban</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">A Google Chrome nem tudta szinkronizálni az adatokat. Kérjük, frissítse a szinkronizálás jelszavát.</translation>
 <translation id="5062123544085870375">A Chrome OS újraindítása</translation>
 <translation id="5132929315877954718">Fedezzen fel nagyszerű alkalmazásokat, játékokat, bővítményeket és témákat a Google Chrome-hoz.</translation>
 <translation id="5170938038195470297">A profilja nem használható, mivel a Google Chrome egy újabb verziójából származik. Előfordulhat, hogy egyes funkciók nem érhetők el. Kérjük, adjon meg egy másik profilmappát, vagy használja a Google Chrome újabb verzióját.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hy.xtb b/chrome/app/resources/google_chrome_strings_hy.xtb
index c2f1438..6cb98740 100644
--- a/chrome/app/resources/google_chrome_strings_hy.xtb
+++ b/chrome/app/resources/google_chrome_strings_hy.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Դարձնել Google Chrome-ը կանխադրված դիտարկիչը</translation>
 <translation id="495931528404527476">Chrome-ում</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome-ը չկարողացավ համաժամացնել ձեր տվյալները: Թարմացրեք Sync-ի անցաբառը:</translation>
 <translation id="5062123544085870375">Chrome OS-ի վերագործարկում</translation>
 <translation id="5132929315877954718">Հավելվածների, խաղերի, ընդլայնումների և թեմաների լայն ընտրանի Google Chrome-ի համար:</translation>
 <translation id="5170938038195470297">Դուք չեք կարող օգտագործել ձեր պրոֆիլը, քանի որ այն Google Chrome-ի նոր տարբերակով է:
diff --git a/chrome/app/resources/google_chrome_strings_id.xtb b/chrome/app/resources/google_chrome_strings_id.xtb
index d0cb3925..ff0e37af 100644
--- a/chrome/app/resources/google_chrome_strings_id.xtb
+++ b/chrome/app/resources/google_chrome_strings_id.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Setel Google Chrome sebagai browser default Anda</translation>
 <translation id="495931528404527476">Di Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome tidak dapat menyinkronkan data Anda. Perbarui frasa sandi Sinkronisasi Anda.</translation>
 <translation id="5062123544085870375">Mulai ulang Chrome OS</translation>
 <translation id="5132929315877954718">Temukan aplikasi, game, ekstensi, dan tema yang hebat untuk Google Chrome.</translation>
 <translation id="5170938038195470297">Profil Anda tidak dapat digunakan karena berasal dari versi terbaru Google Chrome. Beberapa fitur mungkin tidak tersedia. Tentukan direktori profil yang berbeda atau gunakan versi Chrome yang lebih anyar.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_is.xtb b/chrome/app/resources/google_chrome_strings_is.xtb
index e6cc0c6..d35c387 100644
--- a/chrome/app/resources/google_chrome_strings_is.xtb
+++ b/chrome/app/resources/google_chrome_strings_is.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Stilla Google Chrome sem sjálfgefinn vafra</translation>
 <translation id="495931528404527476">Í Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome gat ekki samstillt gögnin þín. Uppfærðu aðgangsorðið þitt fyrir samstillingu.</translation>
 <translation id="5062123544085870375">Endurræstu Chrome OS</translation>
 <translation id="5132929315877954718">Uppgötvaðu frábær forrit, leiki, viðbætur og þemu fyrir Google Chrome</translation>
 <translation id="5170938038195470297">Ekki er hægt að nota prófílinn þinn því að hann er úr nýrri útgáfu Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_it.xtb b/chrome/app/resources/google_chrome_strings_it.xtb
index 891a002..e054e46a 100644
--- a/chrome/app/resources/google_chrome_strings_it.xtb
+++ b/chrome/app/resources/google_chrome_strings_it.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Imposta Google Chrome come browser predefinito</translation>
 <translation id="495931528404527476">In Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Impossibile sincronizzare i dati in Google Chrome. Aggiorna la passphrase di sincronizzazione.</translation>
 <translation id="5062123544085870375">Riavvia Chrome OS</translation>
 <translation id="5132929315877954718">Scopri applicazioni, giochi, estensioni e temi straordinari per Google Chrome.</translation>
 <translation id="5170938038195470297">Non è possibile utilizzare il tuo profilo perché è associato a una versione di Google Chrome più recente. Alcune funzioni potrebbero non essere disponibili. Specifica una directory del profilo diversa o utilizza una versione di Chrome più recente.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_iw.xtb b/chrome/app/resources/google_chrome_strings_iw.xtb
index 21269d5..34fa19f 100644
--- a/chrome/app/resources/google_chrome_strings_iw.xtb
+++ b/chrome/app/resources/google_chrome_strings_iw.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">‏הגדר את Google Chrome כדפדפן ברירת המחדל</translation>
 <translation id="495931528404527476">‏ב-Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">‏Google Chrome לא הצליח לסנכרן את הנתונים שלך. עדכן את משפט הסיסמה שלך עבור סנכרון.</translation>
 <translation id="5062123544085870375">‏הפעלה מחדש של Chrome OS</translation>
 <translation id="5132929315877954718">‏מקום לגלות אפליקציות, משחקים, תוספים ועיצובים מעולים ל-Google Chrome.</translation>
 <translation id="5170938038195470297">‏לא ניתן להשתמש בפרופיל שלך משום שהוא מגרסה חדשה יותר של Google Chrome. ייתכן שחלק מהתכונות לא יהיו זמינות. ציין ספריית פרופיל אחרת או השתמש בגרסה חדשה יותר של Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ja.xtb b/chrome/app/resources/google_chrome_strings_ja.xtb
index 2daa61b6..42d7d47 100644
--- a/chrome/app/resources/google_chrome_strings_ja.xtb
+++ b/chrome/app/resources/google_chrome_strings_ja.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Google Chrome を既定のブラウザとして設定する</translation>
 <translation id="495931528404527476">Chrome 専用</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome はデータを同期できませんでした。同期パスフレーズを更新してください。</translation>
 <translation id="5062123544085870375">Chrome OS を再起動してください</translation>
 <translation id="5132929315877954718">Google Chrome のすばらしいアプリ、ゲーム、拡張機能、テーマをぜひご利用ください。</translation>
 <translation id="5170938038195470297">バージョンが新しい Google Chrome のプロフィールは使用できません。一部の機能が利用できない可能性があります。別の場所のプロフィールを指定するか、新しいバージョンの Chrome をご使用ください。</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ka.xtb b/chrome/app/resources/google_chrome_strings_ka.xtb
index 7053290..b97924fa 100644
--- a/chrome/app/resources/google_chrome_strings_ka.xtb
+++ b/chrome/app/resources/google_chrome_strings_ka.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Google Chrome-ის დაყენება ნაგულისხმევ ბრაუზერად</translation>
 <translation id="495931528404527476">Chrome-ში</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome მა ვერ დაასინქრონა თქვენი მონაცემები. განაახლეთ სინქრონიზაციის საიდუმლო ფრაზა.</translation>
 <translation id="5062123544085870375">გადატვირთეთ Chrome OS</translation>
 <translation id="5132929315877954718">აღმოაჩინეთ დიდებული აპები, თამაშები, გაფართოებები და თემები Google Chrome-ისთვის.</translation>
 <translation id="5170938038195470297">თქვენი პროფილის გამოყენება შეუძლებელია, რადგან იგი მიღებულია Google Chrome-ის უფრო ახალი ვერსიიდან.
diff --git a/chrome/app/resources/google_chrome_strings_kk.xtb b/chrome/app/resources/google_chrome_strings_kk.xtb
index 4fc43e1..8574fbe 100644
--- a/chrome/app/resources/google_chrome_strings_kk.xtb
+++ b/chrome/app/resources/google_chrome_strings_kk.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Әдепкі браузеріңіз ретінде Google Chrome орнату</translation>
 <translation id="495931528404527476">Chrome ішінде</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome деректеріңізді синхрондай алмайды. Синхрондау құпия фразасын жаңартыңыз.</translation>
 <translation id="5062123544085870375">Chrome OS жүйесін қайта қосу</translation>
 <translation id="5132929315877954718">Google Chrome браузеріне арналған тамаша қолданбаларды, ойындарды және тақырыптарды табыңыз.</translation>
 <translation id="5170938038195470297">Профиліңізді пайдалану мүмкін емес, себебі ол жаңарақ Google Chrome нұсқасынан.
diff --git a/chrome/app/resources/google_chrome_strings_km.xtb b/chrome/app/resources/google_chrome_strings_km.xtb
index 5bc000f..a105e093 100644
--- a/chrome/app/resources/google_chrome_strings_km.xtb
+++ b/chrome/app/resources/google_chrome_strings_km.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">កំណត់ Google Chrome ជាកម្មវិធីរុករកលំនាំដើមរបស់អ្នក</translation>
 <translation id="495931528404527476">នៅក្នុង Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome មិនអាចធ្វើសមកម្មទិន្នន័យរបស់អ្នកទេ។ សូមធ្វើបច្ចុប្បន្នភាពឃ្លាសម្ងាត់ សមកម្ម របស់អ្នក។</translation>
 <translation id="5062123544085870375">ចាប់ផ្តើម Chrome OS ឡើងវិញ</translation>
 <translation id="5132929315877954718">ស្វែងយល់ពីកម្មវិធី ហ្គេម កម្មវិធីបន្ថែម និងធីមដ៏អស្ចារ្យសម្រាប់ Google Chrome។</translation>
 <translation id="5170938038195470297">ទម្រង់របស់អ្នកមិនអាចត្រូវបានប្រើទេ ពីព្រោះវាចេញមកពីកំណែថ្មីជាងមុននៃ Google Chrome។
diff --git a/chrome/app/resources/google_chrome_strings_kn.xtb b/chrome/app/resources/google_chrome_strings_kn.xtb
index d3f42a0..64361e4 100644
--- a/chrome/app/resources/google_chrome_strings_kn.xtb
+++ b/chrome/app/resources/google_chrome_strings_kn.xtb
@@ -128,7 +128,6 @@
 <translation id="4953650215774548573">Google Chrome ಅನ್ನು ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಬ್ರೌಸರ್‌ ರೂಪದಲ್ಲಿ ಹೊಂದಿಸಿ</translation>
 <translation id="495931528404527476">Chrome ನಲ್ಲಿ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ನಲ್ಲಿ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ನಿಮ್ಮ ಸಿಂಕ್ ಪಾಸ್‌ಫ್ರೇಸ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಿ.</translation>
 <translation id="5062123544085870375">Chrome OS ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
 <translation id="5132929315877954718">Google Chrome ಸಲುವಾಗಿ ಉತ್ಕೃಷ್ಟಮಟ್ಟದ ಅಪ್ಲಿಕೇಶನ್‌‌ಗಳು, ಗೇಮ್‌ಗಳು, ವಿಸ್ತರಣೆಗಳು ಹಾಗೂ ಥೀಮ್‌ಗಳನ್ನು ಅನ್ವೇಷಿಸಿ</translation>
 <translation id="5170938038195470297">ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ Google Chrome ನ ಹೊಸ ಆವೃತ್ತಿಯಿಂದ ಆಗಿರುವ ಕಾರಣ ಅದನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ. ಕೆಲವು ವೈಶಿಷ್ಟ್ಯಗಳು ಲಭ್ಯವಿಲ್ಲದಿರಬಹುದು. ದಯವಿಟ್ಟು ಬೇರೆಯ ಪ್ರೊಫೈಲ್ ಡೈರೆಕ್ಟರಿಯನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಿ ಅಥವಾ Chrome ನ ಹೊಸ ಆವೃತ್ತಿಯನ್ನು ಬಳಸಿ.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ko.xtb b/chrome/app/resources/google_chrome_strings_ko.xtb
index 5fe52c36..288d999 100644
--- a/chrome/app/resources/google_chrome_strings_ko.xtb
+++ b/chrome/app/resources/google_chrome_strings_ko.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Chrome을 기본 브라우저로 설정</translation>
 <translation id="495931528404527476">Chrome</translation>
 <translation id="4990567037958725628">Chrome 카나리아</translation>
-<translation id="5028489144783860647">Chrome에서 데이터를 동기화하지 못했습니다. 동기화 암호를 업데이트하시기 바랍니다.</translation>
 <translation id="5062123544085870375">Chrome OS 다시 시작</translation>
 <translation id="5132929315877954718">Chrome에 사용할 유용한 애플리케이션, 게임, 확장 프로그램 및 테마를 찾아보세요.</translation>
 <translation id="5170938038195470297">최신 버전의 Chrome에서 가져온 사용자 프로필이기 때문에 사용할 수 없습니다.
diff --git a/chrome/app/resources/google_chrome_strings_ky.xtb b/chrome/app/resources/google_chrome_strings_ky.xtb
index 8b293ad..00271dbe 100644
--- a/chrome/app/resources/google_chrome_strings_ky.xtb
+++ b/chrome/app/resources/google_chrome_strings_ky.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome'ду демейки серепчи катары коюу</translation>
 <translation id="495931528404527476">Chrome ичинде</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome дайындарыңызды шайкештештире алган жок. Шайкештештирүү сырсөз айкашын жаңыртыңыз.</translation>
 <translation id="5062123544085870375">Chrome OS'ту өчүрүп-күйгүзүңүз</translation>
 <translation id="5132929315877954718">Google Chrome'дун мыкты колдонмолор, оюндар, кеңейтүүлөр жана темалар дүйнөсүн ачыңыз.</translation>
 <translation id="5170938038195470297">Профилиңиз Google Chrome'дун акыркы версиясынан болгондуктан колдонулбайт.
diff --git a/chrome/app/resources/google_chrome_strings_lo.xtb b/chrome/app/resources/google_chrome_strings_lo.xtb
index 268de5a2..3802f83 100644
--- a/chrome/app/resources/google_chrome_strings_lo.xtb
+++ b/chrome/app/resources/google_chrome_strings_lo.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">ຕັ້ງ Google Chrome ເປັນບຣາວ​ເຊີມາດຕະຖານຂອງທ່ານ</translation>
 <translation id="495931528404527476">ຢູ່ໃນ Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ບໍ່​ສາ​ມາດຊິງຄ໌ຂໍ້​ມູນ​ຂອງ​ທ່ານໄດ້​. ກະ​ລຸ​ນາອັບເດດຊິງຄ໌ວະລີຜ່ານຂອງ​ທ່ານ​.</translation>
 <translation id="5062123544085870375">ປິດເປີດ Chrome OS ຄືນໃໝ່</translation>
 <translation id="5132929315877954718">ຄົ້ນພົບແອັບຯ, ເກມ, ສ່ວນຂະຫຍາຍ ແລະ ຮູບແບບສີສັນສຳລັບ Google Chrome.</translation>
 <translation id="5170938038195470297">ບໍ່ສາມາດໃຊ້ໂປຣໄຟລ໌ຂອງທ່ານໄດ້ ເພາະວ່າມັນມາຈາກ Google Chrome ລຸ້ນໃໝ່.
diff --git a/chrome/app/resources/google_chrome_strings_lt.xtb b/chrome/app/resources/google_chrome_strings_lt.xtb
index 066ddd5..587d390b 100644
--- a/chrome/app/resources/google_chrome_strings_lt.xtb
+++ b/chrome/app/resources/google_chrome_strings_lt.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Nustatyti „Google Chrome“ kaip numatytąją naršyklę</translation>
 <translation id="495931528404527476">Naudojant „Chrome“</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">„Google Chrome“ negali sinchronizuoti duomenų. Atnaujinkite sinchronizavimo slaptafrazę.</translation>
 <translation id="5062123544085870375">„Chrome“ OS paleidimas iš naujo</translation>
 <translation id="5132929315877954718">Suraskite puikių „Google Chrome“ programų, žaidimų, plėtinių ir temų.</translation>
 <translation id="5170938038195470297">Jūsų profilio negalima naudoti, nes jis iš naujesnės „Google Chrome“ versijos.
diff --git a/chrome/app/resources/google_chrome_strings_lv.xtb b/chrome/app/resources/google_chrome_strings_lv.xtb
index 65c6cc7e..e71876f 100644
--- a/chrome/app/resources/google_chrome_strings_lv.xtb
+++ b/chrome/app/resources/google_chrome_strings_lv.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Iestatīt Google Chrome kā manu noklusējuma pārlūku</translation>
 <translation id="495931528404527476">Pārlūkprogrammā Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nevarēja sinhronizēt jūsu datus. Lūdzu, atjauniniet savu sinhronizācijas ieejas frāzi.</translation>
 <translation id="5062123544085870375">Restartējiet Chrome OS</translation>
 <translation id="5132929315877954718">Atklājiet lieliskas lietotnes, spēles, paplašinājumus un motīvus, ko varat izmantot pārlūkā Google Chrome.</translation>
 <translation id="5170938038195470297">Jūsu profilu nevar lietot, jo tas ir veidots ar jaunāku Google Chrome versiju.
diff --git a/chrome/app/resources/google_chrome_strings_mk.xtb b/chrome/app/resources/google_chrome_strings_mk.xtb
index 28e43c8..d67d06d6 100644
--- a/chrome/app/resources/google_chrome_strings_mk.xtb
+++ b/chrome/app/resources/google_chrome_strings_mk.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Поставете го Google Chrome за ваш стандарден прелистувач</translation>
 <translation id="495931528404527476">Во Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Канари</translation>
-<translation id="5028489144783860647">Google Chrome не можеше да ги синхронизира вашите податоци. Ажурирајте ја пристапната фраза за синхронизација.</translation>
 <translation id="5062123544085870375">Рестартирајте го Chrome OS</translation>
 <translation id="5132929315877954718">Открива одлични апликации, игри, наставки и теми за Google Chrome.</translation>
 <translation id="5170938038195470297">Вашиот профил на може да се користи бидејќи е од поновата верзија на Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_ml.xtb b/chrome/app/resources/google_chrome_strings_ml.xtb
index 1a649bb8..064f4ba5 100644
--- a/chrome/app/resources/google_chrome_strings_ml.xtb
+++ b/chrome/app/resources/google_chrome_strings_ml.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome-നെ നിങ്ങളുടെ ഡിഫോൾട്ട് ബ്രൗസറായി സജ്ജീകരിക്കുക</translation>
 <translation id="495931528404527476">Chrome-ൽ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome-ന് നിങ്ങളുടെ ഡാറ്റ സമന്വയിപ്പിക്കാനായില്ല. നിങ്ങളുടെ സമന്വയ പാസ്‌ഫ്രെയ്‌സ് അപ്‌ഡേറ്റ് ചെയ്യുക.</translation>
 <translation id="5062123544085870375">Chrome OS പുനഃരാരംഭിക്കുക</translation>
 <translation id="5132929315877954718">Google Chrome-നായി മികച്ച അപ്ലിക്കേഷനുകളും വിപുലീകരണങ്ങളും തീമുകളും കണ്ടെത്തുക.</translation>
 <translation id="5170938038195470297">നിങ്ങളുടെ പ്രൊഫൈൽ Google Chrome-ന്റെ ഒരു പുതിയ പതിപ്പിൽ നിന്നായതിനാൽ ഉപയോഗിക്കാൻ കഴിയില്ല.
diff --git a/chrome/app/resources/google_chrome_strings_mn.xtb b/chrome/app/resources/google_chrome_strings_mn.xtb
index ae6fbde..4b5f068d 100644
--- a/chrome/app/resources/google_chrome_strings_mn.xtb
+++ b/chrome/app/resources/google_chrome_strings_mn.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome-ыг өөрийн анхдагч вэб хөтөч болгон тохируулна уу</translation>
 <translation id="495931528404527476">Chrome-д</translation>
 <translation id="4990567037958725628">Google Chrome цайвар шаргал өнгө</translation>
-<translation id="5028489144783860647">Google Chrome таны өгөгдлийг синхрончилж чадсангүй. Синх-ийн нууц үгүүдээ шинэчлэнэ үү.</translation>
 <translation id="5062123544085870375">Chrome OS-г дахин эхлүүлэх</translation>
 <translation id="5132929315877954718">Google Кромын шилдэг апп, тоглоом, өргөтгөл болон загварыг ашиглах боломжтой.</translation>
 <translation id="5170938038195470297">Таны профайл Google Chrome-ийн шинэ хувилбарынх тул ашиглаж болохгүй.
diff --git a/chrome/app/resources/google_chrome_strings_mr.xtb b/chrome/app/resources/google_chrome_strings_mr.xtb
index 78d2689..98f237e 100644
--- a/chrome/app/resources/google_chrome_strings_mr.xtb
+++ b/chrome/app/resources/google_chrome_strings_mr.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">तुमचा डीफॉल्ट ब्राउझर म्हणून Google Chrome सेट करा</translation>
 <translation id="495931528404527476">Chrome मध्ये</translation>
 <translation id="4990567037958725628">Google Chrome कॅनरी</translation>
-<translation id="5028489144783860647">Google Chrome तुमचा डेटा सिंक करू शकले नाही. कृपया तुमची सिंक पासफ्रेज अपडेट करा.</translation>
 <translation id="5062123544085870375">Chrome OS रीस्टार्ट करा</translation>
 <translation id="5132929315877954718">Google Chrome साठी उत्कृष्ट ॲप, खेळ, विस्तार आणि थीम शोधा.</translation>
 <translation id="5170938038195470297">तुमचे प्रोफाइल वापरले जाणे शक्य नाही कारण ते Google Chrome च्या नवीनतम आवृत्तीमधील आहे.
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb
index f9b5b84..2e2f44a 100644
--- a/chrome/app/resources/google_chrome_strings_ms.xtb
+++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Tetapkan Google Chrome sebagai penyemak imbas lalai anda</translation>
 <translation id="495931528404527476">Dalam Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome tidak dapat menyegerakkan data anda. Sila kemas kini frasa laluan Segerak anda.</translation>
 <translation id="5062123544085870375">Mulakan semula OS Chrome</translation>
 <translation id="5132929315877954718">Temui apl, permainan, sambungan dan tema hebat untuk Google Chrome.</translation>
 <translation id="5170938038195470297">Profil anda tidak boleh digunakan kerana ia adalah dari versi Google Chrome yang lebih baharu. Beberapa ciri mungkin tidak tersedia. Sila tetapkan direktori profil lain atau gunakan versi Chrome yang lebih baharu.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_my.xtb b/chrome/app/resources/google_chrome_strings_my.xtb
index 5298b28..837d524 100644
--- a/chrome/app/resources/google_chrome_strings_my.xtb
+++ b/chrome/app/resources/google_chrome_strings_my.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome ကို သင်၏ ပုံသေ ဘရောင်ဇာ အဖြစ် သတ်မှတ်ရန်</translation>
 <translation id="495931528404527476">Chrome ထဲမှာ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome သင်၏ဒေတာကို စင့်ခ်လုပ်၍ မရပါ။ သင့်စင့်ခ်လျှို့ဝှက်စကားစုကို ကျေးဇူးပြု၍ အဆင့်မြှင့်ပါ။</translation>
 <translation id="5062123544085870375">Chrome OS ကို ပြန်လည်စတင်ပါ</translation>
 <translation id="5132929315877954718">Google Chrome အတွက် ဧရာမ အက်ပ်များ၊ ဂိမ်းများ၊ တိုးချဲ့မှုများ နှင့် အပြင်အဆင်များကို ရှာကြည့်ပါ</translation>
 <translation id="5170938038195470297">သင်၏ ပရိုဖိုင်မှာ ပိုသစ်သော Google Chrome ဗားရှင်း ထဲမှ ဖြစ်နေ၍ ၎င်းကို သုံးမရနိုင်ပါ။
diff --git a/chrome/app/resources/google_chrome_strings_ne.xtb b/chrome/app/resources/google_chrome_strings_ne.xtb
index d209090..23ee0cf 100644
--- a/chrome/app/resources/google_chrome_strings_ne.xtb
+++ b/chrome/app/resources/google_chrome_strings_ne.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Google Chrome लाई तपाइँको पूर्वनिर्धारित ब्राउजरको रूपमा सेट गर्नुहोस्</translation>
 <translation id="495931528404527476">Chrome मा</translation>
 <translation id="4990567037958725628">Google Chrome क्यानरी</translation>
-<translation id="5028489144783860647">Google Chrome ले तपाईंको डाटा समक्रमण गर्न सकेन। कृपया आफ्नो समक्रमण पासफ्रेजलाई अद्यावधिक गर्नुहोस्।</translation>
 <translation id="5062123544085870375">Chrome OS पुनः सुरु गर्नुहोस्</translation>
 <translation id="5132929315877954718">Google Chrome को लागि उत्कृष्ट एप्स, खेलहरू, एक्स्टेन्सनहरू र थिमहरू पत्ता लगाउनुहोस्।</translation>
 <translation id="5170938038195470297">तपाईंको प्रोफाइल प्रयोग गर्न सकिंदैन किनकी यो Google Chrome को नयाँ संस्करणबाट छ। केही सुविधाहरू अनुपलब्ध हुन सक्नेछन्। कृपया भिन्न प्रोफाइल डाइरेकटरी निर्दिष्ट गर्नुहोस् वा क्रोम को एक नयाँ संस्करण प्रयोग गर्नुहोस्।</translation>
diff --git a/chrome/app/resources/google_chrome_strings_nl.xtb b/chrome/app/resources/google_chrome_strings_nl.xtb
index a562d1f..e08bdf93 100644
--- a/chrome/app/resources/google_chrome_strings_nl.xtb
+++ b/chrome/app/resources/google_chrome_strings_nl.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Google Chrome instellen als je standaardbrowser</translation>
 <translation id="495931528404527476">In Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome kan je gegevens niet synchroniseren. Update je synchronisatiewachtwoord.</translation>
 <translation id="5062123544085870375">Chrome OS opnieuw opstarten</translation>
 <translation id="5132929315877954718">Ontdek fantastische apps, games, extensies en thema's voor Google Chrome.</translation>
 <translation id="5170938038195470297">Je profiel kan niet worden gebruikt omdat dit afkomstig is van een nieuwere versie van Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_no.xtb b/chrome/app/resources/google_chrome_strings_no.xtb
index 0c6a4b6..24eb156 100644
--- a/chrome/app/resources/google_chrome_strings_no.xtb
+++ b/chrome/app/resources/google_chrome_strings_no.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Bruk Google Chrome som standard nettleser</translation>
 <translation id="495931528404527476">I Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome kunne ikke synkronisere dataene dine. Oppdater passordfrasen for synkronisering.</translation>
 <translation id="5062123544085870375">Start Chrome OS på nytt</translation>
 <translation id="5132929315877954718">Oppdag flotte apper, spill, utvidelser og temaer for Google Chrome.</translation>
 <translation id="5170938038195470297">Profilen din kan ikke brukes fordi den er fra en nyere versjon av Google Chrome. Enkelte funksjoner kan være utilgjengelige. Angi en annen profilkatalog, eller bruk en nyere versjon av Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_or.xtb b/chrome/app/resources/google_chrome_strings_or.xtb
index e980a4d8..4d7b13b7 100644
--- a/chrome/app/resources/google_chrome_strings_or.xtb
+++ b/chrome/app/resources/google_chrome_strings_or.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Google Chromeକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ବ୍ରାଉଜର୍ ଭାବେ ସେଟ୍ କରନ୍ତୁ</translation>
 <translation id="495931528404527476">Chromeରେ</translation>
 <translation id="4990567037958725628">Google Chrome କ୍ୟାନାରୀ</translation>
-<translation id="5028489144783860647">Google Chrome ଆପଣଙ୍କର ଡାଟାକୁ ସିଙ୍କ୍ କରିପାରିଲା ନାହିଁ। ଦୟାକରି ଆପଣଙ୍କର ସିଙ୍କ୍ ପାସ୍‌ଫ୍ରେଜ୍ ଅପ୍‌‌ଡେଟ୍ କରନ୍ତୁ।</translation>
 <translation id="5062123544085870375">Chrome OS ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ</translation>
 <translation id="5132929315877954718">Google Chrome ପାଇଁ ଆହୁରି ଭଲ ଆପ୍, ଗେମ୍, ଏକ୍ସଟେନ୍‌ସନ୍ ଏବଂ ଥିମ୍‌ଗୁଡ଼ିକ ଖୋଜି ପାଆନ୍ତୁ।</translation>
 <translation id="5170938038195470297">ଆପଣଙ୍କର ପ୍ରୋଫାଇଲ୍ ବ୍ୟବହୃତ ହୋଇପାରିବ ନାହିଁ କାରଣ ଏହା Google Chromeର ଏକ ନୂତନ ସଂସ୍କରଣରୁ ଅଟେ।
diff --git a/chrome/app/resources/google_chrome_strings_pa.xtb b/chrome/app/resources/google_chrome_strings_pa.xtb
index 1338faa..7ee5c6e7 100644
--- a/chrome/app/resources/google_chrome_strings_pa.xtb
+++ b/chrome/app/resources/google_chrome_strings_pa.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Google Chrome ਨੂੰ ਆਪਣੇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਬ੍ਰਾਊਜ਼ਰ ਵਜੋਂ ਸੈੱਟ ਕਰੋ</translation>
 <translation id="495931528404527476">Chrome ਵਿੱਚ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ਤੁਹਾਡਾ ਡਾਟਾ ਸਿੰਕ ਨਹੀਂ ਕਰ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਸਿੰਕ ਪਾਸਫਰੇਜ਼ ਅੱਪਡੇਟ ਕਰੋ।</translation>
 <translation id="5062123544085870375">Chrome OS ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ</translation>
 <translation id="5132929315877954718">Google Chrome ਲਈ ਸ਼ਾਨਦਾਰ ਐਪਾਂ, ਗੇਮਾਂ, ਐਕਸਟੈਂਸ਼ਨਾਂ ਅਤੇ ਵਿਸ਼ੇ ਖੋਜੋ।</translation>
 <translation id="5170938038195470297">ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਨਹੀਂ ਵਰਤੀ ਜਾ ਸਕਦੀ ਕਿਉਂਕਿ ਇਹ Chromium ਦੇ ਨਵੇਂ ਵਰਜਨ ਤੋਂ ਹੈ।
diff --git a/chrome/app/resources/google_chrome_strings_pl.xtb b/chrome/app/resources/google_chrome_strings_pl.xtb
index 31a29a3..1e4e5bf 100644
--- a/chrome/app/resources/google_chrome_strings_pl.xtb
+++ b/chrome/app/resources/google_chrome_strings_pl.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Ustaw Google Chrome jako domyślną przeglądarkę</translation>
 <translation id="495931528404527476">W Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nie może zsynchronizować danych. Zaktualizuj hasło synchronizacji.</translation>
 <translation id="5062123544085870375">Uruchom ponownie Chrome OS</translation>
 <translation id="5132929315877954718">Odkryj znakomite aplikacje, gry, rozszerzenia i motywy do przeglądarki Google Chrome.</translation>
 <translation id="5170938038195470297">Nie można użyć Twojego profilu, ponieważ został utworzony w nowszej wersji Google Chrome. Niektóre funkcje mogą być niedostępne. Podaj inny katalog z profilem lub użyj nowszej wersji Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-BR.xtb b/chrome/app/resources/google_chrome_strings_pt-BR.xtb
index fb4884a8..f8d6af7 100644
--- a/chrome/app/resources/google_chrome_strings_pt-BR.xtb
+++ b/chrome/app/resources/google_chrome_strings_pt-BR.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Definir o Google Chrome como seu navegador padrão</translation>
 <translation id="495931528404527476">No Google Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">O Google Chrome não pôde sincronizar seus dados. Atualize sua senha de sincronização.</translation>
 <translation id="5062123544085870375">Reiniciar o Chrome OS</translation>
 <translation id="5132929315877954718">Descubra ótimos aplicativos, jogos, extensões e temas para o Google Chrome.</translation>
 <translation id="5170938038195470297">Seu perfil não pode ser utilizado pois foi criado em uma versão mais recente do Google Chrome. Alguns recursos podem não estar disponíveis. Especifique um diretório de perfil diferente ou utilize uma versão mais recente do Google Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-PT.xtb b/chrome/app/resources/google_chrome_strings_pt-PT.xtb
index 7a9a47c0..aa0e70f 100644
--- a/chrome/app/resources/google_chrome_strings_pt-PT.xtb
+++ b/chrome/app/resources/google_chrome_strings_pt-PT.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Definir o Google Chrome como o navegador predefinido</translation>
 <translation id="495931528404527476">No Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">O Google Chrome não conseguiu sincronizar os dados. Atualize a frase de acesso da Sincronização.</translation>
 <translation id="5062123544085870375">Reiniciar o Chrome OS</translation>
 <translation id="5132929315877954718">Descubra fantásticas aplicações, jogos, extensões e temas para o Google Chrome.</translation>
 <translation id="5170938038195470297">O seu perfil não pode ser utilizado pois pertence a uma versão mais recente do Google Chrome. Algumas funcionalidades poderão estar indisponíveis. Especifique um diretório de perfil diferente ou utilize uma versão mais recente do Google Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ro.xtb b/chrome/app/resources/google_chrome_strings_ro.xtb
index db795ff..049ee2f 100644
--- a/chrome/app/resources/google_chrome_strings_ro.xtb
+++ b/chrome/app/resources/google_chrome_strings_ro.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Setați Google Chrome ca browser prestabilit</translation>
 <translation id="495931528404527476">În Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nu a putut sincroniza datele. Actualizați expresia de acces pentru sincronizare.</translation>
 <translation id="5062123544085870375">Repornește sistemul de operare Chrome</translation>
 <translation id="5132929315877954718">Descoperă aplicații, jocuri, extensii și teme extraordinare pentru Google Chrome.</translation>
 <translation id="5170938038195470297">Profilul dvs. nu poate fi utilizat, deoarece provine de la o versiune Google Chrome mai recentă. Este posibil ca unele funcții să nu fie disponibile. Specificați un director de profil diferit sau utilizați o versiune Chrome mai nouă.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ru.xtb b/chrome/app/resources/google_chrome_strings_ru.xtb
index 751b6628..47f2f93 100644
--- a/chrome/app/resources/google_chrome_strings_ru.xtb
+++ b/chrome/app/resources/google_chrome_strings_ru.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">Сделать Google Chrome браузером по умолчанию</translation>
 <translation id="495931528404527476">В Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome не удалось синхронизировать данные. Обновите кодовую фразу в Sync.</translation>
 <translation id="5062123544085870375">Перезапуск Chrome OS</translation>
 <translation id="5132929315877954718">Широкий выбор приложений, игр, расширений и тем для Google Chrome.</translation>
 <translation id="5170938038195470297">Использовать этот профиль невозможно, так как он был создан в более новой версии Google Chrome. Некоторые функции могут быть недоступны. Укажите другой каталог профиля или установите более новую версию Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_si.xtb b/chrome/app/resources/google_chrome_strings_si.xtb
index 4571df4d..0a111d3 100644
--- a/chrome/app/resources/google_chrome_strings_si.xtb
+++ b/chrome/app/resources/google_chrome_strings_si.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">ඔබේ පෙරනිමි බ්‍රව්සරය ලෙස Google Chrome සකසන්න</translation>
 <translation id="495931528404527476">Chrome තුළ</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chromeට දත්ත සමමු කළ නොහැකි විය. සමමු රහස් වැකිය යාවත්කාලීන කරන්න.</translation>
 <translation id="5062123544085870375">Chrome OS යළි අරඹන්න</translation>
 <translation id="5132929315877954718">Google Chrome සඳහා විශිෂ්ට යෙදුම්, ක්‍රීඩා, දිගු සහ තේමා සොයා ගන්න.</translation>
 <translation id="5170938038195470297">ඔබේ පැතිකඩ Google Chrome නව සංස්කරණයකින් එන බැවින් භාවිත කළ නොහැක.
diff --git a/chrome/app/resources/google_chrome_strings_sk.xtb b/chrome/app/resources/google_chrome_strings_sk.xtb
index 06d28120..5ec7342 100644
--- a/chrome/app/resources/google_chrome_strings_sk.xtb
+++ b/chrome/app/resources/google_chrome_strings_sk.xtb
@@ -128,7 +128,6 @@
 <translation id="4953650215774548573">Nastaviť Google Chrome ako predvolený prehliadač</translation>
 <translation id="495931528404527476">V prehliadači Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Prehliadaču Google Chrome sa nepodarilo synchronizovať vaše údaje. Aktualizujte prístupovú frázu synchronizácie.</translation>
 <translation id="5062123544085870375">Reštartovanie Chrome OS</translation>
 <translation id="5132929315877954718">Objavte skvelé aplikácie, hry, rozšírenia a motívy pre prehliadač Google Chrome.</translation>
 <translation id="5170938038195470297">Váš profil sa nedá použiť, pretože pochádza z novšej verzie prehliadača Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_sl.xtb b/chrome/app/resources/google_chrome_strings_sl.xtb
index 5864d43b..1beb932 100644
--- a/chrome/app/resources/google_chrome_strings_sl.xtb
+++ b/chrome/app/resources/google_chrome_strings_sl.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Nastavitev Google Chroma za privzeti brskalnik</translation>
 <translation id="495931528404527476">V Chromu</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ni mogel sinhronizirati podatkov. Posodobite geslo za sinhroniziranje.</translation>
 <translation id="5062123544085870375">Vnovičen zagon OS-a Chrome</translation>
 <translation id="5132929315877954718">Odkrijte zanimive aplikacije, igre, razširitve in teme za Google Chrome.</translation>
 <translation id="5170938038195470297">Vašega profila ni mogoče uporabiti, ker je iz novejše različice Google Chroma.
diff --git a/chrome/app/resources/google_chrome_strings_sq.xtb b/chrome/app/resources/google_chrome_strings_sq.xtb
index 159c461a..bab450c 100644
--- a/chrome/app/resources/google_chrome_strings_sq.xtb
+++ b/chrome/app/resources/google_chrome_strings_sq.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Caktoje Google Chrome si shfletuesin tënd të parazgjedhur</translation>
 <translation id="495931528404527476">Në Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome nuk mundi të sinkronizonte të dhënat e tua. Përditëso shprehjen e kalimit për sinkronizim.</translation>
 <translation id="5062123544085870375">Rinis Chrome OS</translation>
 <translation id="5132929315877954718">Zbulo aplikacione, lojëra, shtesa dhe tema të mrekullueshme për Google Chrome.</translation>
 <translation id="5170938038195470297">Profili yt nuk mund të përdoret sepse është nga një version më i ri i Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_sr.xtb b/chrome/app/resources/google_chrome_strings_sr.xtb
index 73a7ba6..a498eaa 100644
--- a/chrome/app/resources/google_chrome_strings_sr.xtb
+++ b/chrome/app/resources/google_chrome_strings_sr.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Подеси Google Chrome као подразумевани прегледач</translation>
 <translation id="495931528404527476">У Chrome-у</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome не може да синхронизује податке. Ажурирајте приступну фразу за Синхронизацију.</translation>
 <translation id="5062123544085870375">Рестартујте Chrome ОС</translation>
 <translation id="5132929315877954718">Откријте одличне апликације, игре, додатке и теме за Google Chrome.</translation>
 <translation id="5170938038195470297">Профил не може да се користи јер је из новије верзије Google Chrome-а.
diff --git a/chrome/app/resources/google_chrome_strings_sv.xtb b/chrome/app/resources/google_chrome_strings_sv.xtb
index 5149f53e..6fd39ea 100644
--- a/chrome/app/resources/google_chrome_strings_sv.xtb
+++ b/chrome/app/resources/google_chrome_strings_sv.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Ange Google Chrome som standardwebbläsare</translation>
 <translation id="495931528404527476">I Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome kunde inte synkronisera data. Uppdatera lösenfrasen för synkroniseringen.</translation>
 <translation id="5062123544085870375">Starta om Chrome OS</translation>
 <translation id="5132929315877954718">Upptäck fantastiska program, spel, tillägg och teman för Google Chrome.</translation>
 <translation id="5170938038195470297">Profilen kan inte användas eftersom den tillhör en nyare version av Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_sw.xtb b/chrome/app/resources/google_chrome_strings_sw.xtb
index d270a6e..4b64f71 100644
--- a/chrome/app/resources/google_chrome_strings_sw.xtb
+++ b/chrome/app/resources/google_chrome_strings_sw.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">Weka Google Chrome iwe kivinjari chako chaguomsingi</translation>
 <translation id="495931528404527476">Katika Chrome</translation>
 <translation id="4990567037958725628">Kanari ya Google Chrome</translation>
-<translation id="5028489144783860647">Google Chrome haikuweza kusawazisha data yako. Tafadhali sasisha kauli siri yako ya Usawazishaji.</translation>
 <translation id="5062123544085870375">Zima kisha uwashe mfumo wa uendeshaji wa Chrome</translation>
 <translation id="5132929315877954718">Gundua programu, michezo, viendelezi na mandhari bora ya Google Chrome.</translation>
 <translation id="5170938038195470297">Wasifu wako huenda usitumike kwa sababu unatoka katika toleo jipya la Google Chrome.
diff --git a/chrome/app/resources/google_chrome_strings_ta.xtb b/chrome/app/resources/google_chrome_strings_ta.xtb
index 01951b5..eafc3ffb 100644
--- a/chrome/app/resources/google_chrome_strings_ta.xtb
+++ b/chrome/app/resources/google_chrome_strings_ta.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Google Chrome ஐ உங்கள் இயல்புநிலை உலாவியாக அமைக்கவும்</translation>
 <translation id="495931528404527476">Chrome இல்</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">உங்கள் தரவை Google Chrome ஆல் ஒத்திசைக்க முடியவில்லை. உங்கள் கடவுச்சொற்றொடரைப் புதுப்பிக்கவும்.</translation>
 <translation id="5062123544085870375">Chrome OSஸை மீண்டும் தொடங்கவும்</translation>
 <translation id="5132929315877954718">Google Chrome க்கான சிறந்த ஆப்ஸ், கேம்ஸ், நீட்டிப்புகள் மற்றும் தீம்களைக் கண்டறியவும்.</translation>
 <translation id="5170938038195470297">Google Chrome இன் புத்தம் புதிய பதிப்பு என்பதால், உங்கள் சுயவிவரத்தைப் பயன்படுத்த முடியாது. சில அம்சங்கள் கிடைக்காமல் போகலாம். வேறு சுயவிவர கோப்பகத்தைக் குறிப்பிடுக அல்லது Chrome இன் புதிய பதிப்பைப் பயன்படுத்துக.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_te.xtb b/chrome/app/resources/google_chrome_strings_te.xtb
index 81f9564..e4a914d 100644
--- a/chrome/app/resources/google_chrome_strings_te.xtb
+++ b/chrome/app/resources/google_chrome_strings_te.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Google Chromeను మీ డిఫాల్ట్ బ్రౌజర్‌గా సెట్ చేయండి</translation>
 <translation id="495931528404527476">Chromeలో</translation>
 <translation id="4990567037958725628">Google Chrome కేనరీ</translation>
-<translation id="5028489144783860647">Google Chrome మీ డేటాను సింక్ చేయ‌లేక‌పోయింది. దయచేసి మీ సింక్‌ రహస్య పదబంధాన్ని అప్‌డేట్ చేయండి.</translation>
 <translation id="5062123544085870375">Chrome OSను మళ్లీ ప్రారంభించండి</translation>
 <translation id="5132929315877954718">Google Chrome కోసం గొప్ప అనువర్తనాలు, ఆటలు, పొడిగింపులు మరియు థీమ్‌లను కనుగొనండి.</translation>
 <translation id="5170938038195470297">మీ ప్రొఫైల్‌ను ఉపయోగించడం సాధ్యపడదు, ఎందుకంటే ఇది ఒక కొత్త Google Chrome వెర్షన్ నుండి తీసుకోబడింది. కొన్ని ఫీచర్‌లు అందుబాటులో ఉండకపోవచ్చు. దయచేసి వేరొక ప్రొఫైల్ డైరెక్టరీని పేర్కొనండి లేదా Chrome కొత్త వెర్షన్‌ను ఉపయోగించండి.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_th.xtb b/chrome/app/resources/google_chrome_strings_th.xtb
index 734ed332..0a5b2f4c 100644
--- a/chrome/app/resources/google_chrome_strings_th.xtb
+++ b/chrome/app/resources/google_chrome_strings_th.xtb
@@ -126,7 +126,6 @@
 <translation id="4953650215774548573">ตั้ง Google Chrome เป็นเบราว์เซอร์เริ่มต้นของคุณ</translation>
 <translation id="495931528404527476">ใน Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ไม่สามารถซิงค์ข้อมูลของคุณ โปรดอัปเดตข้อความรหัสผ่านการซิงค์</translation>
 <translation id="5062123544085870375">รีสตาร์ท Chrome OS</translation>
 <translation id="5132929315877954718">พบกับแอป เกม ส่วนขยาย และธีมเด็ดๆ สำหรับ Google Chrome</translation>
 <translation id="5170938038195470297">โปรไฟล์ของคุณไม่สามารถใช้ได้เพราะมาจากรุ่นที่ใหม่กว่าของ Google Chrome ฟีเจอร์บางอย่างอาจจะไม่พร้อมใช้งาน โปรดระบุไดเรกทอรีของโปรไฟล์อื่นหรือใช้ Chrome รุ่นที่ใหม่กว่า</translation>
diff --git a/chrome/app/resources/google_chrome_strings_tr.xtb b/chrome/app/resources/google_chrome_strings_tr.xtb
index 077b803e..937f72fd 100644
--- a/chrome/app/resources/google_chrome_strings_tr.xtb
+++ b/chrome/app/resources/google_chrome_strings_tr.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Google Chrome'u varsayılan tarayıcım olarak ayarla</translation>
 <translation id="495931528404527476">Chrome'da</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome, verilerinizi senkronize edemedi. Lütfen Senkronizasyon parolanızı güncelleyin.</translation>
 <translation id="5062123544085870375">Chrome OS'i yeniden başlat</translation>
 <translation id="5132929315877954718">Google Chrome'a özgü harika uygulamaları, oyunları, uzantıları ve temaları keşfedin.</translation>
 <translation id="5170938038195470297">Profiliniz daha yeni bir Google Chrome sürümünden geldiği için kullanılamıyor.
diff --git a/chrome/app/resources/google_chrome_strings_uk.xtb b/chrome/app/resources/google_chrome_strings_uk.xtb
index 3dfe6c3..e0143bf 100644
--- a/chrome/app/resources/google_chrome_strings_uk.xtb
+++ b/chrome/app/resources/google_chrome_strings_uk.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">Зробити Google Chrome веб-переглядачем за умовчанням</translation>
 <translation id="495931528404527476">У Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome не вдалося синхронізувати ваші дані. Оновіть свою парольну фразу для синхронізації.</translation>
 <translation id="5062123544085870375">Перезапустіть ОС Chrome</translation>
 <translation id="5132929315877954718">Знаходьте чудові додатки, ігри, розширення й теми для Google Chrome.</translation>
 <translation id="5170938038195470297">Ваш профіль не можна використати, оскільки його створено в новішій версії Google Chrome. Деякі функції можуть бути недоступними. Укажіть інший каталог профілю чи скористайтеся новішою версією Chrome.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ur.xtb b/chrome/app/resources/google_chrome_strings_ur.xtb
index dfb3c22..aab24b84 100644
--- a/chrome/app/resources/google_chrome_strings_ur.xtb
+++ b/chrome/app/resources/google_chrome_strings_ur.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">‏Google Chrome کو اپنے ڈیفالٹ براؤزر کے بطور سیٹ کریں</translation>
 <translation id="495931528404527476">‏Chrome میں</translation>
 <translation id="4990567037958725628">‏Google Chrome کینیری</translation>
-<translation id="5028489144783860647">‏Google Chrome آپ کے ڈیٹا کی مطابقت پذیری نہیں کر سکا۔ براہ کرم اپنے Sync پاس فریز کو اپ ڈیٹ کریں کریں۔</translation>
 <translation id="5062123544085870375">‏Chrome OS کو ری سٹارٹ کریں</translation>
 <translation id="5132929315877954718">‏Google Chrome کیلئے زبردست اطلاقات، گیمز، ایکسٹینشنز اور تھیمز کو دریافت کریں۔</translation>
 <translation id="5170938038195470297">‏آپ کا پروفائل استعمال نہیں کیا جا سکتا ہے کیونکہ یہ Google Chrome کے ایک جدید تر ورژن سے ہے۔
diff --git a/chrome/app/resources/google_chrome_strings_uz.xtb b/chrome/app/resources/google_chrome_strings_uz.xtb
index 5a8e3101..c2c6203b 100644
--- a/chrome/app/resources/google_chrome_strings_uz.xtb
+++ b/chrome/app/resources/google_chrome_strings_uz.xtb
@@ -128,7 +128,6 @@
 <translation id="4953650215774548573">Google Chrome‘ni standart brauzer etib tayinlash</translation>
 <translation id="495931528404527476">Chrome brauzerida</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome ma’lumotlarni sinxronlay olmadi. Sync kodli iborasini yangilashingiz kerak.</translation>
 <translation id="5062123544085870375">Chrome OS tizimini qayta ishga tushirish</translation>
 <translation id="5132929315877954718">Google Chrome uchun zo‘r ilovalar, o‘yinlar, kengaytmalar va mavzular bilan tanishing.</translation>
 <translation id="5170938038195470297">Profilingizdan foydalanib bo‘lmaydi, chunki u yanada yangiroq Google Chrome versiyasiga ta’luqli.
diff --git a/chrome/app/resources/google_chrome_strings_vi.xtb b/chrome/app/resources/google_chrome_strings_vi.xtb
index 8ba1037..6f5970d 100644
--- a/chrome/app/resources/google_chrome_strings_vi.xtb
+++ b/chrome/app/resources/google_chrome_strings_vi.xtb
@@ -129,7 +129,6 @@
 <translation id="4953650215774548573">Đặt Google Chrome làm trình duyệt mặc định của bạn</translation>
 <translation id="495931528404527476">Trong Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome không thể đồng bộ hóa dữ liệu của bạn. Vui lòng cập nhật cụm mật khẩu Đồng bộ hóa của bạn.</translation>
 <translation id="5062123544085870375">Khởi động lại Chrome OS</translation>
 <translation id="5132929315877954718">Khám phá các ứng dụng, trò chơi, tiện ích và chủ đề tuyệt vời cho Google Chrome.</translation>
 <translation id="5170938038195470297">Không thể sử dụng hồ sơ của bạn vì hồ sơ được tạo từ phiên bản Google Chrome mới hơn.
diff --git a/chrome/app/resources/google_chrome_strings_zh-CN.xtb b/chrome/app/resources/google_chrome_strings_zh-CN.xtb
index 2432e94..6ff6750 100644
--- a/chrome/app/resources/google_chrome_strings_zh-CN.xtb
+++ b/chrome/app/resources/google_chrome_strings_zh-CN.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">将Google Chrome设为默认浏览器</translation>
 <translation id="495931528404527476">在 Chrome 中</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome无法同步您的数据。请更新您的同步密码。</translation>
 <translation id="5062123544085870375">重启 Chrome 操作系统</translation>
 <translation id="5132929315877954718">查找适用于Google Chrome的精彩应用、游戏、扩展程序和主题背景。</translation>
 <translation id="5170938038195470297">您的个人资料来自新版 Google Chrome 浏览器,因此无法使用。某些功能可能无法使用。请指定其他个人资料目录,或使用新版 Chrome 浏览器。</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-HK.xtb b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
index 99c9218..c8e34bf 100644
--- a/chrome/app/resources/google_chrome_strings_zh-HK.xtb
+++ b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
@@ -130,7 +130,6 @@
 <translation id="4953650215774548573">將 Google Chrome 設為預設瀏覽器</translation>
 <translation id="495931528404527476">在 Chrome 中</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome 無法同步您的數據。請更新您的同步複雜密碼。</translation>
 <translation id="5062123544085870375">重新啟動 Chrome 作業系統</translation>
 <translation id="5132929315877954718">為您的 Google Chrome 探索各種實用有趣的應用程式、遊戲、擴充功能和主題。</translation>
 <translation id="5170938038195470297">由於您的設定檔是來自較新版本的 Google Chrome,所以系統無法使用該檔案。
diff --git a/chrome/app/resources/google_chrome_strings_zh-TW.xtb b/chrome/app/resources/google_chrome_strings_zh-TW.xtb
index 06bd3cf..350b13c4 100644
--- a/chrome/app/resources/google_chrome_strings_zh-TW.xtb
+++ b/chrome/app/resources/google_chrome_strings_zh-TW.xtb
@@ -127,7 +127,6 @@
 <translation id="4953650215774548573">將 Google Chrome 設為預設瀏覽器</translation>
 <translation id="495931528404527476">在 Chrome 中</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
-<translation id="5028489144783860647">Google Chrome 無法同步處理你的資料,請更新你的同步通關密語。</translation>
 <translation id="5062123544085870375">重新啟動 Chrome 作業系統</translation>
 <translation id="5132929315877954718">幫你的 Google Chrome 物色各種實用有趣的應用程式、遊戲、擴充功能和主題。</translation>
 <translation id="5170938038195470297">由於你的設定檔是來自較新版本的 Google Chrome,所以系統無法使用該檔案。這表示你可能無法使用部分功能。請指定另一個設定檔目錄,或使用較新版本的 Google Chrome。</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zu.xtb b/chrome/app/resources/google_chrome_strings_zu.xtb
index f3b65f8..19538cf 100644
--- a/chrome/app/resources/google_chrome_strings_zu.xtb
+++ b/chrome/app/resources/google_chrome_strings_zu.xtb
@@ -131,7 +131,6 @@
 <translation id="4953650215774548573">Setha i-Google Chrome njengesiphequluli sakho sokuzenzakalelayo</translation>
 <translation id="495931528404527476">Ku-Chrome</translation>
 <translation id="4990567037958725628">I-Canary ye-Google Chrome</translation>
-<translation id="5028489144783860647">I-Google Chrome ayikwazanga ukuvumelanisa idatha yakho. Sicela ubuyekeze umushwana wakho wokungena wokuvumelanisa.</translation>
 <translation id="5062123544085870375">Qalisa kabusha i-Chrome OS</translation>
 <translation id="5132929315877954718">Thola izinhlelo zokusebenza ezinhle, amageyimu, izandiso namatimu e-Google Chrome.</translation>
 <translation id="5170938038195470297">Iphrofayela yakho ayikwazi ukusetshenziswa ngoba isuka kunguqulo entsha ye-Google Chrome.
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 3f78537..ac798bc 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -54,7 +54,10 @@
       Update schedule
     </message>
     <message name="IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE" desc="Message used for End of Life section on the About Page.">
-      This device will get automatic software and security updates until <ph name="MONTH_AND_YEAR">$1<ex>September 2020</ex></ph>.
+      This device will get automatic software and security updates until <ph name="MONTH_AND_YEAR">$1<ex>September 2020</ex></ph>. &lt;a target="_blank" href="<ph name="URL">$2<ex>https://google.com/</ex></ph>"&gt;Learn more&lt;/a&gt;
+    </message>
+    <message name="IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE" desc="Message shown on the top level about page to inform the user that this device will no longer receive latest software updates.">
+      This is the last automatic software and security update for this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. To get future updates, upgrade to a newer model. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_ABOUT_PAGE_RELAUNCH" desc="The label for the relaunch button that relaunches the browser once update is complete">
       Restart
@@ -443,7 +446,7 @@
       Play sound on startup
     </message>
     <message name="IDS_SETTINGS_ACCESSIBILITY_EXPLANATION" desc="Informational message at the top of the accessibility section of the settings page about enabling additional accessibility-related features.">
-      Enable accessibility features to make your device easier to use.
+      Enable accessibility features to make your device easier to use. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE" desc="In the settings tab, the title of a link that adds additional accessibility features not found in the built-in settings.">
       Add additional features
@@ -1521,13 +1524,13 @@
       Printers
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL" desc="Label for the link that teaches users how to use CUPS printing.">
-      Set up or manage CUPS printers.
+      Set up or manage CUPS printers. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER" desc="In CUPS printing settings subpage, text for the link adding a new CUPS printer.">
       Add Printer
     </message>
      <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_DETECTED_OR_NEW_PRINTER" desc="In CUPS printing settings subpage, explanatory text for the nearby printers list.">
-      Save detected printers to your profile, or add a new printer.
+      Save detected printers to your profile, or add a new printer. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS" desc="In CUPS printing settings subpage, title for the nearby printers list.">
       Add printers to your profile
@@ -1653,7 +1656,7 @@
       Manufacturer
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_DRIVER" desc="Label for the file selector to manually select a PPD file from the user's file system.">
-      Or specify your printer PPD
+      Or specify your printer PPD <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER_ARIA_LABEL" desc="ARIA label for the file selector button to manually select a PPD file from the user's file system. This text will not be visual on any page. It will only be spoken by screen readers.">
       Browse to specify your printer PPD
@@ -1728,7 +1731,7 @@
       Current PPD file in use: <ph name="PPD_NAME">$1<ex>example.ppd.gz</ex></ph>
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_MANUFACTURER_MODEL_ADDITIONAL_INFORMATION" desc="Informational text displayed to the user when the the user is doing advanced manual printer setup.">
-      <ph name="PRINTER_NAME">$1<ex>Printer</ex></ph> could not be configured automatically. Please specify advanced printer details.
+      <ph name="PRINTER_NAME">$1<ex>Printer</ex></ph> could not be configured automatically. Please specify advanced printer details. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_EULA_NOTICE" desc="The message shown to users if a printer has a EULA agreement attached to it.">
       End User License Agreement
@@ -1777,7 +1780,7 @@
       Network file shares
     </message>
     <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL" desc="Label for the link that teaches users how to setup SMB shares.">
-      Set up or manage network file shares.
+      Set up or manage network file shares. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE" desc="In SMB shares settings subpage, text for the link to add a new SMB share.">
       Add file share
@@ -2854,9 +2857,8 @@
     Show language options
   </message>
   <if expr="chromeos">
-    <!-- Ends with "." because a "Learn more" link appears next to it. -->
     <message name="IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS" desc="Explanatory message about ordering the list of languages.">
-      Add languages or reorder list.
+      Add languages or reorder list. <ph name="BEGIN_LINK">&lt;a&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
     </message>
     <!-- The non-Chrome OS string is in settings_google_chrome_strings.grdp -->
     <message name="IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE" desc="The label for a language that is currently used as the UI display language.">
@@ -3124,7 +3126,7 @@
       Remove all user accounts and reset your <ph name="IDS_SHORT_PRODUCT_NAME">$1<ex>Chrome</ex></ph> device to be just like new.
     </message>
     <message name="IDS_SETTINGS_FACTORY_RESET_WARNING" desc="Warning text in the 'Factory Reset' window">
-      A restart is required before your device can be reset with Powerwash.
+      A restart is required before your device can be reset with Powerwash. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
     </message>
     <message name="IDS_SETTINGS_FACTORY_RESET_BUTTON_LABEL" desc="Label for the factory reset button.">
       Reset
@@ -4030,7 +4032,7 @@
       Add account
     </message>
     <message name="IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION" desc="Description of the Account Manager Settings page. Shown just below the title of the page.">
-      Manage your signed-in accounts. Websites, apps, and extensions in Chrome and Google Play may use these accounts to customize your experience, depending on permissions.
+      Manage your signed-in accounts. Websites, apps, and extensions in Chrome and Google Play may use these accounts to customize your experience, depending on permissions. &lt;a&gt;Learn more&lt;/a&gt;
     </message>
     <message name="IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER" desc="List header for Account List in Account Manager Settings page.">
       Accounts
@@ -4233,7 +4235,7 @@
   </if>
 
   <message name="IDS_SETTINGS_SYNC_OVERVIEW" desc="The message that appears in the options dialog when sync has not been set up by the user.">
-    Sign in to get your bookmarks, history, passwords, and other settings on all your devices. You'll also automatically be signed in to your Google services.
+    Sign in to get your bookmarks, history, passwords, and other settings on all your devices. You'll also automatically be signed in to your Google services. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
   </message>
   <message name="IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION" desc="The text to display in the Sign out of Chrome dialog to stop syncing for non-managed profiles.">
     Changes to your bookmarks, history, passwords, and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google Account and can be managed on <ph name="BEGIN_LINK">&lt;a href="$1" target=&quot;_blank&quot;&gt;<ex>&lt;a href="$1" target=&quot;_blank&quot;&gt;</ex></ph>Google Dashboard<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c34c3f4..f90001f 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -922,6 +922,8 @@
     "net_benchmarking.h",
     "nfc/nfc_permission_context.cc",
     "nfc/nfc_permission_context.h",
+    "nfc/nfc_permission_context_android.cc",
+    "nfc/nfc_permission_context_android.h",
     "notifications/alert_dispatcher_mac.h",
     "notifications/metrics/notification_metrics_logger.cc",
     "notifications/metrics/notification_metrics_logger.h",
@@ -1985,6 +1987,7 @@
     "//chrome/browser/resource_coordinator:mojo_bindings",
     "//chrome/browser/resource_coordinator:tab_manager_features",
     "//chrome/browser/safe_browsing",
+    "//chrome/browser/sharing/proto",
     "//chrome/browser/ssl:proto",
     "//chrome/browser/touch_to_fill",
     "//chrome/browser/ui",
@@ -2558,6 +2561,9 @@
       "android/mojo/chrome_interface_registrar_android.h",
       "android/net/nqe/network_quality_provider.cc",
       "android/net/nqe/network_quality_provider.h",
+      "android/nfc_system_level_setting.h",
+      "android/nfc_system_level_setting_impl.cc",
+      "android/nfc_system_level_setting_impl.h",
       "android/ntp/get_remote_suggestions_scheduler.cc",
       "android/ntp/get_remote_suggestions_scheduler.h",
       "android/ntp/most_visited_sites_bridge.cc",
@@ -3719,6 +3725,8 @@
       "download/notification/download_item_notification.h",
       "download/notification/download_notification_manager.cc",
       "download/notification/download_notification_manager.h",
+      "enterprise_reporting/android_app_info_generator.cc",
+      "enterprise_reporting/android_app_info_generator.h",
       "feedback/feedback_util_chromeos.cc",
       "feedback/feedback_util_chromeos.h",
       "google/google_brand_chromeos.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index d3f5c12e..54c97b3 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -647,11 +647,6 @@
          kInterestFeedLargeImagesAndSnippetsWithUndoableActionsFeatureVariationConstant),
      nullptr}};
 
-const FeatureEntry::FeatureVariation kRemoteSuggestionsFeatureVariations[] = {
-    {"via content suggestion server (backed by ChromeReader)", nullptr, 0,
-     "3313421"},
-    {"via content suggestion server (backed by Google Now)", nullptr, 0,
-     "3313422"}};
 #endif  // OS_ANDROID
 
 const FeatureEntry::Choice kEnableUseZoomForDSFChoices[] = {
@@ -1813,7 +1808,7 @@
      FEATURE_VALUE_TYPE(device::kNewblueDaemon)},
     {"shelf-hotseat", flag_descriptions::kShelfHotseatName,
      flag_descriptions::kShelfHotseatDescription, kOsCrOS,
-     SINGLE_VALUE_TYPE(chromeos::switches::kShelfHotseat)},
+     FEATURE_VALUE_TYPE(chromeos::features::kShelfHotseat)},
     {"shelf-hover-previews", flag_descriptions::kShelfHoverPreviewsName,
      flag_descriptions::kShelfHoverPreviewsDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(chromeos::switches::kShelfHoverPreviews)},
@@ -2479,12 +2474,6 @@
      flag_descriptions::kInterestFeedNotificationsName,
      flag_descriptions::kInterestFeedNotificationsDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(feed::kInterestFeedNotifications)},
-    {"enable-ntp-remote-suggestions",
-     flag_descriptions::kEnableNtpRemoteSuggestionsName,
-     flag_descriptions::kEnableNtpRemoteSuggestionsDescription, kOsAndroid,
-     FEATURE_WITH_PARAMS_VALUE_TYPE(ntp_snippets::kArticleSuggestionsFeature,
-                                    kRemoteSuggestionsFeatureVariations,
-                                    "NTPArticleSuggestions")},
     {"offlining-recent-pages", flag_descriptions::kOffliningRecentPagesName,
      flag_descriptions::kOffliningRecentPagesDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(offline_pages::kOffliningRecentPagesFeature)},
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 9165076..667eba0 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -23,6 +23,7 @@
 #include "components/content_settings/core/common/features.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
 #include "components/download/public/common/download_features.h"
+#include "components/feature_engagement/public/feature_list.h"
 #include "components/feed/feed_feature_list.h"
 #include "components/invalidation/impl/invalidation_switches.h"
 #include "components/language/core/common/language_experiments.h"
@@ -85,6 +86,9 @@
     &features::kWebAuth,
     &features::kWebNfc,
     &features::kWebPayments,
+    &feature_engagement::kIPHChromeDuetHomeButtonFeature,
+    &feature_engagement::kIPHChromeDuetSearchFeature,
+    &feature_engagement::kIPHChromeDuetTabSwitcherFeature,
     &feed::kInterestFeedContentSuggestions,
     &kAdjustWebApkInstallationSpace,
     &kAllowNewIncognitoTabIntents,
@@ -271,7 +275,7 @@
     "AllowNewIncognitoTabIntents", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kFocusOmniboxInIncognitoTabIntents{
-    "FocusOmniboxInIncognitoTabIntents", base::FEATURE_DISABLED_BY_DEFAULT};
+    "FocusOmniboxInIncognitoTabIntents", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kAllowRemoteContextForNotifications{
     "AllowRemoteContextForNotifications", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/mock_nfc_system_level_setting.cc b/chrome/browser/android/mock_nfc_system_level_setting.cc
new file mode 100644
index 0000000..8f94a09d
--- /dev/null
+++ b/chrome/browser/android/mock_nfc_system_level_setting.cc
@@ -0,0 +1,50 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/mock_nfc_system_level_setting.h"
+
+namespace {
+
+static bool nfc_access_is_possible_ = false;
+static bool is_nfc_setting_enabled_ = false;
+static bool has_shown_nfc_setting_prompt_ = false;
+
+}  // namespace
+
+MockNfcSystemLevelSetting::MockNfcSystemLevelSetting()
+    : NfcSystemLevelSetting() {}
+
+MockNfcSystemLevelSetting::~MockNfcSystemLevelSetting() {}
+
+void MockNfcSystemLevelSetting::SetNfcAccessIsPossible(bool is_possible) {
+  nfc_access_is_possible_ = is_possible;
+}
+
+void MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(
+    bool is_enabled) {
+  is_nfc_setting_enabled_ = is_enabled;
+}
+
+bool MockNfcSystemLevelSetting::HasShownNfcSettingPrompt() {
+  return has_shown_nfc_setting_prompt_;
+}
+
+void MockNfcSystemLevelSetting::ClearHasShownNfcSettingPrompt() {
+  has_shown_nfc_setting_prompt_ = false;
+}
+
+bool MockNfcSystemLevelSetting::IsNfcAccessPossible() {
+  return nfc_access_is_possible_;
+}
+
+bool MockNfcSystemLevelSetting::IsNfcSystemLevelSettingEnabled() {
+  return is_nfc_setting_enabled_;
+}
+
+void MockNfcSystemLevelSetting::PromptToEnableNfcSystemLevelSetting(
+    content::WebContents* web_contents,
+    base::OnceClosure prompt_completed_callback) {
+  has_shown_nfc_setting_prompt_ = true;
+  std::move(prompt_completed_callback).Run();
+}
diff --git a/chrome/browser/android/mock_nfc_system_level_setting.h b/chrome/browser/android/mock_nfc_system_level_setting.h
new file mode 100644
index 0000000..440b22d
--- /dev/null
+++ b/chrome/browser/android/mock_nfc_system_level_setting.h
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_MOCK_NFC_SYSTEM_LEVEL_SETTING_H_
+#define CHROME_BROWSER_ANDROID_MOCK_NFC_SYSTEM_LEVEL_SETTING_H_
+
+#include "base/macros.h"
+#include "chrome/browser/android/nfc_system_level_setting.h"
+
+// Mock implementation of NfcSystemLevelSetting for unit tests.
+class MockNfcSystemLevelSetting : public NfcSystemLevelSetting {
+ public:
+  MockNfcSystemLevelSetting();
+  ~MockNfcSystemLevelSetting() override;
+
+  static void SetNfcAccessIsPossible(bool is_possible);
+  static void SetNfcSystemLevelSettingEnabled(bool is_enabled);
+  static bool HasShownNfcSettingPrompt();
+  static void ClearHasShownNfcSettingPrompt();
+
+  // NfcSystemLevelSetting implementation:
+  bool IsNfcAccessPossible() override;
+  bool IsNfcSystemLevelSettingEnabled() override;
+  void PromptToEnableNfcSystemLevelSetting(
+      content::WebContents* web_contents,
+      base::OnceClosure prompt_completed_callback) override;
+
+  DISALLOW_COPY_AND_ASSIGN(MockNfcSystemLevelSetting);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_MOCK_NFC_SYSTEM_LEVEL_SETTING_H_
diff --git a/chrome/browser/android/nfc_system_level_setting.h b/chrome/browser/android/nfc_system_level_setting.h
new file mode 100644
index 0000000..0ba5e42
--- /dev/null
+++ b/chrome/browser/android/nfc_system_level_setting.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_H_
+#define CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+
+namespace content {
+class WebContents;
+}
+
+// This class determines whether NFC is enabled system-wide on the device.
+class NfcSystemLevelSetting {
+ public:
+  virtual ~NfcSystemLevelSetting() {}
+
+  // Returns true if the NFC system level setting can be enabled.
+  virtual bool IsNfcAccessPossible() = 0;
+
+  // Returns true if the NFC system level setting is enabled.
+  virtual bool IsNfcSystemLevelSettingEnabled() = 0;
+
+  // Triggers a prompt to ask the user to turn on the system NFC setting on
+  // their device, and invokes callback when prompt is completed.
+  //
+  // The prompt will be triggered in the activity of the web contents.
+  //
+  // The callback is guaranteed to be called unless the user never replies to
+  // the prompt dialog, which in practice happens very infrequently since the
+  // dialog is modal.
+  //
+  // The callback may be invoked a long time after this method has returned.
+  // If you need to access in the callback an object that is not owned by the
+  // callback, you should ensure that the object has not been destroyed before
+  // accessing it to prevent crashes, e.g. by using weak pointer semantics.
+  virtual void PromptToEnableNfcSystemLevelSetting(
+      content::WebContents* web_contents,
+      base::OnceClosure prompt_completed_callback) = 0;
+};
+
+#endif  // CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_H_
diff --git a/chrome/browser/android/nfc_system_level_setting_impl.cc b/chrome/browser/android/nfc_system_level_setting_impl.cc
new file mode 100644
index 0000000..276f201
--- /dev/null
+++ b/chrome/browser/android/nfc_system_level_setting_impl.cc
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/nfc_system_level_setting_impl.h"
+
+#include "base/android/jni_android.h"
+#include "chrome/android/chrome_jni_headers/NfcSystemLevelSetting_jni.h"
+#include "content/public/browser/web_contents.h"
+
+NfcSystemLevelSettingImpl::NfcSystemLevelSettingImpl() {}
+
+NfcSystemLevelSettingImpl::~NfcSystemLevelSettingImpl() {}
+
+bool NfcSystemLevelSettingImpl::IsNfcAccessPossible() {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_NfcSystemLevelSetting_isNfcAccessPossible(env);
+}
+
+bool NfcSystemLevelSettingImpl::IsNfcSystemLevelSettingEnabled() {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_NfcSystemLevelSetting_isNfcSystemLevelSettingEnabled(env);
+}
+
+void NfcSystemLevelSettingImpl::PromptToEnableNfcSystemLevelSetting(
+    content::WebContents* web_contents,
+    base::OnceClosure prompt_completed_callback) {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  // Transfers the ownership of the callback to the Java callback. The Java
+  // callback is guaranteed to be called unless the user never replies to the
+  // dialog, and the callback pointer will be destroyed in
+  // NfcSystemLevelPrompt.onDismiss.
+  auto* callback_ptr =
+      new base::OnceClosure(std::move(prompt_completed_callback));
+  Java_NfcSystemLevelSetting_promptToEnableNfcSystemLevelSetting(
+      env, web_contents->GetJavaWebContents(),
+      reinterpret_cast<jlong>(callback_ptr));
+}
+
+static void JNI_NfcSystemLevelSetting_OnNfcSystemLevelPromptCompleted(
+    JNIEnv* env,
+    jlong callback_ptr) {
+  auto* callback = reinterpret_cast<base::OnceClosure*>(callback_ptr);
+  std::move(*callback).Run();
+  // Destroy the callback whose ownership was transferred in
+  // PromptToEnableNfcSystemLevelSetting.
+  delete callback;
+}
diff --git a/chrome/browser/android/nfc_system_level_setting_impl.h b/chrome/browser/android/nfc_system_level_setting_impl.h
new file mode 100644
index 0000000..f43fd3c
--- /dev/null
+++ b/chrome/browser/android/nfc_system_level_setting_impl.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_IMPL_H_
+#define CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_IMPL_H_
+
+#include <memory>
+
+#include "base/android/jni_weak_ref.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
+#include "chrome/browser/android/nfc_system_level_setting.h"
+
+class NfcSystemLevelSettingImpl : public NfcSystemLevelSetting {
+ public:
+  NfcSystemLevelSettingImpl();
+  ~NfcSystemLevelSettingImpl() override;
+
+  // NfcSystemLevelSetting implementation:
+  bool IsNfcAccessPossible() override;
+  bool IsNfcSystemLevelSettingEnabled() override;
+  void PromptToEnableNfcSystemLevelSetting(
+      content::WebContents* web_contents,
+      base::OnceClosure prompt_completed_callback) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NfcSystemLevelSettingImpl);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_NFC_SYSTEM_LEVEL_SETTING_IMPL_H_
diff --git a/chrome/browser/apps/app_service/app_service_metrics.cc b/chrome/browser/apps/app_service/app_service_metrics.cc
index d02a47c..68d7382 100644
--- a/chrome/browser/apps/app_service/app_service_metrics.cc
+++ b/chrome/browser/apps/app_service/app_service_metrics.cc
@@ -132,8 +132,6 @@
                            launch_source);
   else if (app_id == ash::kReleaseNotesAppId)
     RecordBuiltInAppLaunch(BuiltInAppName::kReleaseNotes, launch_source);
-  else if (app_id == ash::kInternalAppIdCamera)
-    RecordBuiltInAppLaunch(BuiltInAppName::kCamera, launch_source);
   else if (app_id == ash::kInternalAppIdDiscover)
     RecordBuiltInAppLaunch(BuiltInAppName::kDiscover, launch_source);
   else if (app_id == ash::kInternalAppIdSettings)
@@ -151,9 +149,6 @@
   } else if (app_id == ash::kReleaseNotesAppId) {
     UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchResultInternalApp.Show",
                               BuiltInAppName::kReleaseNotes);
-  } else if (app_id == ash::kInternalAppIdCamera) {
-    UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchResultInternalApp.Show",
-                              BuiltInAppName::kCamera);
   } else if (app_id == ash::kInternalAppIdDiscover) {
     UMA_HISTOGRAM_ENUMERATION("Apps.AppListSearchResultInternalApp.Show",
                               BuiltInAppName::kDiscover);
diff --git a/chrome/browser/apps/app_service/app_service_metrics.h b/chrome/browser/apps/app_service/app_service_metrics.h
index dc488dbd..3ccdaaf 100644
--- a/chrome/browser/apps/app_service/app_service_metrics.h
+++ b/chrome/browser/apps/app_service/app_service_metrics.h
@@ -18,7 +18,7 @@
   kKeyboardShortcutViewer = 0,
   kSettings = 1,
   kContinueReading = 2,
-  kCamera = 3,
+  kCameraDeprecated = 3,
   kDiscover = 4,
   kPluginVm = 5,
   kReleaseNotes = 6,
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc
index b7809e7..78cc3426 100644
--- a/chrome/browser/apps/app_service/extension_apps.cc
+++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -48,6 +48,7 @@
 #include "chrome/common/extensions/extension_metrics.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/services/app_service/public/cpp/instance.h"
 #include "chrome/services/app_service/public/cpp/intent_filter_util.h"
 #include "chrome/services/app_service/public/mojom/types.mojom.h"
 #include "components/arc/arc_service_manager.h"
@@ -142,9 +143,6 @@
 // is empty, the session_id is used.
 std::string GetLaunchId(extensions::AppWindow* app_window) {
   std::string launch_id;
-  if (app_window->extension_id() == extension_misc::kChromeCameraAppId)
-    return launch_id;
-
   if (app_window->show_in_shelf()) {
     if (!app_window->window_key().empty()) {
       launch_id = app_window->window_key();
@@ -719,7 +717,7 @@
   DCHECK(!instance_registry_->ForOneInstance(
       app_window->GetNativeWindow(),
       [](const apps::InstanceUpdate& update) {}));
-
+  app_window_to_aura_window_[app_window] = app_window->GetNativeWindow();
   RegisterInstance(app_window, InstanceState::kStarted);
 }
 
@@ -748,6 +746,15 @@
   RegisterInstance(app_window, InstanceState::kStarted);
 }
 
+void ExtensionApps::OnAppWindowRemoved(extensions::AppWindow* app_window) {
+  if (!ShouldRecordAppWindowActivity(app_window)) {
+    return;
+  }
+
+  RegisterInstance(app_window, InstanceState::kDestroyed);
+  app_window_to_aura_window_.erase(app_window);
+}
+
 void ExtensionApps::OnExtensionLastLaunchTimeChanged(
     const std::string& app_id,
     const base::Time& last_launch_time) {
@@ -1217,7 +1224,18 @@
   DCHECK(app_window);
 
   const extensions::Extension* extension = app_window->GetExtension();
-  if (!extension || !Accepts(extension)) {
+  if (!extension) {
+    return false;
+  }
+
+  // ARC Play Store is not published by this publisher, but the window for Play
+  // Store should be able to be added to InstanceRegistry.
+  if (extension->id() == arc::kPlayStoreAppId &&
+      app_type_ == apps::mojom::AppType::kExtension) {
+    return true;
+  }
+
+  if (!Accepts(extension)) {
     return false;
   }
 
@@ -1236,11 +1254,17 @@
     return;
   }
 
+  aura::Window* window = app_window->GetNativeWindow();
+  if (new_state == InstanceState::kDestroyed) {
+    DCHECK(base::Contains(app_window_to_aura_window_, app_window));
+    window = app_window_to_aura_window_[app_window];
+  }
   std::vector<std::unique_ptr<apps::Instance>> deltas;
-  auto instance = std::make_unique<apps::Instance>(
-      app_window->extension_id(), app_window->GetNativeWindow());
+  auto instance =
+      std::make_unique<apps::Instance>(app_window->extension_id(), window);
   instance->SetLaunchId(GetLaunchId(app_window));
   instance->UpdateState(new_state, base::Time::Now());
+  instance->SetBrowserContext(app_window->browser_context());
   deltas.push_back(std::move(instance));
   instance_registry_->OnInstances(deltas);
 }
diff --git a/chrome/browser/apps/app_service/extension_apps.h b/chrome/browser/apps/app_service/extension_apps.h
index ade888e45a..4a009f8 100644
--- a/chrome/browser/apps/app_service/extension_apps.h
+++ b/chrome/browser/apps/app_service/extension_apps.h
@@ -119,6 +119,7 @@
   void OnAppWindowShown(extensions::AppWindow* app_window,
                         bool was_hidden) override;
   void OnAppWindowHidden(extensions::AppWindow* app_window) override;
+  void OnAppWindowRemoved(extensions::AppWindow* app_window) override;
 
   // extensions::ExtensionPrefsObserver overrides.
   void OnExtensionLastLaunchTimeChanged(
@@ -223,6 +224,8 @@
 
   std::set<std::string> paused_apps_;
 
+  std::map<extensions::AppWindow*, aura::Window*> app_window_to_aura_window_;
+
   ArcAppListPrefs* arc_prefs_ = nullptr;
 
   // app_service_ is owned by the object that owns this object.
diff --git a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector_browsertest.cc b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector_browsertest.cc
index 0677d4c..be4d5b6 100644
--- a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector_browsertest.cc
+++ b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector_browsertest.cc
@@ -8,8 +8,8 @@
 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/test/browser_test_base.h"
 #include "content/public/test/browser_test_utils.h"
 #include "extensions/test/extension_test_message_listener.h"
@@ -116,7 +116,7 @@
 void PlatformAppNavigationRedirectorBrowserTest::SetUpCommandLine(
     base::CommandLine* command_line) {
   PlatformAppBrowserTest::SetUpCommandLine(command_line);
-  command_line->AppendSwitch(::switches::kDisablePopupBlocking);
+  command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
 }
 
 // TODO(sergeygs): Factor out common functionality from TestXyz,
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 695475e..5ddf93ee 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -261,9 +261,10 @@
 
         <include name="IDR_GUEST_SESSION_TAB_HTML" file="resources\chromeos\guest_session_tab.html" flattenhtml="true" type="BINDATA" compress="gzip" />
 
+        <!-- Note: mobile_setup_ui.cc does not support compressed resources. -->
         <include name="IDR_MOBILE_MANIFEST" file="resources\chromeos\mobile_app\manifest.json" type="BINDATA" />
-        <include name="IDR_MOBILE_SETUP_PAGE_HTML" file="resources\chromeos\mobile_setup.html" flattenhtml="true" type="BINDATA" compress="gzip" />
-        <include name="IDR_MOBILE_SETUP_PORTAL_PAGE_HTML" file="resources\chromeos\mobile_setup_portal.html" flattenhtml="true" type="BINDATA" compress="gzip" />
+        <include name="IDR_MOBILE_SETUP_PAGE_HTML" file="resources\chromeos\mobile_setup.html" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_MOBILE_SETUP_PORTAL_PAGE_HTML" file="resources\chromeos\mobile_setup_portal.html" flattenhtml="true" type="BINDATA" />
 
         <include name="IDR_ECHO_MANIFEST" file="resources\chromeos\echo\manifest.json" type="BINDATA" />
         <include name="IDR_OS_CREDITS_HTML" file="resources\chromeos\about_os_credits.html" flattenhtml="true" type="BINDATA" compress="gzip" />
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 76ba14f..c266ca3 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -26,14 +26,20 @@
 #include "chrome/browser/ui/webui/interventions_internals/interventions_internals.mojom.h"
 #include "chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.h"
 #include "chrome/browser/ui/webui/media/media_engagement_ui.h"
+#include "chrome/browser/ui/webui/omnibox/omnibox.mojom.h"
+#include "chrome/browser/ui/webui/omnibox/omnibox_ui.h"
+#include "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.h"
+#include "chrome/browser/ui/webui/usb_internals/usb_internals_ui.h"
 #include "chrome/common/prerender.mojom.h"
 #include "components/dom_distiller/content/browser/distillability_driver.h"
 #include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h"
 #include "components/dom_distiller/content/common/mojom/distillability_service.mojom.h"
 #include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h"
 #include "components/dom_distiller/core/dom_distiller_service.h"
+#include "components/feed/buildflags.h"
 #include "components/performance_manager/performance_manager_tab_helper.h"
 #include "components/performance_manager/public/mojom/coordination_unit.mojom.h"
+#include "components/safe_browsing/buildflags.h"
 #include "components/translate/content/common/translate.mojom.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_frame_host.h"
@@ -49,18 +55,30 @@
 #include "third_party/blink/public/mojom/payments/payment_request.mojom.h"
 #include "third_party/blink/public/public_buildflags.h"
 
+#if BUILDFLAG(ENABLE_FEED_IN_CHROME)
+#include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
+#include "chrome/browser/ui/webui/feed_internals/feed_internals_ui.h"
+#endif  // BUILDFLAG(ENABLE_FEED_IN_CHROME)
+
 #if BUILDFLAG(ENABLE_UNHANDLED_TAP)
 #include "chrome/browser/android/contextualsearch/unhandled_tap_notifier_impl.h"
 #include "chrome/browser/android/contextualsearch/unhandled_tap_web_contents_observer.h"
 #include "third_party/blink/public/mojom/unhandled_tap_notifier/unhandled_tap_notifier.mojom.h"
 #endif  // BUILDFLAG(ENABLE_UNHANDLED_TAP)
 
+#if BUILDFLAG(FULL_SAFE_BROWSING)
+#include "chrome/browser/ui/webui/reset_password/reset_password.mojom.h"
+#include "chrome/browser/ui/webui/reset_password/reset_password_ui.h"
+#endif  // BUILDFLAG(FULL_SAFE_BROWSING)
+
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/contextualsearch/contextual_search_observer.h"
 #include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h"
 #include "chrome/browser/offline_pages/android/offline_page_auto_fetcher.h"
 #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom.h"
 #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals_ui.h"
+#include "chrome/browser/ui/webui/snippets_internals/snippets_internals.mojom.h"
+#include "chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h"
 #include "chrome/common/offline_page_auto_fetcher.mojom.h"
 #include "components/contextual_search/content/browser/contextual_search_js_api_service_impl.h"
 #include "components/contextual_search/content/common/mojom/contextual_search_js_api_service.mojom.h"
@@ -76,6 +94,8 @@
 #include "chrome/browser/payments/payment_request_factory.h"
 #include "chrome/browser/ui/webui/downloads/downloads.mojom.h"
 #include "chrome/browser/ui/webui/downloads/downloads_ui.h"
+#include "chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom.h"
+#include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h"
 #endif
 
 #if defined(OS_CHROMEOS)
@@ -94,6 +114,11 @@
 #include "chrome/browser/ui/webui/chromeos/machine_learning/machine_learning_internals_ui.h"
 #endif
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.h"
+#include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.h"
+#endif
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
@@ -385,17 +410,29 @@
       MediaEngagementUI, media::mojom::MediaEngagementScoreDetailsProvider>(
       map);
 
+  RegisterWebUIControllerInterfaceBinder<OmniboxUI,
+                                         ::mojom::OmniboxPageHandler>(map);
+
   RegisterWebUIControllerInterfaceBinder<
       SiteEngagementUI, ::mojom::SiteEngagementDetailsProvider>(map);
 
+  RegisterWebUIControllerInterfaceBinder<UsbInternalsUI,
+                                         ::mojom::UsbInternalsPageHandler>(map);
+
 #if defined(OS_ANDROID)
   RegisterWebUIControllerInterfaceBinder<
       explore_sites::ExploreSitesInternalsUI,
       explore_sites_internals::mojom::PageHandler>(map);
+
+  RegisterWebUIControllerInterfaceBinder<
+      SnippetsInternalsUI, snippets_internals::mojom::PageHandlerFactory>(map);
 #else
   RegisterWebUIControllerInterfaceBinder<DownloadsUI,
                                          downloads::mojom::PageHandlerFactory>(
       map);
+
+  RegisterWebUIControllerInterfaceBinder<
+      NewTabPageUI, new_tab_page::mojom::PageHandlerFactory>(map);
 #endif
 
 #if defined(OS_CHROMEOS)
@@ -404,6 +441,10 @@
       add_supervision::mojom::AddSupervisionHandler>(map);
 
   RegisterWebUIControllerInterfaceBinder<
+      chromeos::cellular_setup::CellularSetupDialogUI,
+      chromeos::cellular_setup::mojom::CellularSetup>(map);
+
+  RegisterWebUIControllerInterfaceBinder<
       chromeos::machine_learning::MachineLearningInternalsUI,
       chromeos::machine_learning::mojom::PageHandler>(map);
 #endif  // defined(OS_CHROMEOS)
@@ -416,6 +457,17 @@
   RegisterWebUIControllerInterfaceBinder<DiscardsUI,
                                          discards::mojom::GraphDump>(map);
 #endif
+
+#if BUILDFLAG(ENABLE_FEED_IN_CHROME)
+  RegisterWebUIControllerInterfaceBinder<FeedInternalsUI,
+                                         feed_internals::mojom::PageHandler>(
+      map);
+#endif
+
+#if BUILDFLAG(FULL_SAFE_BROWSING)
+  RegisterWebUIControllerInterfaceBinder<ResetPasswordUI,
+                                         ::mojom::ResetPasswordHandler>(map);
+#endif
 }
 
 }  // namespace internal
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 9926639..2b274a18 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -2713,6 +2713,7 @@
     "extensions/signin_screen_policy_provider_unittest.cc",
     "extensions/wallpaper_private_api_unittest.cc",
     "external_metrics_unittest.cc",
+    "file_manager/crostini_file_tasks_unittest.cc",
     "file_manager/documents_provider_root_manager_unittest.cc",
     "file_manager/file_tasks_notifier_unittest.cc",
     "file_manager/file_tasks_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
index 47d7c50..89da988 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -149,17 +149,6 @@
   }
 }
 
-void KioskExternalUpdater::OnFormatEvent(
-    disks::DiskMountManager::FormatEvent event,
-    FormatError error_code,
-    const std::string& device_path) {
-}
-
-void KioskExternalUpdater::OnRenameEvent(
-    disks::DiskMountManager::RenameEvent event,
-    RenameError error_code,
-    const std::string& device_path) {}
-
 void KioskExternalUpdater::OnExternalUpdateUnpackSuccess(
     const std::string& app_id,
     const std::string& version,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
index 1dd661c0..b2074f8 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
@@ -61,12 +61,6 @@
       disks::DiskMountManager::MountEvent event,
       MountError error_code,
       const disks::DiskMountManager::MountPointInfo& mount_info) override;
-  void OnFormatEvent(disks::DiskMountManager::FormatEvent event,
-                     FormatError error_code,
-                     const std::string& device_path) override;
-  void OnRenameEvent(disks::DiskMountManager::RenameEvent event,
-                     RenameError error_code,
-                     const std::string& device_path) override;
 
   // KioskExternalUpdateValidatorDelegate overrides:
   void OnExternalUpdateUnpackSuccess(const std::string& app_id,
diff --git a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc
index 5b9663f..2c06b4c6 100644
--- a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc
+++ b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc
@@ -62,12 +62,14 @@
 
 void WebKioskAppLauncher::OnAppDataObtained(
     std::unique_ptr<WebApplicationInfo> app_info) {
-  if (app_info) {
-    WebKioskAppManager::Get()->UpdateAppByAccountId(account_id_,
-                                                    std::move(app_info));
+  if (!app_info) {
+    // Notify about failed installation, let the controller decide what to do.
+    delegate_->OnAppInstallFailed();
+    return;
   }
-  // If we could not update the app data, we should still launch the app(we may
-  // be under captive portal, there can be redirect, etc).
+
+  WebKioskAppManager::Get()->UpdateAppByAccountId(account_id_,
+                                                  std::move(app_info));
   delegate_->OnAppPrepared();
 }
 
diff --git a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.h b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.h
index 77106a91..ba0b8e7 100644
--- a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.h
+++ b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.h
@@ -36,6 +36,7 @@
     virtual void InitializeNetwork() = 0;
     virtual void OnAppStartedInstalling() = 0;
     virtual void OnAppPrepared() = 0;
+    virtual void OnAppInstallFailed() = 0;
     virtual void OnAppLaunched() = 0;
     virtual void OnAppLaunchFailed() = 0;
 
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc
index d04615bf..69d7e843 100644
--- a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc
+++ b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc
@@ -35,6 +35,8 @@
       node_ptr_(node),
       is_clickable_leaf_(is_clickable_leaf) {}
 
+AccessibilityNodeInfoDataWrapper::~AccessibilityNodeInfoDataWrapper() = default;
+
 bool AccessibilityNodeInfoDataWrapper::IsNode() const {
   return true;
 }
@@ -91,6 +93,11 @@
                                  class_name);
   }
 
+  if (role_) {
+    out_data->role = *role_;
+    return;
+  }
+
   if (GetProperty(AXBooleanProperty::EDITABLE)) {
     out_data->role = ax::mojom::Role::kTextField;
     return;
@@ -282,7 +289,8 @@
   int labelled_by = -1;
 
   // Accessible name computation is a concatenated string comprising of:
-  // content description, text, labelled by text, and pane title.
+  // content description, text, labelled by text, pane title, and cached name
+  // from previous events.
   std::string text;
   std::string content_description;
   std::string label;
@@ -309,7 +317,7 @@
   GetProperty(AXStringProperty::HINT_TEXT, &hint_text);
 
   if (!text.empty() || !content_description.empty() || !label.empty() ||
-      !pane_title.empty() || !hint_text.empty()) {
+      !pane_title.empty() || !hint_text.empty() || cached_name_) {
     // Append non empty properties to name attribute.
     std::vector<std::string> names;
     if (!content_description.empty())
@@ -333,6 +341,9 @@
     if (!hint_text.empty())
       names.push_back(hint_text);
 
+    if (cached_name_ && !(*cached_name_).empty())
+      names.push_back(*cached_name_);
+
     // TODO (sarakato): Exposing all possible labels for a node, may result in
     // too much being spoken. For ARC ++, this may result in divergent behaviour
     // from Talkback.
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h
index cab422a..9a8343a9 100644
--- a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h
+++ b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h
@@ -20,6 +20,8 @@
                                    mojom::AccessibilityNodeInfoData* node,
                                    bool is_clickable_leaf);
 
+  ~AccessibilityNodeInfoDataWrapper() override;
+
   // AccessibilityInfoDataWrapper overrides.
   bool IsNode() const override;
   mojom::AccessibilityNodeInfoData* GetNode() const override;
@@ -36,6 +38,9 @@
 
   mojom::AccessibilityNodeInfoData* node() { return node_ptr_; }
 
+  void set_role(ax::mojom::Role role) { role_ = role; }
+  void set_cached_name(const std::string& name) { cached_name_ = name; }
+
  private:
   bool GetProperty(mojom::AccessibilityBooleanProperty prop) const;
   bool GetProperty(mojom::AccessibilityIntProperty prop,
@@ -62,6 +67,9 @@
 
   bool is_clickable_leaf_;
 
+  base::Optional<ax::mojom::Role> role_;
+  base::Optional<std::string> cached_name_;
+
   DISALLOW_COPY_AND_ASSIGN(AccessibilityNodeInfoDataWrapper);
 };
 
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
index f3a71b3..0a38b591 100644
--- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
+++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
@@ -7,6 +7,7 @@
 #include <stack>
 #include <string>
 
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h"
 #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h"
@@ -29,9 +30,24 @@
 using AXIntListProperty = mojom::AccessibilityIntListProperty;
 using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
 using AXNodeInfoDataPtr = mojom::AccessibilityNodeInfoDataPtr;
+using AXStringProperty = mojom::AccessibilityStringProperty;
 using AXWindowInfoData = mojom::AccessibilityWindowInfoData;
 using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty;
 
+namespace {
+bool IsDrawerLayout(AXNodeInfoData* node) {
+  if (!node || !node->string_properties)
+    return false;
+
+  auto it = node->string_properties->find(AXStringProperty::CLASS_NAME);
+  if (it == node->string_properties->end())
+    return false;
+
+  return it->second == "androidx.drawerlayout.widget.DrawerLayout" ||
+         it->second == "android.support.v4.widget.DrawerLayout";
+}
+}  // namespace
+
 AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate)
     : current_tree_serializer_(new AXTreeArcSerializer(this)),
       is_notification_(false),
@@ -129,10 +145,15 @@
     // is fired from Android multiple times.
     // The event of WINDOW_STATE_CHANGED is fired only once for each window
     // change and use it as a trigger to move the a11y focus to the first node.
+    AccessibilityInfoDataWrapper* focused_node =
+        GetFromId(event_data->source_id);
     AccessibilityInfoDataWrapper* new_focus =
-        FindFirstFocusableNode(GetFromId(event_data->source_id));
+        FindFirstFocusableNode(focused_node);
     if (IsValid(new_focus))
       focused_id_ = new_focus->GetId();
+
+    if (event_data->eventText)
+      UpdateAXNameCache(focused_node, *event_data->eventText);
   }
   if (!focused_id_.has_value()) {
     AccessibilityInfoDataWrapper* root = GetRoot();
@@ -155,6 +176,8 @@
     }
   }
 
+  ApplyCachedProperties();
+
   ExtensionMsg_AccessibilityEventBundleParams event_bundle;
   event_bundle.tree_id = ax_tree_id();
 
@@ -386,6 +409,53 @@
   return nullptr;
 }
 
+void AXTreeSourceArc::UpdateAXNameCache(
+    AccessibilityInfoDataWrapper* focused_node,
+    const std::vector<std::string>& event_text) {
+  if (IsDrawerLayout(focused_node->GetNode())) {
+    // When drawer menu opened, make the menu title announced.
+    // When focus is changed, ChromeVox computes the diff in ancestry between
+    // the previously focused and new focused node.
+    // As the DrawerLayout is LCA of them, set the new title to be the first
+    // visible child node (which is usually drawer menu).
+    std::vector<AccessibilityInfoDataWrapper*> children;
+    focused_node->GetChildren(&children);
+    for (auto* child : children) {
+      if (child->IsNode() && child->IsVisibleToUser() &&
+          GetBooleanProperty(child->GetNode(), AXBooleanProperty::IMPORTANCE)) {
+        cached_roles_[child->GetId()] = ax::mojom::Role::kMenu;
+        if (!event_text.empty())
+          cached_names_[child->GetId()] = base::JoinString(event_text, " ");
+        return;
+      }
+    }
+  }
+}
+
+void AXTreeSourceArc::ApplyCachedProperties() {
+  for (auto it = cached_names_.begin(); it != cached_names_.end();) {
+    AccessibilityInfoDataWrapper* node = GetFromId(it->first);
+    if (node) {
+      static_cast<AccessibilityNodeInfoDataWrapper*>(node)->set_cached_name(
+          it->second);
+      it++;
+    } else {
+      it = cached_names_.erase(it);
+    }
+  }
+
+  for (auto it = cached_roles_.begin(); it != cached_roles_.end();) {
+    AccessibilityInfoDataWrapper* node = GetFromId(it->first);
+    if (node) {
+      static_cast<AccessibilityNodeInfoDataWrapper*>(node)->set_role(
+          it->second);
+      it++;
+    } else {
+      it = cached_roles_.erase(it);
+    }
+  }
+}
+
 void AXTreeSourceArc::Reset() {
   tree_map_.clear();
   parent_map_.clear();
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
index fb52ce7..8e91307 100644
--- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
+++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
@@ -116,6 +116,11 @@
   AccessibilityInfoDataWrapper* FindFirstFocusableNode(
       AccessibilityInfoDataWrapper* info_data) const;
 
+  void UpdateAXNameCache(AccessibilityInfoDataWrapper* focused_node,
+                         const std::vector<std::string>& event_text);
+
+  void ApplyCachedProperties();
+
   // Resets tree state.
   void Reset();
 
@@ -145,6 +150,9 @@
   bool is_notification_;
   bool is_input_method_window_;
 
+  std::map<int32_t, std::string> cached_names_;
+  std::map<int32_t, ax::mojom::Role> cached_roles_;
+
   // A delegate that handles accessibility actions on behalf of this tree. The
   // delegate is valid during the lifetime of this tree.
   const Delegate* const delegate_;
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
index 3f0092b8..eb18084 100644
--- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
+++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
@@ -931,7 +931,6 @@
   event->node_data.emplace_back(AXNodeInfoData::New());
   AXNodeInfoData* root = event->node_data.back().get();
   root->id = 10;
-
   SetProperty(root, AXIntListProperty::CHILD_NODE_IDS,
               std::vector<int>({1, 2}));
   SetProperty(root, AXBooleanProperty::IMPORTANCE, true);
@@ -972,6 +971,76 @@
   EXPECT_EQ(2, GetDispatchedEventCount(ax::mojom::Event::kFocus));
 }
 
+TEST_F(AXTreeSourceArcTest, OnDrawerOpened) {
+  auto event = AXEventData::New();
+  event->source_id = 10;  // root
+  event->task_id = 1;
+  event->event_type = AXEventType::WINDOW_STATE_CHANGED;
+  event->eventText = std::vector<std::string>({"Navigation"});
+
+  event->window_data = std::vector<mojom::AccessibilityWindowInfoDataPtr>();
+  event->window_data->emplace_back(AXWindowInfoData::New());
+  AXWindowInfoData* root_window = event->window_data->back().get();
+  root_window->window_id = 100;
+  root_window->root_node_id = 10;
+
+  /* AXTree of this test:
+    [10] root (DrawerLayout)
+    --[1] node1 (not-importantForAccessibility) hidden node
+    --[2] node2 visible node
+    ----[3] node3 node with text
+  */
+  event->node_data.emplace_back(AXNodeInfoData::New());
+  AXNodeInfoData* root = event->node_data.back().get();
+  root->id = 10;
+  SetProperty(root, AXIntListProperty::CHILD_NODE_IDS,
+              std::vector<int>({1, 2}));
+  SetProperty(root, AXBooleanProperty::IMPORTANCE, true);
+  SetProperty(root, AXStringProperty::CLASS_NAME,
+              "androidx.drawerlayout.widget.DrawerLayout");
+
+  event->node_data.emplace_back(AXNodeInfoData::New());
+  AXNodeInfoData* node1 = event->node_data.back().get();
+  node1->id = 1;
+  SetProperty(node1, AXBooleanProperty::VISIBLE_TO_USER, true);
+
+  event->node_data.emplace_back(AXNodeInfoData::New());
+  AXNodeInfoData* node2 = event->node_data.back().get();
+  node2->id = 2;
+  SetProperty(node2, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({3}));
+  SetProperty(node2, AXBooleanProperty::IMPORTANCE, true);
+  SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true);
+
+  event->node_data.emplace_back(AXNodeInfoData::New());
+  AXNodeInfoData* node3 = event->node_data.back().get();
+  node3->id = 3;
+  SetProperty(node3, AXBooleanProperty::IMPORTANCE, true);
+  SetProperty(node3, AXBooleanProperty::VISIBLE_TO_USER, true);
+  SetProperty(node3, AXStringProperty::TEXT, "sample string.");
+
+  CallNotifyAccessibilityEvent(event.get());
+
+  std::unique_ptr<ui::AXNodeData> data;
+  std::string name;
+  CallSerializeNode(node2, &data);
+  ASSERT_EQ(ax::mojom::Role::kMenu, data->role);
+  ASSERT_TRUE(
+      data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
+  EXPECT_EQ("Navigation", name);
+
+  // Validate that the drawer title is cached.
+  event->eventText.reset();
+  event->event_type = AXEventType::WINDOW_CONTENT_CHANGED;
+  CallNotifyAccessibilityEvent(event.get());
+
+  data->RemoveStringAttribute(ax::mojom::StringAttribute::kName);
+  CallSerializeNode(node2, &data);
+  ASSERT_EQ(ax::mojom::Role::kMenu, data->role);
+  ASSERT_TRUE(
+      data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
+  EXPECT_EQ("Navigation", name);
+}
+
 TEST_F(AXTreeSourceArcTest, SerializeAndUnserialize) {
   auto event = AXEventData::New();
   event->source_id = 10;
diff --git a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.cc b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.cc
index 7ffaf235..8c57b66 100644
--- a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.cc
+++ b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.cc
@@ -271,7 +271,10 @@
   event.shift_key = data_ptr->is_shift_down;
   event.caps_lock = data_ptr->is_capslock_on;
 
-  ime_engine_->SendKeyEvents(input_context_id_, {event});
+  std::string error;
+  if (!ime_engine_->SendKeyEvents(input_context_id_, {event}, &error)) {
+    LOG(ERROR) << error;
+  }
 }
 
 void InputConnectionImpl::SetCompositionRange(
@@ -330,7 +333,11 @@
       press.key = press.code = std::get<2>(t);
       chromeos::InputMethodEngine::KeyboardEvent release(press);
       release.type = "keyup";
-      ime_engine_->SendKeyEvents(input_context_id_, {press, release});
+      std::string error;
+      if (!ime_engine_->SendKeyEvents(input_context_id_, {press, release},
+                                      &error)) {
+        LOG(ERROR) << error;
+      }
       break;
     }
   }
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
index 82e97f48..4e7faa5 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -221,7 +221,9 @@
   std::unique_ptr<base::ListValue> cert_names(
       std::make_unique<base::ListValue>());
   for (const auto& name : smart_card_manager->get_required_cert_names()) {
-    cert_names->Append(name);
+    base::DictionaryValue value;
+    value.SetString("alias", name);
+    cert_names->Append(value.CreateDeepCopy());
   }
   filtered_policies->Set(kArcRequiredKeyPairs, std::move(cert_names));
 }
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
index 72bdbf7..9ba9926 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -632,10 +632,11 @@
   // One certificate is required to be installed.
   smart_card_manager()->set_required_cert_names_for_testing(
       std::vector<std::string>({kFakeCertName}));
-  GetPoliciesAndVerifyResult(
-      "{\"guid\":\"" + instance_guid() + "\"," +
-      base::StringPrintf(kRequiredKeyPairFormat, "\"", kFakeCertName, "\"") +
-      "}");
+  GetPoliciesAndVerifyResult("{\"guid\":\"" + instance_guid() + "\"," +
+                             base::StringPrintf(kRequiredKeyPairFormat,
+                                                "{\"alias\":\"", kFakeCertName,
+                                                "\"}") +
+                             "}");
 
   // An empty list is required to be installed.
   smart_card_manager()->set_required_cert_names_for_testing(
diff --git a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.cc b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.cc
new file mode 100644
index 0000000..3b671366
--- /dev/null
+++ b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.cc
@@ -0,0 +1,80 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h"
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h"
+#include "chrome/browser/chromeos/login/test/device_state_mixin.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/extensions/policy_test_utils.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_paths.h"
+#include "components/policy/proto/chrome_device_policy.pb.h"
+#include "extensions/test/test_background_page_first_load_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+// Extension ID of the test certificate provider extension.
+constexpr char kTestCertProviderExtensionId[] =
+    "ecmhnokcdiianioonpgakiooenfnonid";
+// Path to the update manifest XML file of the test certificate provider
+// extension.
+constexpr char kTestCertProviderExtensionUpdateManifestPath[] =
+    "/extensions/test_certificate_provider/update_manifest.xml";
+
+}  // namespace
+
+TestCertificateProviderExtensionLoginScreenMixin::
+    TestCertificateProviderExtensionLoginScreenMixin(
+        InProcessBrowserTestMixinHost* host,
+        chromeos::DeviceStateMixin* device_state_mixin)
+    : InProcessBrowserTestMixin(host), device_state_mixin_(device_state_mixin) {
+  base::FilePath test_data_dir;
+  base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
+  embedded_test_server_.ServeFilesFromDirectory(test_data_dir);
+  // Rewrite the "mock.http" domain with the test server's address in the
+  // served "update_manifest.xml" files, to let the extensions subsystem fetch
+  // the .crx file referred from the update manifest.
+  extensions::policy_test_utils::SetUpEmbeddedTestServer(
+      &embedded_test_server_);
+}
+
+TestCertificateProviderExtensionLoginScreenMixin::
+    ~TestCertificateProviderExtensionLoginScreenMixin() = default;
+
+void TestCertificateProviderExtensionLoginScreenMixin::SetUpOnMainThread() {
+  ASSERT_TRUE(embedded_test_server_.Start());
+
+  Profile* const profile =
+      chromeos::ProfileHelper::GetSigninProfile()->GetOriginalProfile();
+  test_certificate_provider_extension_ =
+      std::make_unique<TestCertificateProviderExtension>(
+          profile, kTestCertProviderExtensionId);
+
+  extensions::TestBackgroundPageFirstLoadObserver bg_page_first_load_observer(
+      profile, kTestCertProviderExtensionId);
+
+  const GURL update_manifest_url = embedded_test_server_.GetURL(
+      kTestCertProviderExtensionUpdateManifestPath);
+  const std::string policy_item_value = base::ReplaceStringPlaceholders(
+      "$1;$2", {kTestCertProviderExtensionId, update_manifest_url.spec()},
+      nullptr);
+  device_state_mixin_->RequestDevicePolicyUpdate()
+      ->policy_payload()
+      ->mutable_device_login_screen_extensions()
+      ->add_device_login_screen_extensions(policy_item_value);
+
+  bg_page_first_load_observer.Wait();
+}
+
+void TestCertificateProviderExtensionLoginScreenMixin::TearDownOnMainThread() {
+  test_certificate_provider_extension_.reset();
+}
diff --git a/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h
new file mode 100644
index 0000000..21595f36
--- /dev/null
+++ b/chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h
@@ -0,0 +1,55 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_LOGIN_SCREEN_MIXIN_H_
+#define CHROME_BROWSER_CHROMEOS_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_LOGIN_SCREEN_MIXIN_H_
+
+#include <memory>
+
+#include "chrome/test/base/mixin_based_in_process_browser_test.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace chromeos {
+class DeviceStateMixin;
+}
+
+class TestCertificateProviderExtension;
+
+// Mixin for installing and running TestCertificateProviderExtension on the
+// Login Screen via the device policy.
+//
+// Note: Please make sure that the |kDisableBackgroundNetworking| switch is NOT
+// set when using this mixin.
+class TestCertificateProviderExtensionLoginScreenMixin final
+    : public InProcessBrowserTestMixin {
+ public:
+  TestCertificateProviderExtensionLoginScreenMixin(
+      InProcessBrowserTestMixinHost* host,
+      chromeos::DeviceStateMixin* device_state_mixin);
+  TestCertificateProviderExtensionLoginScreenMixin(
+      const TestCertificateProviderExtensionLoginScreenMixin&) = delete;
+  TestCertificateProviderExtensionLoginScreenMixin& operator=(
+      const TestCertificateProviderExtensionLoginScreenMixin&) = delete;
+  ~TestCertificateProviderExtensionLoginScreenMixin() override;
+
+  TestCertificateProviderExtension* test_certificate_provider_extension() {
+    return test_certificate_provider_extension_.get();
+  }
+  const TestCertificateProviderExtension* test_certificate_provider_extension()
+      const {
+    return test_certificate_provider_extension_.get();
+  }
+
+  // InProcessBrowserTestMixin:
+  void SetUpOnMainThread() override;
+  void TearDownOnMainThread() override;
+
+ private:
+  chromeos::DeviceStateMixin* const device_state_mixin_;
+  net::EmbeddedTestServer embedded_test_server_;
+  std::unique_ptr<TestCertificateProviderExtension>
+      test_certificate_provider_extension_;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_LOGIN_SCREEN_MIXIN_H_
diff --git a/chrome/browser/chromeos/crostini/crostini_installer.cc b/chrome/browser/chromeos/crostini/crostini_installer.cc
index 9cbe866..60bbffde 100644
--- a/chrome/browser/chromeos/crostini/crostini_installer.cc
+++ b/chrome/browser/chromeos/crostini/crostini_installer.cc
@@ -15,12 +15,14 @@
 #include "base/task/post_task.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/crostini/ansible/ansible_management_service_factory.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager_factory.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/crostini/crostini_terminal.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -37,6 +39,7 @@
 
 namespace {
 using SetupResult = CrostiniInstaller::SetupResult;
+constexpr char kCrostiniSetupSourceHistogram[] = "Crostini.SetupSource";
 
 class CrostiniInstallerFactory : public BrowserContextKeyedServiceFactory {
  public:
@@ -182,6 +185,20 @@
   }
 }
 
+void CrostiniInstaller::ShowDialog(CrostiniUISurface ui_surface) {
+  // Defensive check to prevent showing the installer when crostini is not
+  // allowed.
+  if (!CrostiniFeatures::Get()->IsUIAllowed(profile_)) {
+    return;
+  }
+  base::UmaHistogramEnumeration(kCrostiniSetupSourceHistogram, ui_surface,
+                                crostini::CrostiniUISurface::kCount);
+
+  // TODO(lxj): We should pass the dialog |this| here instead of letting the
+  // webui to call |GetForProfile()| later.
+  chromeos::CrostiniInstallerDialog::Show(profile_);
+}
+
 void CrostiniInstaller::Install(CrostiniManager::RestartOptions options,
                                 ProgressCallback progress_callback,
                                 ResultCallback result_callback) {
diff --git a/chrome/browser/chromeos/crostini/crostini_installer.h b/chrome/browser/chromeos/crostini/crostini_installer.h
index f3da069..7aa6a5c 100644
--- a/chrome/browser/chromeos/crostini/crostini_installer.h
+++ b/chrome/browser/chromeos/crostini/crostini_installer.h
@@ -68,6 +68,8 @@
   ~CrostiniInstaller() override;
   void Shutdown() override;
 
+  void ShowDialog(CrostiniUISurface ui_surface);
+
   // CrostiniInstallerUIDelegate:
   void Install(CrostiniManager::RestartOptions options,
                ProgressCallback progress_callback,
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index f6703b4..df2f701 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -66,15 +66,6 @@
 
 namespace {
 
-enum class ContainerOsVersion {
-  kUnkown = 0,
-  kDebianStretch = 1,
-  kDebianBuster = 2,
-  kDebianOther = 3,
-  kOtherOs = 4,
-  kMaxValue = kOtherOs,
-};
-
 chromeos::CiceroneClient* GetCiceroneClient() {
   return chromeos::DBusThreadManager::Get()->GetCiceroneClient();
 }
diff --git a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
index 702c2f1..482a978 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
@@ -1083,7 +1083,10 @@
 
 TEST_F(CrostiniManagerRestartTest, OsReleaseSetCorrectly) {
   vm_tools::cicerone::OsRelease os_release;
+  base::HistogramTester histogram_tester{};
   os_release.set_pretty_name("Debian GNU/Linux 10 (buster)");
+  os_release.set_version_id("10");
+  os_release.set_id("debian");
   fake_cicerone_client_->set_lxd_container_os_release(os_release);
 
   restart_id_ = crostini_manager()->RestartCrostini(
@@ -1101,6 +1104,8 @@
   // API in our protos.
   EXPECT_EQ(os_release.SerializeAsString(),
             stored_os_release->SerializeAsString());
+  histogram_tester.ExpectUniqueSample("Crostini.ContainerOsVersion",
+                                      ContainerOsVersion::kDebianBuster, 1);
 }
 
 TEST_F(CrostiniManagerRestartTest, RestartThenUninstall) {
diff --git a/chrome/browser/chromeos/crostini/crostini_simple_types.h b/chrome/browser/chromeos/crostini/crostini_simple_types.h
index 0218723..9b2e6cf 100644
--- a/chrome/browser/chromeos/crostini/crostini_simple_types.h
+++ b/chrome/browser/chromeos/crostini/crostini_simple_types.h
@@ -186,4 +186,13 @@
 
 }  // namespace crostini
 
+enum class ContainerOsVersion {
+  kUnkown = 0,
+  kDebianStretch = 1,
+  kDebianBuster = 2,
+  kDebianOther = 3,
+  kOtherOs = 4,
+  kMaxValue = kOtherOs,
+};
+
 #endif  // CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_SIMPLE_TYPES_H_
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index c94f554..cea2d25 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -16,6 +16,7 @@
 #include "base/task/post_task.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/crostini/crostini_installer.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_mime_types_service.h"
 #include "chrome/browser/chromeos/crostini/crostini_mime_types_service_factory.h"
@@ -401,7 +402,8 @@
     // At this point, we know that Crostini UI is allowed.
     if (!crostini_manager->IsCrosTerminaInstalled() ||
         !CrostiniFeatures::Get()->IsEnabled(profile)) {
-      ShowCrostiniInstallerView(profile, CrostiniUISurface::kAppList);
+      crostini::CrostiniInstaller::GetForProfile(profile)->ShowDialog(
+          CrostiniUISurface::kAppList);
       return std::move(callback).Run(false, "Crostini not installed");
     }
 
diff --git a/chrome/browser/chromeos/crostini/crostini_util.h b/chrome/browser/chromeos/crostini/crostini_util.h
index 5d670ffd..fe6045b 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.h
+++ b/chrome/browser/chromeos/crostini/crostini_util.h
@@ -122,8 +122,6 @@
 // See chrome/browser/ui/views/crostini for implementation of the ShowXXX
 // functions below.
 
-// Shows the Crostini Installer dialog.
-void ShowCrostiniInstallerView(Profile* profile, CrostiniUISurface ui_surface);
 // Shows the Crostini Uninstaller dialog.
 void ShowCrostiniUninstallerView(Profile* profile,
                                  CrostiniUISurface ui_surface);
diff --git a/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc b/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc
index 5f6725e..dabc1426 100644
--- a/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc
+++ b/chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider_browsertest.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/command_line.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
@@ -16,10 +17,12 @@
 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h"
 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h"
 #include "chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension.h"
+#include "chrome/browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h"
 #include "chrome/browser/chromeos/dbus/cryptohome_key_delegate_service_provider.h"
-#include "chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h"
-#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/chromeos/login/test/device_state_mixin.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/ui/browser.h"
+#include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
 #include "chromeos/dbus/constants/cryptohome_key_delegate_constants.h"
 #include "chromeos/dbus/cryptohome/key.pb.h"
@@ -27,11 +30,9 @@
 #include "chromeos/dbus/services/service_provider_test_helper.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/user_names.h"
-#include "components/version_info/channel.h"
 #include "content/public/browser/browser_context.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
-#include "extensions/test/test_background_page_first_load_observer.h"
 #include "net/cert/asn1_util.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util.h"
@@ -56,16 +57,25 @@
 
 // Tests for the CryptohomeKeyDelegateServiceProvider class.
 class CryptohomeKeyDelegateServiceProviderTest
-    : public policy::SigninProfileExtensionsPolicyTestBase {
+    : public MixinBasedInProcessBrowserTest {
  protected:
-  CryptohomeKeyDelegateServiceProviderTest()
-      : policy::SigninProfileExtensionsPolicyTestBase(
-            version_info::Channel::UNKNOWN) {}
+  CryptohomeKeyDelegateServiceProviderTest() = default;
 
-  ~CryptohomeKeyDelegateServiceProviderTest() override {}
+  CryptohomeKeyDelegateServiceProviderTest(
+      const CryptohomeKeyDelegateServiceProviderTest&) = delete;
+  CryptohomeKeyDelegateServiceProviderTest& operator=(
+      const CryptohomeKeyDelegateServiceProviderTest&) = delete;
+
+  ~CryptohomeKeyDelegateServiceProviderTest() override = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitch(chromeos::switches::kLoginManager);
+    command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
+  }
 
   void SetUpOnMainThread() override {
-    policy::SigninProfileExtensionsPolicyTestBase::SetUpOnMainThread();
+    MixinBasedInProcessBrowserTest::SetUpOnMainThread();
 
     dbus_service_test_helper_ =
         std::make_unique<chromeos::ServiceProviderTestHelper>();
@@ -77,8 +87,6 @@
             kCryptohomeKeyDelegateChallengeKey /* exported_method_name */,
         &service_provider_);
 
-    PrepareExtension();
-
     // Populate the browser's state with the mapping between the test
     // certificate provider extension and the certs that it provides, so that
     // the tested implementation knows where it should send challenges to. In
@@ -92,16 +100,14 @@
     dbus_service_test_helper_->TearDown();
     dbus_service_test_helper_.reset();
 
-    cert_provider_extension_.reset();
-
-    policy::SigninProfileExtensionsPolicyTestBase::TearDownOnMainThread();
+    MixinBasedInProcessBrowserTest::TearDownOnMainThread();
   }
 
   // Refreshes the browser's state from the current certificate providers.
   void RefreshCertsFromCertProviders() {
     chromeos::CertificateProviderService* cert_provider_service =
         chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
-            GetInitialProfile());
+            chromeos::ProfileHelper::GetSigninProfile());
     std::unique_ptr<chromeos::CertificateProvider> cert_provider =
         cert_provider_service->CreateCertificateProvider();
     base::RunLoop run_loop;
@@ -125,7 +131,7 @@
         cryptohome::KeyChallengeRequest::CHALLENGE_TYPE_SIGNATURE);
     request.mutable_signature_request_data()->set_data_to_sign(kDataToSign);
     request.mutable_signature_request_data()->set_public_key_spki_der(
-        GetCertSpki(*cert_provider_extension_->certificate()));
+        GetCertSpki(*cert_provider_extension()->certificate()));
     request.mutable_signature_request_data()->set_signature_algorithm(
         signature_algorithm);
 
@@ -156,7 +162,7 @@
   bool IsSignatureValid(crypto::SignatureVerifier::SignatureAlgorithm algorithm,
                         const std::vector<uint8_t>& signature) const {
     const std::string spki =
-        GetCertSpki(*cert_provider_extension_->certificate());
+        GetCertSpki(*cert_provider_extension()->certificate());
     crypto::SignatureVerifier verifier;
     if (!verifier.VerifyInit(algorithm, signature,
                              base::as_bytes(base::make_span(spki)))) {
@@ -167,35 +173,25 @@
   }
 
   TestCertificateProviderExtension* cert_provider_extension() {
-    return cert_provider_extension_.get();
+    return cert_provider_extension_mixin_.test_certificate_provider_extension();
+  }
+  const TestCertificateProviderExtension* cert_provider_extension() const {
+    return cert_provider_extension_mixin_.test_certificate_provider_extension();
   }
 
  private:
-  // Test certificate provider extension:
-  const std::string kExtensionId = "ecmhnokcdiianioonpgakiooenfnonid";
-  const std::string kExtensionUpdateManifestPath =
-      "/extensions/test_certificate_provider/update_manifest.xml";
-
   // Data that is passed as an input for the signature challenge request.
   const std::string kDataToSign = "some_data";
 
-  // Installs the certificate provider extension into the sign-in profile.
-  void PrepareExtension() {
-    Profile* const profile = GetInitialProfile();
-    cert_provider_extension_ =
-        std::make_unique<TestCertificateProviderExtension>(profile,
-                                                           kExtensionId);
-    extensions::TestBackgroundPageFirstLoadObserver bg_page_first_load_observer(
-        profile, kExtensionId);
-    AddExtensionForForceInstallation(kExtensionId,
-                                     kExtensionUpdateManifestPath);
-    bg_page_first_load_observer.Wait();
-  }
+  chromeos::DeviceStateMixin device_state_mixin_{
+      &mixin_host_,
+      chromeos::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
+  TestCertificateProviderExtensionLoginScreenMixin
+      cert_provider_extension_mixin_{&mixin_host_, &device_state_mixin_};
 
   chromeos::CryptohomeKeyDelegateServiceProvider service_provider_;
   std::unique_ptr<chromeos::ServiceProviderTestHelper>
       dbus_service_test_helper_;
-  std::unique_ptr<TestCertificateProviderExtension> cert_provider_extension_;
 };
 
 // Verifies that the ChallengeKey request with the PKCS #1 v1.5 SHA-256
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index 46ec552..acbcd5a 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -92,9 +92,10 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/toolbar/app_menu_model.h"
-#include "chrome/browser/ui/views/crostini/crostini_installer_view.h"
 #include "chrome/browser/ui/views/crostini/crostini_uninstaller_view.h"
 #include "chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
@@ -1685,9 +1686,10 @@
   // start terminal app on completion.  After starting the installer,
   // we call RestartCrostini and we will be put in the pending restarters
   // queue and be notified on success/otherwise of installation.
-  CrostiniInstallerView::Show(
-      profile, crostini::CrostiniInstaller::GetForProfile(profile));
-  CrostiniInstallerView::GetActiveViewForTesting()->Accept();
+  chromeos::CrostiniInstallerDialog::Show(
+      profile, base::BindOnce([](chromeos::CrostiniInstallerUI* installer_ui) {
+        installer_ui->ClickInstallForTesting();
+      }));
   crostini::CrostiniManager::GetForProfile(profile)->RestartCrostini(
       crostini::kCrostiniDefaultVmName, crostini::kCrostiniDefaultContainerName,
       base::BindOnce(
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc
index 97936b12..7759f56 100644
--- a/chrome/browser/chromeos/extensions/default_app_order.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -60,7 +60,6 @@
     arc::kPlayGamesAppId,
     arc::kPlayBooksAppId,                   // Play Books ARC app
     extension_misc::kGooglePlayBooksAppId,  // Play Books Chrome app
-    ash::kInternalAppIdCamera,
     extension_misc::kCameraAppId,
     extension_misc::kGooglePhotosAppId,
     arc::kGooglePhotosAppId,
diff --git a/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc b/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc
index 4d64867..7a3be62 100644
--- a/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc
+++ b/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc
@@ -98,18 +98,10 @@
 
 }  // namespace
 
-void FindCrostiniTasks(Profile* profile,
-                       const std::vector<extensions::EntryInfo>& entries,
-                       std::vector<FullTaskDescriptor>* result_list,
-                       base::OnceClosure completion_closure) {
-  if (!crostini::CrostiniFeatures::Get()->IsUIAllowed(profile)) {
-    std::move(completion_closure).Run();
-    return;
-  }
-
-  std::vector<std::string> result_app_ids;
-  std::vector<std::string> result_app_names;
-
+void FindCrostiniApps(Profile* profile,
+                      const std::vector<extensions::EntryInfo>& entries,
+                      std::vector<std::string>* app_ids,
+                      std::vector<std::string>* app_names) {
   crostini::CrostiniRegistryService* registry_service =
       crostini::CrostiniRegistryServiceFactory::GetForProfile(profile);
   crostini::CrostiniMimeTypesService* mime_types_service =
@@ -122,8 +114,20 @@
     bool had_unsupported_mime_type = false;
     for (const extensions::EntryInfo& entry : entries) {
       if (supported_mime_types.find(entry.mime_type) !=
-          supported_mime_types.end())
+          supported_mime_types.end()) {
         continue;
+      }
+
+      // Allow files with type text/* to be opened with a text/plain application
+      // as per xdg spec.
+      // https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html.
+      // TODO(crbug.com/1032910): Add xdg mime support for aliases, subclasses.
+      if (base::StartsWith(entry.mime_type, "text/",
+                           base::CompareCase::SENSITIVE) &&
+          supported_mime_types.find(kUnknownTextMimeType) !=
+              supported_mime_types.end()) {
+        continue;
+      }
       // If we see either of these then we use the Linux container MIME type
       // mappings as alternates for finding an appropriate app since these are
       // the defaults when Chrome can't figure out the exact MIME type (but they
@@ -133,17 +137,32 @@
         std::string alternate_mime_type = mime_types_service->GetMimeType(
             entry.path, registration.VmName(), registration.ContainerName());
         if (supported_mime_types.find(alternate_mime_type) !=
-            supported_mime_types.end())
+            supported_mime_types.end()) {
           continue;
+        }
       }
       had_unsupported_mime_type = true;
       break;
     }
     if (had_unsupported_mime_type)
       continue;
-    result_app_ids.push_back(app_id);
-    result_app_names.push_back(registration.Name());
+    app_ids->push_back(app_id);
+    app_names->push_back(registration.Name());
   }
+}
+
+void FindCrostiniTasks(Profile* profile,
+                       const std::vector<extensions::EntryInfo>& entries,
+                       std::vector<FullTaskDescriptor>* result_list,
+                       base::OnceClosure completion_closure) {
+  if (!crostini::CrostiniFeatures::Get()->IsUIAllowed(profile)) {
+    std::move(completion_closure).Run();
+    return;
+  }
+
+  std::vector<std::string> result_app_ids;
+  std::vector<std::string> result_app_names;
+  FindCrostiniApps(profile, entries, &result_app_ids, &result_app_names);
 
   if (result_app_ids.empty()) {
     std::move(completion_closure).Run();
diff --git a/chrome/browser/chromeos/file_manager/crostini_file_tasks.h b/chrome/browser/chromeos/file_manager/crostini_file_tasks.h
index aa1eca6..8e5c31b0 100644
--- a/chrome/browser/chromeos/file_manager/crostini_file_tasks.h
+++ b/chrome/browser/chromeos/file_manager/crostini_file_tasks.h
@@ -28,6 +28,13 @@
 constexpr char kCrostiniAppActionID[] = "open-with";
 
 // Finds the Crostini tasks that can handle |entries|, appends them to
+// Finds the Crostini |app_ids| and |app_names| that can handle |entries|.
+// VisibleForTesting.  Called by |FindCrostiniTasks|.
+void FindCrostiniApps(Profile* profile,
+                      const std::vector<extensions::EntryInfo>& entries,
+                      std::vector<std::string>* app_ids,
+                      std::vector<std::string>* app_names);
+
 // |result_list|, and calls back to |callback| once finished.
 void FindCrostiniTasks(Profile* profile,
                        const std::vector<extensions::EntryInfo>& entries,
diff --git a/chrome/browser/chromeos/file_manager/crostini_file_tasks_unittest.cc b/chrome/browser/chromeos/file_manager/crostini_file_tasks_unittest.cc
new file mode 100644
index 0000000..efb6f3f
--- /dev/null
+++ b/chrome/browser/chromeos/file_manager/crostini_file_tasks_unittest.cc
@@ -0,0 +1,135 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/file_manager/crostini_file_tasks.h"
+
+#include "base/files/file_path.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
+#include "content/public/test/browser_task_environment.h"
+#include "extensions/browser/entry_info.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace file_manager {
+namespace file_tasks {
+
+class CrostiniFileTasksTest : public testing::Test {
+ public:
+  CrostiniFileTasksTest() {}
+
+ protected:
+  void AddApp(const std::string& id,
+              const std::string& name,
+              const std::string& mime) {
+    // crostini.registry {<id>: {container_name: "penguin", name: {"": <name>},
+    //                           mime_types: [<mime>,], vm_name: "termina"}}
+    DictionaryPrefUpdate update(profile_.GetPrefs(),
+                                crostini::prefs::kCrostiniRegistry);
+    base::DictionaryValue* registry = update.Get();
+    base::Value app(base::Value::Type::DICTIONARY);
+    app.SetKey("container_name", base::Value("penguin"));
+    base::Value mimes(base::Value::Type::LIST);
+    mimes.Append(mime);
+    app.SetKey("mime_types", std::move(mimes));
+    base::Value name_dict(base::Value::Type::DICTIONARY);
+    name_dict.SetKey("", base::Value(name));
+    app.SetKey("name", std::move(name_dict));
+    app.SetKey("vm_name", base::Value("termina"));
+    registry->SetKey(id, std::move(app));
+  }
+
+  void AddEntry(const std::string& path, const std::string& mime) {
+    entries_.push_back(
+        extensions::EntryInfo(base::FilePath(path), mime, false));
+  }
+
+  void AddMime(const std::string& file_ext, const std::string& mime) {
+    // crostini.mime_types {<termina/penguin/<file_ext>:
+    // {container_name: "penguin", mime_type: <mime>, vm_name: "termina"}}
+    DictionaryPrefUpdate update(profile_.GetPrefs(),
+                                crostini::prefs::kCrostiniMimeTypes);
+    base::DictionaryValue* mimes = update.Get();
+    base::Value mime_dict(base::Value::Type::DICTIONARY);
+    mime_dict.SetKey("container_name", base::Value("penguin"));
+    mime_dict.SetKey("mime_type", base::Value(mime));
+    mime_dict.SetKey("vm_name", base::Value("termina"));
+    mimes->SetKey("termina/penguin/" + file_ext, std::move(mime_dict));
+  }
+
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
+  std::vector<extensions::EntryInfo> entries_;
+  std::vector<std::string> app_ids_;
+  std::vector<std::string> app_names_;
+
+  DISALLOW_COPY_AND_ASSIGN(CrostiniFileTasksTest);
+};
+
+TEST_F(CrostiniFileTasksTest, NoApps) {
+  AddApp("app1", "name1", "test/mime1");
+  AddEntry("entry.txt", "test/mime2");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::IsEmpty());
+  EXPECT_THAT(app_names_, testing::IsEmpty());
+}
+
+TEST_F(CrostiniFileTasksTest, AppRegisteredForMime) {
+  AddApp("app1", "name1", "test/mime1");
+  AddEntry("entry.txt", "test/mime1");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::ElementsAre("app1"));
+  EXPECT_THAT(app_names_, testing::ElementsAre("name1"));
+}
+
+TEST_F(CrostiniFileTasksTest, NotAllEntries) {
+  AddApp("app1", "name1", "test/mime1");
+  AddApp("app2", "name2", "test/mime2");
+  AddEntry("entry1.txt", "test/mime1");
+  AddEntry("entry2.txt", "test/mime2");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::IsEmpty());
+  EXPECT_THAT(app_names_, testing::IsEmpty());
+}
+
+TEST_F(CrostiniFileTasksTest, MultipleAppsRegistered) {
+  AddApp("app1", "name1", "test/mime1");
+  AddApp("app2", "name2", "test/mime1");
+  AddEntry("entry.txt", "test/mime1");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::ElementsAre("app1", "app2"));
+  EXPECT_THAT(app_names_, testing::ElementsAre("name1", "name2"));
+}
+
+TEST_F(CrostiniFileTasksTest, AppRegisteredForTextPlain) {
+  AddApp("app1", "name1", "text/plain");
+  AddEntry("entry.js", "text/javascript");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::ElementsAre("app1"));
+  EXPECT_THAT(app_names_, testing::ElementsAre("name1"));
+}
+
+TEST_F(CrostiniFileTasksTest, MimeServiceForTextPlain) {
+  AddApp("app1", "name1", "test/mime1");
+  AddEntry("entry.unknown", "text/plain");
+  AddMime("unknown", "test/mime1");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::ElementsAre("app1"));
+  EXPECT_THAT(app_names_, testing::ElementsAre("name1"));
+}
+
+TEST_F(CrostiniFileTasksTest, MimeServiceForApplicationOctetStream) {
+  AddApp("app1", "name1", "test/mime1");
+  AddEntry("entry.unknown", "application/octet-stream");
+  AddMime("unknown", "test/mime1");
+  FindCrostiniApps(&profile_, entries_, &app_ids_, &app_names_);
+  EXPECT_THAT(app_ids_, testing::ElementsAre("app1"));
+  EXPECT_THAT(app_names_, testing::ElementsAre("name1"));
+}
+
+}  // namespace file_tasks
+}  // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc
index d5b8872..2142f91 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -925,7 +925,8 @@
 void VolumeManager::OnFormatEvent(
     chromeos::disks::DiskMountManager::FormatEvent event,
     chromeos::FormatError error_code,
-    const std::string& device_path) {
+    const std::string& device_path,
+    const std::string& device_label) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DVLOG(1) << "OnDeviceEvent: " << event << ", " << error_code
            << ", " << device_path;
@@ -960,7 +961,8 @@
 void VolumeManager::OnRenameEvent(
     chromeos::disks::DiskMountManager::RenameEvent event,
     chromeos::RenameError error_code,
-    const std::string& device_path) {
+    const std::string& device_path,
+    const std::string& device_label) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DVLOG(1) << "OnDeviceEvent: " << event << ", " << error_code << ", "
            << device_path;
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.h b/chrome/browser/chromeos/file_manager/volume_manager.h
index 12ae400..635b362 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.h
+++ b/chrome/browser/chromeos/file_manager/volume_manager.h
@@ -387,10 +387,12 @@
                         mount_info) override;
   void OnFormatEvent(chromeos::disks::DiskMountManager::FormatEvent event,
                      chromeos::FormatError error_code,
-                     const std::string& device_path) override;
+                     const std::string& device_path,
+                     const std::string& device_label) override;
   void OnRenameEvent(chromeos::disks::DiskMountManager::RenameEvent event,
                      chromeos::RenameError error_code,
-                     const std::string& device_path) override;
+                     const std::string& device_path,
+                     const std::string& device_label) override;
 
   // chromeos::file_system_provider::Observer overrides.
   void OnProvidedFileSystemMount(
diff --git a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
index 71378f23..87f1091 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
@@ -674,7 +674,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnFormatEvent(DiskMountManager::FORMAT_STARTED,
-                                  chromeos::FORMAT_ERROR_NONE, "device1");
+                                  chromeos::FORMAT_ERROR_NONE, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -690,7 +691,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnFormatEvent(DiskMountManager::FORMAT_STARTED,
-                                  chromeos::FORMAT_ERROR_UNKNOWN, "device1");
+                                  chromeos::FORMAT_ERROR_UNKNOWN, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -706,7 +708,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                                  chromeos::FORMAT_ERROR_NONE, "device1");
+                                  chromeos::FORMAT_ERROR_NONE, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -731,7 +734,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                                  chromeos::FORMAT_ERROR_UNKNOWN, "device1");
+                                  chromeos::FORMAT_ERROR_UNKNOWN, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -994,7 +998,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnRenameEvent(DiskMountManager::RENAME_STARTED,
-                                  chromeos::RENAME_ERROR_NONE, "device1");
+                                  chromeos::RENAME_ERROR_NONE, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -1010,7 +1015,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnRenameEvent(DiskMountManager::RENAME_STARTED,
-                                  chromeos::RENAME_ERROR_UNKNOWN, "device1");
+                                  chromeos::RENAME_ERROR_UNKNOWN, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -1026,7 +1032,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnRenameEvent(DiskMountManager::RENAME_COMPLETED,
-                                  chromeos::RENAME_ERROR_NONE, "device1");
+                                  chromeos::RENAME_ERROR_NONE, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
@@ -1050,7 +1057,8 @@
   volume_manager()->AddObserver(&observer);
 
   volume_manager()->OnRenameEvent(DiskMountManager::RENAME_COMPLETED,
-                                  chromeos::RENAME_ERROR_UNKNOWN, "device1");
+                                  chromeos::RENAME_ERROR_UNKNOWN, "device1",
+                                  "label1");
 
   ASSERT_EQ(1U, observer.events().size());
   const LoggingObserver::Event& event = observer.events()[0];
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index 7d9f3a4d5..526a4977 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -40,9 +40,9 @@
 
 namespace {
 
-const char kErrorNotActive[] = "IME is not active";
-const char kErrorWrongContext[] = "Context is not active";
-const char kCandidateNotFound[] = "Candidate not found";
+const char kErrorNotActive[] = "IME is not active.";
+const char kErrorWrongContext[] = "Context is not active.";
+const char kCandidateNotFound[] = "Candidate not found.";
 
 // The default entry number of a page in CandidateWindowProperty.
 const int kDefaultPageSize = 9;
@@ -208,7 +208,8 @@
   std::map<int, int>::const_iterator position =
       candidate_indexes_.find(candidate_id);
   if (position == candidate_indexes_.end()) {
-    *error = kCandidateNotFound;
+    *error = base::StringPrintf("%s candidate id = %d", kCandidateNotFound,
+                                candidate_id);
     return false;
   }
 
@@ -221,14 +222,18 @@
 }
 
 bool InputMethodEngine::SetMenuItems(
-    const std::vector<input_method::InputMethodManager::MenuItem>& items) {
-  return UpdateMenuItems(items);
+    const std::vector<input_method::InputMethodManager::MenuItem>& items,
+    std::string* error) {
+  return UpdateMenuItems(items, error);
 }
 
 bool InputMethodEngine::UpdateMenuItems(
-    const std::vector<input_method::InputMethodManager::MenuItem>& items) {
-  if (!IsActive())
+    const std::vector<input_method::InputMethodManager::MenuItem>& items,
+    std::string* error) {
+  if (!IsActive()) {
+    *error = kErrorNotActive;
     return false;
+  }
 
   ui::ime::InputMethodMenuItemList menu_item_list;
   for (const auto& item : items) {
@@ -300,7 +305,8 @@
 }
 
 bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event,
-                                     const std::string& code) {
+                                     const std::string& code,
+                                     std::string* error) {
   DCHECK(event);
   if (event->key_code() == ui::VKEY_UNKNOWN)
     event->set_key_code(ui::DomKeycodeToKeyboardCode(code));
@@ -319,6 +325,8 @@
     input_context->SendKeyEvent(event);
     return true;
   }
+
+  *error = kErrorWrongContext;
   return false;
 }
 
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index d3adc25..da34364ce 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -119,11 +119,13 @@
   // Set the list of items that appears in the language menu when this IME is
   // active.
   bool SetMenuItems(
-      const std::vector<input_method::InputMethodManager::MenuItem>& items);
+      const std::vector<input_method::InputMethodManager::MenuItem>& items,
+      std::string* error);
 
   // Update the state of the menu items.
   bool UpdateMenuItems(
-      const std::vector<input_method::InputMethodManager::MenuItem>& items);
+      const std::vector<input_method::InputMethodManager::MenuItem>& items,
+      std::string* error);
 
   // Hides the input view window (from API call).
   void HideInputView();
@@ -142,7 +144,10 @@
 
   void CommitTextToInputContext(int context_id,
                                 const std::string& text) override;
-  bool SendKeyEvent(ui::KeyEvent* event, const std::string& code) override;
+
+  bool SendKeyEvent(ui::KeyEvent* event,
+                    const std::string& code,
+                    std::string* error) override;
 
   // Enables overriding input view page to Virtual Keyboard window.
   void EnableInputView();
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index 99d8484f..1062e60 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -42,8 +42,8 @@
 const char kTestExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf";
 const char kTestExtensionId2[] = "dmpipdbjkoajgdeppkffbjhngfckdloi";
 const char kTestImeComponentId[] = "test_engine_id";
-const char kErrorNotActive[] = "IME is not active";
-const char kErrorInvalidValue[] = "Argument '%s' with value '%d' is not valid";
+const char kErrorNotActive[] = "IME is not active.";
+const char kErrorInvalidValue[] = "Argument '%s' with value '%d' is not valid.";
 
 enum CallsBitmap {
   NONE = 0U,
diff --git a/chrome/browser/chromeos/login/test/oobe_screen_waiter.cc b/chrome/browser/chromeos/login/test/oobe_screen_waiter.cc
index a7326a2..9f22009 100644
--- a/chrome/browser/chromeos/login/test/oobe_screen_waiter.cc
+++ b/chrome/browser/chromeos/login/test/oobe_screen_waiter.cc
@@ -42,7 +42,7 @@
   run_loop_->Run();
   run_loop_.reset();
 
-  DCHECK_EQ(State::DONE, state_);
+  ASSERT_EQ(State::DONE, state_);
 
   oobe_ui_observer_.RemoveAll();
   if (check_native_window_visible_)
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.cc b/chrome/browser/chromeos/login/web_kiosk_controller.cc
index 2c92b4b..301aa64 100644
--- a/chrome/browser/chromeos/login/web_kiosk_controller.cc
+++ b/chrome/browser/chromeos/login/web_kiosk_controller.cc
@@ -287,6 +287,23 @@
     LaunchApp();
 }
 
+void WebKioskController::OnAppInstallFailed() {
+  // When app installation, still try running the app(there can network/app
+  // restrictions that block app launch until we handle them).
+  // For example, chat.google.com on the first launch opens accounts.google.com
+  // to get the gaia id.
+  app_state_ = AppState::INSTALLED;
+
+  if (!web_kiosk_splash_screen_view_)
+    return;
+  web_kiosk_splash_screen_view_->UpdateAppLaunchState(
+      AppLaunchSplashScreenView::AppLaunchState::
+          APP_LAUNCH_STATE_WAITING_APP_WINDOW_INSTALL_FAILED);
+  web_kiosk_splash_screen_view_->Show();
+  if (launch_on_install_)
+    LaunchApp();
+}
+
 void WebKioskController::LaunchApp() {
   DCHECK(app_state_ == AppState::INSTALLED);
   // We need to change the session state so we are able to create browser
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.h b/chrome/browser/chromeos/login/web_kiosk_controller.h
index 466a949..a7c2bac 100644
--- a/chrome/browser/chromeos/login/web_kiosk_controller.h
+++ b/chrome/browser/chromeos/login/web_kiosk_controller.h
@@ -102,6 +102,7 @@
   void InitializeNetwork() override;
   void OnAppStartedInstalling() override;
   void OnAppPrepared() override;
+  void OnAppInstallFailed() override;
   void OnAppLaunched() override;
   void OnAppLaunchFailed() override;
 
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.cc
index e374e85..828cbb3 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.cc
@@ -40,9 +40,8 @@
 
 namespace {
 
-void CreateTemporaryDriveDownloadFile(base::FilePath* file_path) {
-  const base::FilePath drive_directory(kPluginVmDriveDownloadDirectory);
-
+void CreateTemporaryDriveDownloadFile(const base::FilePath& drive_directory,
+                                      base::FilePath* file_path) {
   if (!base::DeleteFileRecursively(drive_directory)) {
     LOG(ERROR) << "PluginVM Drive download folder failed to be removed";
   }
@@ -145,9 +144,7 @@
 }
 
 void PluginVmDriveImageDownloadService::StartDownload(
-    const std::string& file_id,
-    OnDownloadStartedCallback on_download_started_callback,
-    OnDownloadFailedCallback on_download_failed_callback) {
+    const std::string& file_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   file_id_ = file_id;
@@ -156,16 +153,13 @@
   base::PostTaskAndReply(
       FROM_HERE,
       {base::ThreadPool(), base::TaskPriority::USER_VISIBLE, base::MayBlock()},
-      base::BindOnce(&CreateTemporaryDriveDownloadFile, &download_file_path_),
+      base::BindOnce(&CreateTemporaryDriveDownloadFile, download_directory_,
+                     &download_file_path_),
       base::BindOnce(&PluginVmDriveImageDownloadService::DispatchDownloadFile,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(on_download_started_callback),
-                     std::move(on_download_failed_callback)));
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
-void PluginVmDriveImageDownloadService::DispatchDownloadFile(
-    OnDownloadStartedCallback on_download_started_callback,
-    OnDownloadFailedCallback on_download_failed_callback) {
+void PluginVmDriveImageDownloadService::DispatchDownloadFile() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (base::PathExists(download_file_path_)) {
@@ -181,10 +175,10 @@
             &PluginVmDriveImageDownloadService::ProgressCallback,
             weak_ptr_factory_.GetWeakPtr()));
 
-    std::move(on_download_started_callback).Run();
+    plugin_vm_image_manager_->OnDownloadStarted();
   } else {
-    std::move(on_download_failed_callback)
-        .Run(PluginVmImageManager::FailureReason::DOWNLOAD_FAILED_UNKNOWN);
+    plugin_vm_image_manager_->OnDownloadFailed(
+        PluginVmImageManager::FailureReason::DOWNLOAD_FAILED_UNKNOWN);
   }
 }
 
@@ -203,11 +197,20 @@
   base::PostTaskAndReplyWithResult(
       FROM_HERE,
       {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::MayBlock()},
-      base::BindOnce(&base::DeleteFileRecursively,
-                     base::FilePath(kPluginVmDriveDownloadDirectory)),
+      base::BindOnce(&base::DeleteFileRecursively, download_directory_),
       std::move(on_file_deleted_callback));
 }
 
+void PluginVmDriveImageDownloadService::SetDriveServiceForTesting(
+    std::unique_ptr<drive::DriveServiceInterface> drive_service) {
+  drive_service_ = std::move(drive_service);
+}
+
+void PluginVmDriveImageDownloadService::SetDownloadDirectoryForTesting(
+    const base::FilePath& download_directory) {
+  download_directory_ = download_directory;
+}
+
 void PluginVmDriveImageDownloadService::DownloadActionCallback(
     google_apis::DriveApiErrorCode error_code,
     const base::FilePath& file_path) {
@@ -228,7 +231,6 @@
   secure_hash_service_->Finish(sha256_hash.data(), sha256_hash.size());
   completion_info.hash256 =
       base::HexEncode(sha256_hash.data(), sha256_hash.size());
-
   plugin_vm_image_manager_->OnDownloadCompleted(completion_info);
 }
 
@@ -241,7 +243,6 @@
         ConvertToFailureReason(error_code));
     return;
   }
-
   secure_hash_service_->Update(content->c_str(), content->length());
   total_bytes_downloaded_ += content->length();
 }
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.h
index b7f4db3..88aadad 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.h
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.h
@@ -50,9 +50,7 @@
       const PluginVmDriveImageDownloadService&) = delete;
   ~PluginVmDriveImageDownloadService();
 
-  void StartDownload(const std::string& id,
-                     OnDownloadStartedCallback on_download_started_callback,
-                     OnDownloadFailedCallback on_download_failed_callback);
+  void StartDownload(const std::string& id);
   void CancelDownload();
 
   // Used to reset the internal state of the downloader.
@@ -62,10 +60,12 @@
   // on a non-UI thread.
   void RemoveTemporaryArchive(OnFileDeletedCallback on_file_deleted_callback);
 
+  void SetDriveServiceForTesting(
+      std::unique_ptr<drive::DriveServiceInterface> drive_service);
+  void SetDownloadDirectoryForTesting(const base::FilePath& download_directory);
+
  private:
-  void DispatchDownloadFile(
-      OnDownloadStartedCallback on_download_started_callback,
-      OnDownloadFailedCallback on_download_failed_callback);
+  void DispatchDownloadFile();
 
   void DownloadActionCallback(google_apis::DriveApiErrorCode error_code,
                               const base::FilePath& file_path);
@@ -78,6 +78,7 @@
   std::unique_ptr<crypto::SecureHash> secure_hash_service_;
   std::string file_id_;
   int64_t total_bytes_downloaded_ = 0;
+  base::FilePath download_directory_{kPluginVmDriveDownloadDirectory};
   base::FilePath download_file_path_;
   google_apis::CancelCallback cancel_callback_;
 
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
index 30271e51..6768235 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
@@ -118,12 +118,7 @@
       drive_download_service_->ResetState();
     }
 
-    drive_download_service_->StartDownload(
-        GetIdFromDriveUrl(url),
-        base::BindOnce(&PluginVmImageManager::OnDownloadStarted,
-                       weak_ptr_factory_.GetWeakPtr()),
-        base::BindOnce(&PluginVmImageManager::OnDownloadFailed,
-                       weak_ptr_factory_.GetWeakPtr()));
+    drive_download_service_->StartDownload(GetIdFromDriveUrl(url));
   } else {
     download_service_->StartDownload(GetDownloadParams(url));
   }
@@ -508,6 +503,11 @@
   return current_download_guid_;
 }
 
+void PluginVmImageManager::SetDriveDownloadServiceForTesting(
+    std::unique_ptr<PluginVmDriveImageDownloadService> drive_download_service) {
+  drive_download_service_ = std::move(drive_download_service);
+}
+
 PluginVmImageManager::PluginVmImageManager(Profile* profile)
     : profile_(profile),
       download_service_(
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h
index c667c2d..8767cc85 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h
@@ -150,6 +150,9 @@
       download::DownloadService* download_service);
   void SetDownloadedPluginVmImageArchiveForTesting(
       const base::FilePath& downloaded_plugin_vm_image_archive);
+  void SetDriveDownloadServiceForTesting(
+      std::unique_ptr<PluginVmDriveImageDownloadService>
+          drive_download_service);
   std::string GetCurrentDownloadGuidForTesting();
 
  private:
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
index 219e256..40190b09 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
 
+#include <stdint.h>
+#include <string.h>
+
 #include <memory>
 #include <string>
 #include <utility>
@@ -13,6 +16,7 @@
 #include "base/optional.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_drive_image_download_service.h"
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h"
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_metrics_util.h"
@@ -27,9 +31,13 @@
 #include "chromeos/dbus/fake_concierge_client.h"
 #include "components/account_id/account_id.h"
 #include "components/download/public/background_service/test/test_download_service.h"
+#include "components/drive/service/dummy_drive_service.h"
+#include "components/drive/service/fake_drive_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/browser_task_environment.h"
+#include "google_apis/drive/drive_api_error_codes.h"
+#include "google_apis/drive/test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -38,15 +46,20 @@
 namespace {
 
 using ::testing::_;
+using ::testing::AtLeast;
 
 const char kProfileName[] = "p1";
 const char kUrl[] = "http://example.com";
+const char kDriveUrl[] = "https://drive.google.com/open?id=fakedriveid";
+const char kDriveId[] = "fakedriveid";
+const char kDriveUrl2[] = "https://drive.google.com/open?id=nonexistantdriveid";
+const char kDriveContentType[] = "application/zip";
 const char kPluginVmImageFile[] = "plugin_vm_image_file_1.zip";
 const char kContent[] = "This is zipped content.";
 const char kHash[] =
-    "842841a4c75a55ad050d686f4ea5f77e83ae059877fe9b6946aa63d3d057ed32";
+    "c80344fd4a0e9ee9f803f64edb3ea3ed8b11fe300869817e8fd50898d0663c35";
 const char kHashUppercase[] =
-    "842841A4C75A55AD050D686F4EA5F77E83AE059877FE9B6946AA63D3D057ED32";
+    "C80344FD4A0E9EE9F803F64EDB3EA3ED8B11FE300869817E8FD50898D0663C35";
 const char kHash2[] =
     "02f06421ae27144aacdc598aebcd345a5e2e634405e8578300173628fe1574bd";
 // File size set in test_download_service.
@@ -80,10 +93,62 @@
                void(plugin_vm::PluginVmImageManager::FailureReason));
 };
 
-class PluginVmImageManagerTest : public testing::Test {
+// We are inheriting from DummyDriveService instead of DriveServiceInterface
+// here since we are only interested in a couple of methods and don't need to
+// define the rest.
+class SimpleFakeDriveService : public drive::DummyDriveService {
  public:
-  PluginVmImageManagerTest() = default;
-  ~PluginVmImageManagerTest() override = default;
+  using DownloadActionCallback = google_apis::DownloadActionCallback;
+  using GetContentCallback = google_apis::GetContentCallback;
+  using ProgressCallback = google_apis::ProgressCallback;
+
+  void RunDownloadActionCallback(google_apis::DriveApiErrorCode error,
+                                 const base::FilePath& temp_file) {
+    download_action_callback_.Run(error, temp_file);
+  }
+
+  void RunGetContentCallback(google_apis::DriveApiErrorCode error,
+                             std::unique_ptr<std::string> content) {
+    get_content_callback_.Run(error, std::move(content));
+  }
+
+  void RunProgressCallback(int64_t progress, int64_t total) {
+    progress_callback_.Run(progress, total);
+  }
+
+  bool cancel_callback_called() const { return cancel_callback_called_; }
+
+  // DriveServiceInterface override.
+  google_apis::CancelCallback DownloadFile(
+      const base::FilePath& /*cache_path*/,
+      const std::string& /*resource_id*/,
+      const DownloadActionCallback& download_action_callback,
+      const GetContentCallback& get_content_callback,
+      const ProgressCallback& progress_callback) override {
+    download_action_callback_ = download_action_callback;
+    get_content_callback_ = get_content_callback;
+    progress_callback_ = progress_callback;
+
+    // It is safe to use base::Unretained as this object will not get deleted
+    // before the end of the test.
+    return base::BindRepeating(&SimpleFakeDriveService::CancelCallback,
+                               base::Unretained(this));
+  }
+
+ private:
+  void CancelCallback() { cancel_callback_called_ = true; }
+
+  bool cancel_callback_called_{false};
+
+  DownloadActionCallback download_action_callback_;
+  GetContentCallback get_content_callback_;
+  ProgressCallback progress_callback_;
+};
+
+class PluginVmImageManagerTestBase : public testing::Test {
+ public:
+  PluginVmImageManagerTestBase() = default;
+  ~PluginVmImageManagerTestBase() override = default;
 
  protected:
   void SetUp() override {
@@ -98,17 +163,9 @@
     SetPluginVmImagePref(kUrl, kHash);
 
     manager_ = PluginVmImageManagerFactory::GetForProfile(profile_.get());
-    download_service_ = std::make_unique<download::test::TestDownloadService>();
-    download_service_->SetIsReady(true);
-    download_service_->SetHash256(kHash);
-    client_ = std::make_unique<PluginVmImageDownloadClient>(profile_.get());
-    download_service_->set_client(client_.get());
-    manager_->SetDownloadServiceForTesting(download_service_.get());
     observer_ = std::make_unique<MockObserver>();
     manager_->SetObserver(observer_.get());
 
-    fake_downloaded_plugin_vm_image_archive_ = CreateZipFile();
-    histogram_tester_ = std::make_unique<base::HistogramTester>();
     fake_concierge_client_ = static_cast<chromeos::FakeConciergeClient*>(
         chromeos::DBusThreadManager::Get()->GetConciergeClient());
 
@@ -118,10 +175,7 @@
   }
 
   void TearDown() override {
-    histogram_tester_.reset();
     observer_.reset();
-    download_service_.reset();
-    client_.reset();
     plugin_vm_test_helper_.reset();
     profile_.reset();
     observer_.reset();
@@ -155,21 +209,12 @@
     task_environment_.RunUntilIdle();
   }
 
-  base::FilePath CreateZipFile() {
-    base::FilePath zip_file_path =
-        profile_->GetPath().AppendASCII(kPluginVmImageFile);
-    base::WriteFile(zip_file_path, kContent, strlen(kContent));
-    return zip_file_path;
-  }
-
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<PluginVmTestHelper> plugin_vm_test_helper_;
   PluginVmImageManager* manager_;
-  std::unique_ptr<download::test::TestDownloadService> download_service_;
   std::unique_ptr<MockObserver> observer_;
   base::FilePath fake_downloaded_plugin_vm_image_archive_;
-  std::unique_ptr<base::HistogramTester> histogram_tester_;
   // Owned by chromeos::DBusThreadManager
   chromeos::FakeConciergeClient* fake_concierge_client_;
   chromeos::FakeDlcserviceClient* fake_dlcservice_client_;
@@ -187,12 +232,112 @@
   }
 
   base::ScopedTempDir profiles_dir_;
-  std::unique_ptr<PluginVmImageDownloadClient> client_;
 
-  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerTest);
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerTestBase);
 };
 
-TEST_F(PluginVmImageManagerTest, DownloadPluginVmImageParamsTest) {
+class PluginVmImageManagerDownloadServiceTest
+    : public PluginVmImageManagerTestBase {
+ public:
+  PluginVmImageManagerDownloadServiceTest() = default;
+  ~PluginVmImageManagerDownloadServiceTest() override = default;
+
+ protected:
+  void SetUp() override {
+    PluginVmImageManagerTestBase::SetUp();
+
+    download_service_ = std::make_unique<download::test::TestDownloadService>();
+    download_service_->SetIsReady(true);
+    download_service_->SetHash256(kHash);
+    client_ = std::make_unique<PluginVmImageDownloadClient>(profile_.get());
+    download_service_->set_client(client_.get());
+    manager_->SetDownloadServiceForTesting(download_service_.get());
+    histogram_tester_ = std::make_unique<base::HistogramTester>();
+    fake_downloaded_plugin_vm_image_archive_ = CreateZipFile();
+  }
+
+  void TearDown() override {
+    PluginVmImageManagerTestBase::TearDown();
+
+    histogram_tester_.reset();
+    download_service_.reset();
+    client_.reset();
+  }
+
+  base::FilePath CreateZipFile() {
+    base::FilePath zip_file_path =
+        profile_->GetPath().AppendASCII(kPluginVmImageFile);
+    base::WriteFile(zip_file_path, kContent, strlen(kContent));
+    return zip_file_path;
+  }
+
+  std::unique_ptr<download::test::TestDownloadService> download_service_;
+  std::unique_ptr<base::HistogramTester> histogram_tester_;
+
+ private:
+  std::unique_ptr<PluginVmImageDownloadClient> client_;
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerDownloadServiceTest);
+};
+
+class PluginVmImageManagerDriveTest : public PluginVmImageManagerTestBase {
+ public:
+  PluginVmImageManagerDriveTest() = default;
+  ~PluginVmImageManagerDriveTest() override = default;
+
+ protected:
+  void SetUp() override {
+    PluginVmImageManagerTestBase::SetUp();
+
+    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
+    std::unique_ptr<google_apis::FileResource> entry;
+    auto fake_drive_service = std::make_unique<drive::FakeDriveService>();
+    // We will need to access this object for some tests in the future.
+    fake_drive_service_ = fake_drive_service.get();
+    fake_drive_service->AddNewFileWithResourceId(
+        kDriveId, kDriveContentType, kContent,
+        "",  // parent_resource_id
+        kPluginVmImageFile,
+        true,  // shared_with_me
+        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
+    base::RunLoop().RunUntilIdle();
+    ASSERT_EQ(google_apis::HTTP_CREATED, error);
+    ASSERT_TRUE(entry);
+
+    auto drive_download_service =
+        std::make_unique<PluginVmDriveImageDownloadService>(manager_,
+                                                            profile_.get());
+    // We will need to access this object for some tests in the future.
+    drive_download_service_ = drive_download_service.get();
+
+    base::ScopedTempDir temp_dir;
+    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+    drive_download_service->SetDownloadDirectoryForTesting(temp_dir.Take());
+    drive_download_service->SetDriveServiceForTesting(
+        std::move(fake_drive_service));
+
+    manager_->SetDriveDownloadServiceForTesting(
+        std::move(drive_download_service));
+  }
+
+  SimpleFakeDriveService* SetUpSimpleFakeDriveService() {
+    auto fake_drive_service = std::make_unique<SimpleFakeDriveService>();
+    SimpleFakeDriveService* fake_drive_service_ptr = fake_drive_service.get();
+
+    drive_download_service_->SetDriveServiceForTesting(
+        std::move(fake_drive_service));
+
+    return fake_drive_service_ptr;
+  }
+
+  PluginVmDriveImageDownloadService* drive_download_service_;
+  drive::FakeDriveService* fake_drive_service_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PluginVmImageManagerDriveTest);
+};
+
+TEST_F(PluginVmImageManagerDownloadServiceTest,
+       DownloadPluginVmImageParamsTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
 
   EXPECT_CALL(*observer_, OnDlcDownloadStarted());
@@ -222,7 +367,7 @@
   task_environment_.RunUntilIdle();
 }
 
-TEST_F(PluginVmImageManagerTest, OnlyOneImageIsProcessedTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, OnlyOneImageIsProcessedTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
 
   EXPECT_CALL(*observer_, OnDlcDownloadStarted());
@@ -256,7 +401,8 @@
                                         kDownloadedPluginVmImageSizeInMb, 1);
 }
 
-TEST_F(PluginVmImageManagerTest, CanProceedWithANewImageWhenSucceededTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest,
+       CanProceedWithANewImageWhenSucceededTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
 
   EXPECT_CALL(*observer_, OnDownloadCompleted()).Times(2);
@@ -275,7 +421,8 @@
                                         kDownloadedPluginVmImageSizeInMb, 2);
 }
 
-TEST_F(PluginVmImageManagerTest, CanProceedWithANewImageWhenFailedTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest,
+       CanProceedWithANewImageWhenFailedTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
 
   EXPECT_CALL(
@@ -303,7 +450,7 @@
                                         kDownloadedPluginVmImageSizeInMb, 1);
 }
 
-TEST_F(PluginVmImageManagerTest, CancelledDownloadTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, CancelledDownloadTest) {
   EXPECT_CALL(*observer_, OnDownloadCompleted()).Times(0);
   EXPECT_CALL(*observer_, OnDownloadCancelled());
 
@@ -316,7 +463,7 @@
   histogram_tester_->ExpectTotalCount(kPluginVmImageDownloadedSizeHistogram, 0);
 }
 
-TEST_F(PluginVmImageManagerTest, ImportNonExistingImageTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, ImportNonExistingImageTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
 
   EXPECT_CALL(*observer_, OnDownloadCompleted());
@@ -333,7 +480,7 @@
                                         kDownloadedPluginVmImageSizeInMb, 1);
 }
 
-TEST_F(PluginVmImageManagerTest, CancelledImportTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, CancelledImportTest) {
   SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
   SetupConciergeForCancelDiskImageOperation(fake_concierge_client_,
                                             true /* success */);
@@ -351,7 +498,7 @@
   task_environment_.RunUntilIdle();
 }
 
-TEST_F(PluginVmImageManagerTest, EmptyPluginVmImageUrlTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, EmptyPluginVmImageUrlTest) {
   SetPluginVmImagePref("", kHash);
   EXPECT_CALL(
       *observer_,
@@ -363,14 +510,15 @@
   histogram_tester_->ExpectTotalCount(kPluginVmImageDownloadedSizeHistogram, 0);
 }
 
-TEST_F(PluginVmImageManagerTest, VerifyDownloadTest) {
+TEST_F(PluginVmImageManagerDownloadServiceTest, VerifyDownloadTest) {
   EXPECT_FALSE(manager_->VerifyDownload(kHash2));
   EXPECT_TRUE(manager_->VerifyDownload(kHashUppercase));
   EXPECT_TRUE(manager_->VerifyDownload(kHash));
   EXPECT_FALSE(manager_->VerifyDownload(std::string()));
 }
 
-TEST_F(PluginVmImageManagerTest, CannotStartDownloadIfDlcDownloadNotRun) {
+TEST_F(PluginVmImageManagerDownloadServiceTest,
+       CannotStartDownloadIfDlcDownloadNotRun) {
   EXPECT_CALL(
       *observer_,
       OnDownloadFailed(
@@ -380,7 +528,8 @@
   task_environment_.RunUntilIdle();
 }
 
-TEST_F(PluginVmImageManagerTest, CannotStartDlcDownloadIfPluginVmGetsDisabled) {
+TEST_F(PluginVmImageManagerDownloadServiceTest,
+       CannotStartDlcDownloadIfPluginVmGetsDisabled) {
   profile_->ScopedCrosSettingsTestHelper()->SetBoolean(
       chromeos::kPluginVmAllowed, false);
   EXPECT_CALL(
@@ -391,4 +540,98 @@
   task_environment_.RunUntilIdle();
 }
 
+TEST_F(PluginVmImageManagerDriveTest, InvalidDriveUrlTest) {
+  SetPluginVmImagePref(kDriveUrl2, kHash);
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(
+      *observer_,
+      OnDownloadFailed(PluginVmImageManager::FailureReason::INVALID_IMAGE_URL));
+  ProcessImageUntilImporting();
+}
+
+TEST_F(PluginVmImageManagerDriveTest, NoConnectionDriveTest) {
+  SetPluginVmImagePref(kDriveUrl, kHash);
+  fake_drive_service_->set_offline(true);
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(
+      *observer_,
+      OnDownloadFailed(
+          PluginVmImageManager::FailureReason::DOWNLOAD_FAILED_NETWORK));
+  ProcessImageUntilImporting();
+}
+
+TEST_F(PluginVmImageManagerDriveTest, WrongHashDriveTest) {
+  SetPluginVmImagePref(kDriveUrl, kHash2);
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(
+      *observer_,
+      OnDownloadFailed(PluginVmImageManager::FailureReason::HASH_MISMATCH));
+
+  ProcessImageUntilImporting();
+}
+
+TEST_F(PluginVmImageManagerDriveTest, DriveDownloadFailedAfterStartingTest) {
+  SetPluginVmImagePref(kDriveUrl, kHash);
+  SimpleFakeDriveService* fake_drive_service = SetUpSimpleFakeDriveService();
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(*observer_, OnDownloadProgressUpdated(5, 100, _));
+  EXPECT_CALL(*observer_, OnDownloadProgressUpdated(10, 100, _));
+  EXPECT_CALL(
+      *observer_,
+      OnDownloadFailed(
+          PluginVmImageManager::FailureReason::DOWNLOAD_FAILED_NETWORK));
+  EXPECT_CALL(*observer_, OnDownloadCompleted()).Times(0);
+
+  manager_->StartDlcDownload();
+  task_environment_.RunUntilIdle();
+  manager_->StartDownload();
+  task_environment_.RunUntilIdle();
+
+  fake_drive_service->RunGetContentCallback(
+      google_apis::HTTP_SUCCESS, std::make_unique<std::string>("Part1"));
+  fake_drive_service->RunProgressCallback(5, 100);
+  fake_drive_service->RunGetContentCallback(
+      google_apis::HTTP_SUCCESS, std::make_unique<std::string>("Part2"));
+  fake_drive_service->RunProgressCallback(10, 100);
+  fake_drive_service->RunGetContentCallback(google_apis::DRIVE_NO_CONNECTION,
+                                            std::unique_ptr<std::string>());
+}
+
+TEST_F(PluginVmImageManagerDriveTest, CancelledDriveDownloadTest) {
+  SetPluginVmImagePref(kDriveUrl, kHash);
+  SimpleFakeDriveService* fake_drive_service = SetUpSimpleFakeDriveService();
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(*observer_, OnDownloadProgressUpdated(5, 100, _));
+  EXPECT_CALL(*observer_, OnDownloadCompleted()).Times(0);
+
+  manager_->StartDlcDownload();
+  task_environment_.RunUntilIdle();
+  manager_->StartDownload();
+  task_environment_.RunUntilIdle();
+
+  fake_drive_service->RunGetContentCallback(
+      google_apis::HTTP_SUCCESS, std::make_unique<std::string>("Part1"));
+  fake_drive_service->RunProgressCallback(5, 100);
+  manager_->CancelDownload();
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(fake_drive_service->cancel_callback_called());
+}
+
+TEST_F(PluginVmImageManagerDriveTest, SuccessfulDriveDownloadTest) {
+  SetPluginVmImagePref(kDriveUrl, kHash);
+
+  EXPECT_CALL(*observer_, OnDownloadStarted());
+  EXPECT_CALL(*observer_, OnDownloadCompleted());
+  EXPECT_CALL(*observer_,
+              OnDownloadProgressUpdated(_, std::strlen(kContent), _))
+      .Times(AtLeast(1));
+
+  ProcessImageUntilImporting();
+}
+
 }  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
index af983b6..14fcdf2 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
@@ -182,9 +182,9 @@
 
 // TODO(muhamedp): Update if a different url format is ultimately chosen.
 bool IsDriveUrl(const GURL& url) {
-  const std::string url_base = "https://drive.google.com/open?id=";
-  return url.spec().find(url_base) == 0 &&
-         url.spec().length() > url_base.length();
+  const std::string url_base = "https://drive.google.com/open";
+  const std::string& spec = url.spec();
+  return spec.find(url_base) == 0 && spec.find("id=") < (spec.length() - 3);
 }
 
 // TODO(muhamedp): Update if a different url format is ultimately chosen.
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc
index e30c0b6..c7504202 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util_unittest.cc
@@ -98,6 +98,7 @@
   EXPECT_FALSE(IsDriveUrl(GURL("https://othersite.com?id=" + file_id)));
   EXPECT_FALSE(
       IsDriveUrl(GURL("https://drive.google.com.othersite.com?id=" + file_id)));
+  EXPECT_FALSE(IsDriveUrl(GURL(base_url)));
 }
 
 TEST_F(PluginVmUtilTest, DriveLinkIdExtraction) {
diff --git a/chrome/browser/chromeos/policy/device_login_screen_policy_browsertest.cc b/chrome/browser/chromeos/policy/device_login_screen_policy_browsertest.cc
new file mode 100644
index 0000000..64fabcdb
--- /dev/null
+++ b/chrome/browser/chromeos/policy/device_login_screen_policy_browsertest.cc
@@ -0,0 +1,199 @@
+// 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 <string>
+
+#include "ash/public/cpp/ash_pref_names.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
+#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
+#include "chrome/browser/chromeos/policy/device_policy_builder.h"
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/constants/chromeos_switches.h"
+#include "components/policy/core/common/policy_types.h"
+#include "components/policy/proto/chrome_device_policy.pb.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "components/prefs/pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace em = enterprise_management;
+
+namespace policy {
+
+namespace {
+
+// Spins the loop until a notification is received from |prefs| that the value
+// of |pref_name| has changed. If the notification is received before Wait()
+// has been called, Wait() returns immediately and no loop is spun.
+class PrefChangeWatcher {
+ public:
+  PrefChangeWatcher(const char* pref_name, PrefService* prefs);
+
+  void Wait();
+
+  void OnPrefChange();
+
+ private:
+  bool pref_changed_ = false;
+
+  base::RunLoop run_loop_;
+  PrefChangeRegistrar registrar_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefChangeWatcher);
+};
+
+PrefChangeWatcher::PrefChangeWatcher(const char* pref_name,
+                                     PrefService* prefs) {
+  registrar_.Init(prefs);
+  registrar_.Add(pref_name,
+                 base::BindRepeating(&PrefChangeWatcher::OnPrefChange,
+                                     base::Unretained(this)));
+}
+
+void PrefChangeWatcher::Wait() {
+  if (!pref_changed_)
+    run_loop_.Run();
+}
+
+void PrefChangeWatcher::OnPrefChange() {
+  pref_changed_ = true;
+  run_loop_.Quit();
+}
+
+}  // namespace
+class DeviceLoginScreenPolicyBrowsertest : public DevicePolicyCrosBrowserTest {
+ protected:
+  DeviceLoginScreenPolicyBrowsertest();
+  ~DeviceLoginScreenPolicyBrowsertest() override;
+
+  // DevicePolicyCrosBrowserTest:
+  void SetUpOnMainThread() override;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override;
+
+  void RefreshDevicePolicyAndWaitForPrefChange(const char* pref_name);
+
+  bool IsPrefManaged(const char* pref_name) const;
+
+  base::Value GetPrefValue(const char* pref_name) const;
+
+  Profile* login_profile_ = nullptr;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DeviceLoginScreenPolicyBrowsertest);
+};
+
+DeviceLoginScreenPolicyBrowsertest::DeviceLoginScreenPolicyBrowsertest() {}
+
+DeviceLoginScreenPolicyBrowsertest::~DeviceLoginScreenPolicyBrowsertest() {}
+
+void DeviceLoginScreenPolicyBrowsertest::SetUpOnMainThread() {
+  DevicePolicyCrosBrowserTest::SetUpOnMainThread();
+  login_profile_ = chromeos::ProfileHelper::GetSigninProfile();
+  ASSERT_TRUE(login_profile_);
+  // Set the login screen profile.
+  chromeos::AccessibilityManager* accessibility_manager =
+      chromeos::AccessibilityManager::Get();
+  ASSERT_TRUE(accessibility_manager);
+  accessibility_manager->SetProfileForTest(
+      chromeos::ProfileHelper::GetSigninProfile());
+
+  chromeos::MagnificationManager* magnification_manager =
+      chromeos::MagnificationManager::Get();
+  ASSERT_TRUE(magnification_manager);
+  magnification_manager->SetProfileForTest(
+      chromeos::ProfileHelper::GetSigninProfile());
+}
+
+void DeviceLoginScreenPolicyBrowsertest::
+    RefreshDevicePolicyAndWaitForPrefChange(const char* pref_name) {
+  PrefChangeWatcher watcher(pref_name, login_profile_->GetPrefs());
+  RefreshDevicePolicy();
+  watcher.Wait();
+}
+
+void DeviceLoginScreenPolicyBrowsertest::SetUpCommandLine(
+    base::CommandLine* command_line) {
+  DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line);
+  command_line->AppendSwitch(chromeos::switches::kLoginManager);
+  command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
+}
+
+bool DeviceLoginScreenPolicyBrowsertest::IsPrefManaged(
+    const char* pref_name) const {
+  const PrefService::Preference* pref =
+      login_profile_->GetPrefs()->FindPreference(pref_name);
+  return pref && pref->IsManaged();
+}
+
+base::Value DeviceLoginScreenPolicyBrowsertest::GetPrefValue(
+    const char* pref_name) const {
+  const PrefService::Preference* pref =
+      login_profile_->GetPrefs()->FindPreference(pref_name);
+  if (pref)
+    return pref->GetValue()->Clone();
+  else
+    return base::Value();
+}
+
+IN_PROC_BROWSER_TEST_F(DeviceLoginScreenPolicyBrowsertest,
+                       DeviceLoginScreenPrimaryMouseButtonSwitch) {
+  // Verifies that the state of the primary mouse button on the login screen can
+  // be controlled through device policy.
+  PrefService* prefs = login_profile_->GetPrefs();
+  ASSERT_TRUE(prefs);
+
+  // Manually switch the primary mouse button to right button.
+  prefs->SetBoolean(prefs::kPrimaryMouseButtonRight, true);
+  EXPECT_EQ(base::Value(true), GetPrefValue(prefs::kPrimaryMouseButtonRight));
+
+  // Switch the primary mouse button to left button through device policy,
+  // and wait for the change to take effect.
+  em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+  proto.mutable_login_screen_primary_mouse_button_switch()->set_value(false);
+  RefreshDevicePolicyAndWaitForPrefChange(prefs::kPrimaryMouseButtonRight);
+
+  // Verify that the pref which controls the primary mouse button state in the
+  // login profile is managed by the policy.
+  EXPECT_TRUE(IsPrefManaged(prefs::kPrimaryMouseButtonRight));
+  EXPECT_EQ(base::Value(false), GetPrefValue(prefs::kPrimaryMouseButtonRight));
+
+  // Verify that the state of primary mouse button cannot be changed manually
+  // anymore.
+  prefs->SetBoolean(prefs::kPrimaryMouseButtonRight, true);
+  EXPECT_EQ(base::Value(false), GetPrefValue(prefs::kPrimaryMouseButtonRight));
+
+  // Switch the primary mouse button to right button through device policy
+  // as a recommended value, and wait for the change to take effect.
+  proto.mutable_login_screen_primary_mouse_button_switch()->set_value(true);
+  proto.mutable_login_screen_primary_mouse_button_switch()
+      ->mutable_policy_options()
+      ->set_mode(em::PolicyOptions::RECOMMENDED);
+  RefreshDevicePolicyAndWaitForPrefChange(prefs::kPrimaryMouseButtonRight);
+
+  // Verify that the pref which controls the primary mouse button state in the
+  // login profile is being applied as recommended by the policy.
+  EXPECT_FALSE(IsPrefManaged(prefs::kPrimaryMouseButtonRight));
+  EXPECT_EQ(base::Value(true), GetPrefValue(prefs::kPrimaryMouseButtonRight));
+
+  // Verify that the state of primary mouse button can be enabled manually
+  // again.
+  prefs->SetBoolean(prefs::kPrimaryMouseButtonRight, false);
+  EXPECT_EQ(base::Value(false), GetPrefValue(prefs::kPrimaryMouseButtonRight));
+}
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index cb4414e1..888312c 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -165,6 +165,21 @@
     }
   }
 
+  if (policy.has_login_screen_primary_mouse_button_switch()) {
+    const em::BooleanPolicyProto& container(
+        policy.login_screen_primary_mouse_button_switch());
+    if (container.has_value()) {
+      PolicyLevel level;
+      if (GetPolicyLevel(container.has_policy_options(),
+                         container.policy_options(), &level)) {
+        policies->Set(key::kDeviceLoginScreenPrimaryMouseButtonSwitch, level,
+                      POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
+                      std::make_unique<base::Value>(container.value()),
+                      nullptr);
+      }
+    }
+  }
+
   if (policy.has_reboot_on_shutdown()) {
     const em::RebootOnShutdownProto& container(policy.reboot_on_shutdown());
     if (container.has_reboot_on_shutdown()) {
diff --git a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
index e68f17e..202b0250 100644
--- a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
+++ b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
@@ -57,6 +57,8 @@
     {key::kDeviceLoginScreenScreenMagnifierType, key::kScreenMagnifierType},
     {key::kDeviceLoginScreenShowOptionsInSystemTrayMenu,
      key::kShowAccessibilityOptionsInSystemTrayMenu},
+    {key::kDeviceLoginScreenPrimaryMouseButtonSwitch,
+     key::kPrimaryMouseButtonSwitch},
 };
 
 const DevicePolicyToUserPolicyMapEntry kRecommendedDevicePoliciesMap[] = {
diff --git a/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.cc b/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.cc
index fadae8b1..415e1ea7 100644
--- a/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.cc
+++ b/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.cc
@@ -15,6 +15,7 @@
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/pref_names.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/model/model_type_controller_delegate.h"
 #include "components/sync/model_impl/client_tag_based_model_type_processor.h"
 #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
 #include "components/sync/model_impl/syncable_service_based_bridge.h"
@@ -23,40 +24,19 @@
 using syncer::ForwardingModelTypeControllerDelegate;
 using syncer::SyncableServiceBasedBridge;
 
-// static
-std::unique_ptr<OsSyncableServiceModelTypeController>
-OsSyncableServiceModelTypeController::Create(
+OsSyncableServiceModelTypeController::OsSyncableServiceModelTypeController(
     syncer::ModelType type,
     syncer::OnceModelTypeStoreFactory store_factory,
     base::WeakPtr<syncer::SyncableService> syncable_service,
     const base::RepeatingClosure& dump_stack,
     PrefService* pref_service,
-    syncer::SyncService* sync_service) {
-  // The bridge must be created first so that it can be used to construct the
-  // delegates passed to the superclass constructor.
-  auto bridge = std::make_unique<SyncableServiceBasedBridge>(
-      type, std::move(store_factory),
-      std::make_unique<ClientTagBasedModelTypeProcessor>(type, dump_stack),
-      syncable_service.get());
-  // Calls new because the constructor is private.
-  return base::WrapUnique(new OsSyncableServiceModelTypeController(
-      type, std::move(bridge), pref_service, sync_service));
-}
-
-OsSyncableServiceModelTypeController::OsSyncableServiceModelTypeController(
-    syncer::ModelType type,
-    std::unique_ptr<syncer::ModelTypeSyncBridge> bridge,
-    PrefService* pref_service,
     syncer::SyncService* sync_service)
-    : ModelTypeController(
+    : ModelTypeController(type),
+      bridge_(std::make_unique<SyncableServiceBasedBridge>(
           type,
-          /*delegate_for_full_sync_mode=*/
-          std::make_unique<ForwardingModelTypeControllerDelegate>(
-              bridge->change_processor()->GetControllerDelegate().get()),
-          /*delegate_for_transport_mode=*/
-          std::make_unique<ForwardingModelTypeControllerDelegate>(
-              bridge->change_processor()->GetControllerDelegate().get())),
-      bridge_(std::move(bridge)),
+          std::move(store_factory),
+          std::make_unique<ClientTagBasedModelTypeProcessor>(type, dump_stack),
+          syncable_service.get())),
       pref_service_(pref_service),
       sync_service_(sync_service) {
   DCHECK(chromeos::features::IsSplitSettingsSyncEnabled());
@@ -64,6 +44,14 @@
          type == syncer::OS_PRIORITY_PREFERENCES);
   DCHECK(pref_service_);
   DCHECK(sync_service_);
+  syncer::ModelTypeControllerDelegate* delegate =
+      bridge_->change_processor()->GetControllerDelegate().get();
+  // Runs in transport-mode and full-sync mode, sharing the bridge's delegate.
+  InitModelTypeController(
+      /*delegate_for_full_sync_mode=*/
+      std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
+      /*delegate_for_transport_mode=*/
+      std::make_unique<ForwardingModelTypeControllerDelegate>(delegate));
 
   pref_registrar_.Init(pref_service_);
   pref_registrar_.Add(
diff --git a/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.h b/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.h
index e7509e7..cb9e569 100644
--- a/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.h
+++ b/chrome/browser/chromeos/sync/os_syncable_service_model_type_controller.h
@@ -29,7 +29,7 @@
 class OsSyncableServiceModelTypeController
     : public syncer::ModelTypeController {
  public:
-  static std::unique_ptr<OsSyncableServiceModelTypeController> Create(
+  OsSyncableServiceModelTypeController(
       syncer::ModelType type,
       syncer::OnceModelTypeStoreFactory store_factory,
       base::WeakPtr<syncer::SyncableService> syncable_service,
@@ -48,13 +48,6 @@
   PreconditionState GetPreconditionState() const override;
 
  private:
-  // See implementation comment in Create().
-  OsSyncableServiceModelTypeController(
-      syncer::ModelType type,
-      std::unique_ptr<syncer::ModelTypeSyncBridge> bridge,
-      PrefService* pref_service,
-      syncer::SyncService* sync_service);
-
   // Callback for changes to the OS sync feature enabled pref.
   void OnUserPrefChanged();
 
diff --git a/chrome/browser/devtools/devtools_eye_dropper.cc b/chrome/browser/devtools/devtools_eye_dropper.cc
index 9c37d65..f3fb379 100644
--- a/chrome/browser/devtools/devtools_eye_dropper.cc
+++ b/chrome/browser/devtools/devtools_eye_dropper.cc
@@ -115,8 +115,8 @@
 }
 
 bool DevToolsEyeDropper::HandleMouseEvent(const blink::WebMouseEvent& event) {
-  last_cursor_x_ = event.PositionInWidget().x;
-  last_cursor_y_ = event.PositionInWidget().y;
+  last_cursor_x_ = event.PositionInWidget().x();
+  last_cursor_y_ = event.PositionInWidget().y();
   if (frame_.drawsNothing())
     return true;
 
diff --git a/chrome/browser/download/android/download_controller.cc b/chrome/browser/download/android/download_controller.cc
index 5db8a61..7f8cdc9 100644
--- a/chrome/browser/download/android/download_controller.cc
+++ b/chrome/browser/download/android/download_controller.cc
@@ -230,6 +230,18 @@
 }
 
 // static
+void DownloadController::CloseTabIfEmpty(content::WebContents* web_contents) {
+  if (!web_contents)
+    return;
+
+  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
+  if (tab && !tab->GetJavaObject().is_null()) {
+    JNIEnv* env = base::android::AttachCurrentThread();
+    Java_DownloadController_closeTabIfBlank(env, tab->GetJavaObject());
+  }
+}
+
+// static
 DownloadController* DownloadController::GetInstance() {
   return base::Singleton<DownloadController>::get();
 }
@@ -341,11 +353,7 @@
       env, jurl, juser_agent, jfile_name, jmime_type, jcookie, jreferer);
 
   WebContents* web_contents = wc_getter.Run();
-  if (web_contents) {
-    TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
-    if (tab && !tab->GetJavaObject().is_null())
-      Java_DownloadController_closeTabIfBlank(env, tab->GetJavaObject());
-  }
+  CloseTabIfEmpty(web_contents);
 }
 
 bool DownloadController::HasFileAccessPermission() {
@@ -362,15 +370,6 @@
   if (!download_item->IsDangerous())
     Java_DownloadController_onDownloadStarted(env);
 
-  WebContents* web_contents =
-      content::DownloadItemUtils::GetWebContents(download_item);
-  if (web_contents) {
-    TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
-    if (tab && !tab->GetJavaObject().is_null()) {
-      Java_DownloadController_closeTabIfBlank(env, tab->GetJavaObject());
-    }
-  }
-
   // Register for updates to the DownloadItem.
   download_item->RemoveObserver(this);
   download_item->AddObserver(this);
diff --git a/chrome/browser/download/android/download_controller.h b/chrome/browser/download/android/download_controller.h
index 65abb4bf..17d81ec 100644
--- a/chrome/browser/download/android/download_controller.h
+++ b/chrome/browser/download/android/download_controller.h
@@ -52,6 +52,8 @@
   };
   static void RecordStoragePermission(StoragePermissionType type);
 
+  static void CloseTabIfEmpty(content::WebContents* web_contents);
+
   // Callback when user permission prompt finishes. Args: whether file access
   // permission is acquired, which permission to update.
   using AcquirePermissionCallback =
diff --git a/chrome/browser/download/default_download_dir_policy_handler.cc b/chrome/browser/download/default_download_dir_policy_handler.cc
index bfc63e2..d825583da 100644
--- a/chrome/browser/download/default_download_dir_policy_handler.cc
+++ b/chrome/browser/download/default_download_dir_policy_handler.cc
@@ -43,6 +43,9 @@
                     base::Value(expanded_value));
     prefs->SetValue(prefs::kSaveFileDefaultDirectory,
                     base::Value(expanded_value));
+    // Prevents a download path set by policy from being reset because it is
+    // dangerous.
+    prefs->SetBoolean(prefs::kDownloadDirUpgraded, true);
   }
 }
 
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc
index 7f770f0..c38565cd 100644
--- a/chrome/browser/download/download_ui_controller.cc
+++ b/chrome/browser/download/download_ui_controller.cc
@@ -20,6 +20,7 @@
 #include "content/public/browser/web_contents_delegate.h"
 
 #if defined(OS_ANDROID)
+#include "chrome/browser/download/android/download_controller.h"
 #include "chrome/browser/download/android/download_controller_base.h"
 #else
 #include "chrome/browser/profiles/profile.h"
@@ -182,10 +183,12 @@
       item->GetState() != download::DownloadItem::CANCELLED)
     return;
 
-#if !defined(OS_ANDROID)
   content::WebContents* web_contents =
       content::DownloadItemUtils::GetWebContents(item);
   if (web_contents) {
+#if defined(OS_ANDROID)
+    DownloadController::CloseTabIfEmpty(web_contents);
+#else
     Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
     // If the download occurs in a new tab, and it's not a save page
     // download (started before initial navigation completed) close it.
@@ -199,8 +202,8 @@
         !item->IsSavePackageDownload()) {
       web_contents->Close();
     }
+#endif  // defined(OS_ANDROID)
   }
-#endif
 
   if (item->GetState() == download::DownloadItem::CANCELLED)
     return;
diff --git a/chrome/browser/enterprise_reporting/android_app_info_generator.cc b/chrome/browser/enterprise_reporting/android_app_info_generator.cc
new file mode 100644
index 0000000..4aff3a2
--- /dev/null
+++ b/chrome/browser/enterprise_reporting/android_app_info_generator.cc
@@ -0,0 +1,96 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise_reporting/android_app_info_generator.h"
+
+#include <map>
+#include <sstream>
+
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
+#include "components/arc/mojom/app_permissions.mojom.h"
+#include "components/policy/proto/device_management_backend.pb.h"
+
+namespace em = enterprise_management;
+
+namespace {
+
+void ExtractPackagePermissions(
+    const base::flat_map<arc::mojom::AppPermission,
+                         arc::mojom::PermissionStatePtr>& permissions,
+    em::AndroidAppInfo* app_info) {
+  for (auto it = permissions.begin(); it != permissions.end(); it++) {
+    std::stringstream stream;
+    stream << it->first;
+
+    em::AndroidAppPermission* app_permission = app_info->add_permissions();
+    app_permission->set_name(stream.str());
+    app_permission->set_granted(it->second->granted);
+    app_permission->set_managed(it->second->managed);
+  }
+}
+
+em::AndroidAppInfo::AndroidAppStatus ExtractAppStatus(
+    const ArcAppListPrefs::AppInfo& app) {
+  if (app.suspended)
+    return em::AndroidAppInfo::STATUS_SUSPENDED;
+  else if (app.ready)
+    return em::AndroidAppInfo::STATUS_ENABLED;
+  else
+    return em::AndroidAppInfo::STATUS_DISABLED;
+}
+
+em::AndroidAppInfo::InstalledSource ExtractInstalledSource(
+    const ArcAppListPrefs& prefs,
+    const ArcAppListPrefs::AppInfo& app) {
+  if (!app.ready)
+    return em::AndroidAppInfo::SOURCE_NOT_INSTALLED;
+
+  if (prefs.IsControlledByPolicy(app.package_name))
+    return em::AndroidAppInfo::SOURCE_BY_ADMIN;
+  else
+    return em::AndroidAppInfo::SOURCE_BY_USER;
+}
+
+}  // namespace
+
+namespace enterprise_reporting {
+
+std::unique_ptr<em::AndroidAppInfo> AndroidAppInfoGenerator::Generate(
+    ArcAppListPrefs* prefs,
+    const std::string& app_id) const {
+  // An AppInfo instance will always be generated.
+  auto info = std::make_unique<em::AndroidAppInfo>();
+
+  // Collect application information if possible.
+  std::unique_ptr<ArcAppListPrefs::AppInfo> app = prefs->GetApp(app_id);
+
+  if (app) {
+    info->set_app_id(prefs->GetAppIdByPackageName(app->package_name));
+    info->set_app_name(app->name);
+    info->set_package_name(app->package_name);
+    info->set_status(ExtractAppStatus(*app));
+    info->set_installed_source(ExtractInstalledSource(*prefs, *app));
+
+    // Collect package information if possible.
+    std::unique_ptr<ArcAppListPrefs::PackageInfo> package =
+        prefs->GetPackage(app->package_name);
+
+    if (package) {
+      info->set_version(package->package_version);
+      ExtractPackagePermissions(package->permissions, info.get());
+    } else {
+      LOG(ERROR) << base::StringPrintf(
+          "Package (package name: %s) can not be found.",
+          app->package_name.c_str());
+    }
+  } else {
+    LOG(ERROR) << base::StringPrintf("App (app id: %s) can not be found.",
+                                     app_id.c_str());
+  }
+
+  return info;
+}
+
+}  // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise_reporting/android_app_info_generator.h b/chrome/browser/enterprise_reporting/android_app_info_generator.h
new file mode 100644
index 0000000..585fd68e
--- /dev/null
+++ b/chrome/browser/enterprise_reporting/android_app_info_generator.h
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_REPORTING_ANDROID_APP_INFO_GENERATOR_H_
+#define CHROME_BROWSER_ENTERPRISE_REPORTING_ANDROID_APP_INFO_GENERATOR_H_
+
+#include <memory>
+#include <string>
+
+class ArcAppListPrefs;
+
+namespace enterprise_management {
+class AndroidAppInfo;
+}  // namespace enterprise_management
+
+namespace enterprise_reporting {
+
+// A class that is responsible for collecting Android application information
+// with given |app_id|.
+class AndroidAppInfoGenerator {
+ public:
+  AndroidAppInfoGenerator() = default;
+  AndroidAppInfoGenerator(const AndroidAppInfoGenerator&) = delete;
+  AndroidAppInfoGenerator& operator=(const AndroidAppInfoGenerator&) = delete;
+  ~AndroidAppInfoGenerator() = default;
+
+  std::unique_ptr<enterprise_management::AndroidAppInfo> Generate(
+      ArcAppListPrefs* prefs,
+      const std::string& app_id) const;
+};
+
+}  // namespace enterprise_reporting
+
+#endif  // CHROME_BROWSER_ENTERPRISE_REPORTING_ANDROID_APP_INFO_GENERATOR_H_
diff --git a/chrome/browser/enterprise_reporting/android_app_info_generator_unittest.cc b/chrome/browser/enterprise_reporting/android_app_info_generator_unittest.cc
new file mode 100644
index 0000000..6146c6a
--- /dev/null
+++ b/chrome/browser/enterprise_reporting/android_app_info_generator_unittest.cc
@@ -0,0 +1,192 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise_reporting/android_app_info_generator.h"
+
+#include <memory>
+
+#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/arc/test/fake_app_instance.h"
+#include "content/public/test/browser_task_environment.h"
+#include "device_management_backend.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace am = arc::mojom;
+namespace em = enterprise_management;
+
+namespace enterprise_reporting {
+
+namespace {
+constexpr char kAppName[] = "app_name";
+constexpr char kPackageName[] = "package_name";
+constexpr char kActivityName[] = "activity_name";
+constexpr int kPackageVersion = 9;
+
+am::AppInfo CreateArcApp(bool suspended) {
+  am::AppInfo app;
+  app.name = kAppName;
+  app.package_name = kPackageName;
+  app.activity = kActivityName;
+  app.suspended = suspended;
+  app.sticky = true;
+  app.notifications_enabled = true;
+  return app;
+}
+
+am::ArcPackageInfoPtr CreateArcPackage(const std::string& package_name,
+                                       int package_version) {
+  base::flat_map<am::AppPermission, am::PermissionStatePtr> permissions;
+
+  permissions.emplace(
+      am::AppPermission::CAMERA,
+      am::PermissionState::New(false /* granted */, false /* managed */));
+  permissions.emplace(
+      am::AppPermission::LOCATION,
+      am::PermissionState::New(true /* granted */, true /* managed */));
+
+  return am::ArcPackageInfo::New(
+      package_name, package_version, 1 /* last_backup_android_id */,
+      1 /* last_backup_time */, true /* sync */, false /* system */,
+      false /* vpn_provider */, nullptr /* web_app_info */, base::nullopt,
+      std::move(permissions) /* permission states */);
+}
+
+}  // namespace
+
+class AndroidAppInfoGeneratorTest : public ::testing::Test {
+ public:
+  AndroidAppInfoGeneratorTest() = default;
+  AndroidAppInfoGeneratorTest(const AndroidAppInfoGeneratorTest&) = delete;
+  AndroidAppInfoGeneratorTest& operator=(const AndroidAppInfoGeneratorTest&) =
+      delete;
+  ~AndroidAppInfoGeneratorTest() override = default;
+
+  void SetUp() override {
+    testing::Test::SetUp();
+    arc_app_test_.SetUp(&profile_);
+  }
+
+  void TearDown() override {
+    arc_app_test_.TearDown();
+    testing::Test::TearDown();
+  }
+
+  void AddArcApp(am::AppInfo arc_app) {
+    arc_app_test()->app_instance()->SendRefreshAppList({arc_app});
+  }
+
+  void AddArcPackage(am::ArcPackageInfoPtr arc_package_ptr) {
+    arc_app_test()->app_instance()->SendPackageAdded(
+        std::move(arc_package_ptr));
+  }
+
+  AndroidAppInfoGenerator* app_info_generator() { return &app_info_generator_; }
+  ArcAppTest* arc_app_test() { return &arc_app_test_; }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
+  AndroidAppInfoGenerator app_info_generator_;
+  ArcAppTest arc_app_test_;
+};
+
+TEST_F(AndroidAppInfoGeneratorTest, GenerateAppInfo) {
+  ArcAppListPrefs* prefs = arc_app_test()->arc_app_list_prefs();
+  AddArcPackage(CreateArcPackage(kPackageName, kPackageVersion));
+  AddArcApp(CreateArcApp(false /* suspended */));
+
+  std::string app_id = prefs->GetAppId(kPackageName, kActivityName);
+  std::unique_ptr<em::AndroidAppInfo> app_info =
+      app_info_generator()->Generate(prefs, app_id);
+
+  EXPECT_EQ(app_info->app_id(), app_id);
+  EXPECT_EQ(app_info->app_name(), kAppName);
+  EXPECT_EQ(app_info->package_name(), kPackageName);
+  EXPECT_EQ(app_info->status(), em::AndroidAppInfo::STATUS_ENABLED);
+  EXPECT_EQ(app_info->installed_source(), em::AndroidAppInfo::SOURCE_BY_USER);
+  EXPECT_EQ(app_info->version(), kPackageVersion);
+  EXPECT_EQ(app_info->permissions_size(), 2);
+
+  em::AndroidAppPermission permission0 = app_info->permissions(0);
+  EXPECT_EQ(permission0.name(), "AppPermission::CAMERA");
+  EXPECT_FALSE(permission0.granted());
+  EXPECT_FALSE(permission0.managed());
+
+  em::AndroidAppPermission permission1 = app_info->permissions(1);
+  EXPECT_EQ(permission1.name(), "AppPermission::LOCATION");
+  EXPECT_TRUE(permission1.granted());
+  EXPECT_TRUE(permission1.managed());
+}
+
+TEST_F(AndroidAppInfoGeneratorTest, GenerateAppInfoWithSuspendedStatus) {
+  ArcAppListPrefs* prefs = arc_app_test()->arc_app_list_prefs();
+  AddArcPackage(CreateArcPackage(kPackageName, kPackageVersion));
+  AddArcApp(CreateArcApp(true /* suspended */));
+
+  std::string app_id = prefs->GetAppId(kPackageName, kActivityName);
+  std::unique_ptr<em::AndroidAppInfo> app_info =
+      app_info_generator()->Generate(prefs, app_id);
+
+  EXPECT_EQ(app_info->status(), em::AndroidAppInfo::STATUS_SUSPENDED);
+}
+
+TEST_F(AndroidAppInfoGeneratorTest, GenerateAppInfoInstalledByAdmin) {
+  ArcAppListPrefs* prefs = arc_app_test()->arc_app_list_prefs();
+  AddArcPackage(CreateArcPackage(kPackageName, kPackageVersion));
+  AddArcApp(CreateArcApp(false /* suspended */));
+
+  // Set policy to install the package enforcedly.
+  const std::string policy = base::StringPrintf(
+      "{\"applications\":[{\"installType\":\"FORCE_INSTALLED\","
+      "\"packageName\":\"%s\"}]}",
+      kPackageName);
+  prefs->OnPolicySent(policy);
+
+  std::string app_id = prefs->GetAppId(kPackageName, kActivityName);
+  std::unique_ptr<em::AndroidAppInfo> app_info =
+      app_info_generator()->Generate(prefs, app_id);
+
+  EXPECT_EQ(app_info->installed_source(), em::AndroidAppInfo::SOURCE_BY_ADMIN);
+}
+
+TEST_F(AndroidAppInfoGeneratorTest, GenerateAppInfoWithoutPackage) {
+  ArcAppListPrefs* prefs = arc_app_test()->arc_app_list_prefs();
+  AddArcApp(CreateArcApp(false /* suspended */));
+
+  std::string app_id = prefs->GetAppId(kPackageName, kActivityName);
+  std::unique_ptr<em::AndroidAppInfo> app_info =
+      app_info_generator()->Generate(prefs, app_id);
+
+  EXPECT_EQ(app_info->app_id(), app_id);
+  EXPECT_EQ(app_info->app_name(), kAppName);
+  EXPECT_EQ(app_info->package_name(), kPackageName);
+  EXPECT_EQ(app_info->status(), em::AndroidAppInfo::STATUS_ENABLED);
+  EXPECT_EQ(app_info->installed_source(), em::AndroidAppInfo::SOURCE_BY_USER);
+
+  // Following fields are empty because package is not found.
+  EXPECT_FALSE(app_info->has_version());
+  EXPECT_EQ(app_info->permissions_size(), 0);
+}
+
+TEST_F(AndroidAppInfoGeneratorTest, GenerateAppInfoWithInvalidAppId) {
+  ArcAppListPrefs* prefs = arc_app_test()->arc_app_list_prefs();
+  std::string app_id = "invalid_app_id";
+  std::unique_ptr<em::AndroidAppInfo> app_info =
+      app_info_generator()->Generate(prefs, app_id);
+
+  // Following fields are empty because application and corresponding package
+  // are not found.
+  EXPECT_FALSE(app_info->has_app_id());
+  EXPECT_FALSE(app_info->has_app_name());
+  EXPECT_FALSE(app_info->has_package_name());
+  EXPECT_FALSE(app_info->has_status());
+  EXPECT_FALSE(app_info->has_installed_source());
+  EXPECT_FALSE(app_info->has_version());
+  EXPECT_EQ(app_info->permissions_size(), 0);
+}
+
+}  // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc b/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
index 906bc9ff..422233b 100644
--- a/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
+++ b/chrome/browser/enterprise_reporting/profile_report_generator_unittest.cc
@@ -14,6 +14,8 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/account_id/account_id.h"
+#include "components/policy/core/common/mock_policy_service.h"
+#include "components/policy/core/common/policy_map.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -36,10 +38,33 @@
 
   void SetUp() override {
     ASSERT_TRUE(profile_manager_.SetUp());
+    InitMockPolicyService();
+    InitPolicyMap();
+
     profile_ = profile_manager_.CreateTestingProfile(
         kProfile, {}, base::UTF8ToUTF16(kProfile), 0, {},
         IdentityTestEnvironmentProfileAdaptor::
-            GetIdentityTestEnvironmentFactories());
+            GetIdentityTestEnvironmentFactories(),
+        base::nullopt, std::move(policy_service_));
+  }
+
+  void InitMockPolicyService() {
+    policy_service_ = std::make_unique<policy::MockPolicyService>();
+
+    ON_CALL(*policy_service_.get(),
+            GetPolicies(::testing::Eq(policy::PolicyNamespace(
+                policy::POLICY_DOMAIN_CHROME, std::string()))))
+        .WillByDefault(::testing::ReturnRef(policy_map_));
+  }
+
+  void InitPolicyMap() {
+    policy_map_.Set("kPolicyName1", policy::POLICY_LEVEL_MANDATORY,
+                    policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+                    std::make_unique<base::Value>(std::vector<base::Value>()),
+                    nullptr);
+    policy_map_.Set("kPolicyName2", policy::POLICY_LEVEL_RECOMMENDED,
+                    policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_MERGED,
+                    std::make_unique<base::Value>(true), nullptr);
   }
 
   std::unique_ptr<em::ChromeUserProfileInfo> GenerateReport(
@@ -85,6 +110,9 @@
   TestingProfileManager profile_manager_;
   TestingProfile* profile_;
 
+  std::unique_ptr<policy::MockPolicyService> policy_service_;
+  policy::PolicyMap policy_map_;
+
   DISALLOW_COPY_AND_ASSIGN(ProfileReportGeneratorTest);
 };
 
@@ -116,6 +144,23 @@
             report->chrome_signed_in_user().obfudscated_gaia_id());
 }
 
+TEST_F(ProfileReportGeneratorTest, PoliciesDisabled) {
+  // Users' profile info is collected by default.
+  std::unique_ptr<em::ChromeUserProfileInfo> report = GenerateReport();
+  EXPECT_EQ(2, report->chrome_policies_size());
+
+  // Stop to collect profile info after |set_policies_enabled| is set as false.
+  generator_.set_policies_enabled(false);
+  report = GenerateReport();
+  EXPECT_EQ(0, report->chrome_policies_size());
+
+  // Start to collect profile info again after |set_policies_enabled| is set as
+  // true.
+  generator_.set_policies_enabled(true);
+  report = GenerateReport();
+  EXPECT_EQ(2, report->chrome_policies_size());
+}
+
 TEST_F(ProfileReportGeneratorTest, PendingRequest) {
   generator_.set_extension_request_enabled(true);
   std::vector<std::string> ids = {kExtensionId};
diff --git a/chrome/browser/enterprise_reporting/report_generator.cc b/chrome/browser/enterprise_reporting/report_generator.cc
index 9244c08..0190a099 100644
--- a/chrome/browser/enterprise_reporting/report_generator.cc
+++ b/chrome/browser/enterprise_reporting/report_generator.cc
@@ -8,14 +8,23 @@
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "components/policy/core/common/cloud/cloud_policy_util.h"
 
 #if defined(OS_WIN)
 #include "base/win/wmi.h"
 #endif
 
+#if defined(CHROMEOS)
+#include "chrome/browser/enterprise_reporting/android_app_info_generator.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
+#endif
+
 namespace em = enterprise_management;
 
 namespace enterprise_reporting {
@@ -35,7 +44,9 @@
 }
 
 void ReportGenerator::CreateBasicRequest() {
-#if !defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS)
+  AppendAndroidAppInfos();
+#else
   basic_request_.set_computer_name(this->GetMachineName());
   basic_request_.set_os_user_name(GetOSUserName());
   basic_request_.set_serial_number(GetSerialNumber());
@@ -71,6 +82,35 @@
 #endif
 }
 
+#if defined(OS_CHROMEOS)
+
+void ReportGenerator::AppendAndroidAppInfos() {
+  // Android application is only supported for primary profile.
+  Profile* primary_profile =
+      g_browser_process->profile_manager()->GetPrimaryUserProfile();
+
+  if (!arc::IsArcPlayStoreEnabledForProfile(primary_profile))
+    return;
+
+  ArcAppListPrefs* prefs = ArcAppListPrefs::Get(primary_profile);
+
+  if (!prefs) {
+    LOG(ERROR) << base::StringPrintf(
+        "Failed to generate ArcAppListPrefs instance for primary user profile "
+        "(debug name: %s).",
+        primary_profile->GetDebugName().c_str());
+    return;
+  }
+
+  AndroidAppInfoGenerator generator;
+  for (std::string app_id : prefs->GetAppIds()) {
+    em::AndroidAppInfo* app_info = basic_request_.add_android_app_infos();
+    generator.Generate(prefs, app_id)->Swap(app_info);
+  }
+}
+
+#endif
+
 void ReportGenerator::OnBrowserReportReady(
     std::unique_ptr<em::BrowserReport> browser_report) {
   basic_request_.set_allocated_browser_report(browser_report.release());
diff --git a/chrome/browser/enterprise_reporting/report_generator.h b/chrome/browser/enterprise_reporting/report_generator.h
index 7f8533d..f681707 100644
--- a/chrome/browser/enterprise_reporting/report_generator.h
+++ b/chrome/browser/enterprise_reporting/report_generator.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "chrome/browser/enterprise_reporting/browser_report_generator.h"
 #include "chrome/browser/enterprise_reporting/report_request_definition.h"
 #include "chrome/browser/enterprise_reporting/report_request_queue_generator.h"
@@ -51,6 +52,12 @@
   // on other platforms.
   virtual std::string GetSerialNumber();
 
+#if defined(OS_CHROMEOS)
+  // Collect the Android application information installed on primary profile,
+  // and append it to |basic_request_|.
+  virtual void AppendAndroidAppInfos();
+#endif
+
  private:
   void OnBrowserReportReady(std::unique_ptr<em::BrowserReport> browser_report);
 
diff --git a/chrome/browser/enterprise_reporting/report_generator_unittest.cc b/chrome/browser/enterprise_reporting/report_generator_unittest.cc
index 7e27426..7ab2cf1 100644
--- a/chrome/browser/enterprise_reporting/report_generator_unittest.cc
+++ b/chrome/browser/enterprise_reporting/report_generator_unittest.cc
@@ -25,6 +25,13 @@
 #include "extensions/common/extension_builder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
+#include "components/arc/arc_prefs.h"
+#include "components/arc/test/fake_app_instance.h"
+#endif
+
 namespace em = enterprise_management;
 
 namespace enterprise_reporting {
@@ -37,6 +44,15 @@
 const char kPluginDescription[] = "This is a plugin.";
 const char kPluginFileName[] = "file_name";
 
+#if defined(OS_CHROMEOS)
+const char kArcAppName1[] = "app_name1";
+const char kArcPackageName1[] = "package_name1";
+const char kArcActivityName1[] = "activity_name1";
+const char kArcAppName2[] = "app_name2";
+const char kArcPackageName2[] = "package_name2";
+const char kArcActivityName2[] = "activity_name2";
+#endif
+
 #if !defined(OS_CHROMEOS)
 // We only upload serial number on Windows.
 void VerifySerialNumber(const std::string& serial_number) {
@@ -78,6 +94,41 @@
                                      .Build());
 }
 
+#if defined(OS_CHROMEOS)
+
+arc::mojom::AppInfo CreateArcApp(const std::string& app_name,
+                                 const std::string& package_name,
+                                 const std::string& activity_name) {
+  arc::mojom::AppInfo app;
+  app.name = app_name;
+  app.package_name = package_name;
+  app.activity = activity_name;
+  app.suspended = false;
+  app.sticky = true;
+  app.notifications_enabled = true;
+  return app;
+}
+
+arc::mojom::ArcPackageInfoPtr CreateArcPackage(
+    const std::string& package_name) {
+  return arc::mojom::ArcPackageInfo::New(
+      package_name, 0 /* package_version */, 0 /* last_backup_android_id */,
+      0 /* last_backup_time */, false /* sync */);
+}
+
+void AddArcPackageAndApp(ArcAppTest* arc_app_test,
+                         const std::string& app_name,
+                         const std::string& package_name,
+                         const std::string& activity_name) {
+  arc::mojom::ArcPackageInfoPtr package = CreateArcPackage(package_name);
+  arc_app_test->app_instance()->SendPackageAdded(std::move(package));
+
+  arc::mojom::AppInfo app = CreateArcApp(app_name, package_name, activity_name);
+  arc_app_test->app_instance()->SendAppAdded(app);
+}
+
+#endif
+
 }  // namespace
 
 class ReportGeneratorTest : public ::testing::Test {
@@ -256,4 +307,61 @@
                       profile_names, browser_report);
 }
 
+#if defined(OS_CHROMEOS)
+
+TEST_F(ReportGeneratorTest, ReportArcAppInChromeOS) {
+  ArcAppTest arc_app_test;
+  TestingProfile primary_profile;
+  arc_app_test.SetUp(&primary_profile);
+
+  // Create two Arc applications in primary profile.
+  AddArcPackageAndApp(&arc_app_test, kArcAppName1, kArcPackageName1,
+                      kArcActivityName1);
+  AddArcPackageAndApp(&arc_app_test, kArcAppName2, kArcPackageName2,
+                      kArcActivityName2);
+
+  EXPECT_EQ(2u, arc_app_test.arc_app_list_prefs()->GetAppIds().size());
+
+  // Verify the Arc application information in the report is same as the test
+  // data.
+  auto requests = GenerateRequests();
+  EXPECT_EQ(1u, requests.size());
+
+  ReportRequest* request = requests.front().get();
+  EXPECT_EQ(2, request->android_app_infos_size());
+  em::AndroidAppInfo app_info1 = request->android_app_infos(1);
+  EXPECT_EQ(kArcAppName1, app_info1.app_name());
+  em::AndroidAppInfo app_info2 = request->android_app_infos(0);
+  EXPECT_EQ(kArcAppName2, app_info2.app_name());
+
+  arc_app_test.TearDown();
+}
+
+TEST_F(ReportGeneratorTest, ArcPlayStoreDisabled) {
+  ArcAppTest arc_app_test;
+  TestingProfile primary_profile;
+  arc_app_test.SetUp(&primary_profile);
+
+  // Create two Arc applications in primary profile.
+  AddArcPackageAndApp(&arc_app_test, kArcAppName1, kArcPackageName1,
+                      kArcActivityName1);
+  AddArcPackageAndApp(&arc_app_test, kArcAppName2, kArcPackageName2,
+                      kArcActivityName2);
+
+  EXPECT_EQ(2u, arc_app_test.arc_app_list_prefs()->GetAppIds().size());
+
+  // No Arc application information is reported after the Arc Play Store
+  // support for given profile is disabled.
+  primary_profile.GetPrefs()->SetBoolean(arc::prefs::kArcEnabled, false);
+  auto requests = GenerateRequests();
+  EXPECT_EQ(1u, requests.size());
+
+  ReportRequest* request = requests.front().get();
+  EXPECT_EQ(0, request->android_app_infos_size());
+
+  arc_app_test.TearDown();
+}
+
+#endif
+
 }  // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise_reporting/report_request_queue_generator.cc b/chrome/browser/enterprise_reporting/report_request_queue_generator.cc
index 23b5ed4..0caa35c 100644
--- a/chrome/browser/enterprise_reporting/report_request_queue_generator.cc
+++ b/chrome/browser/enterprise_reporting/report_request_queue_generator.cc
@@ -34,7 +34,12 @@
 }  // namespace
 
 ReportRequestQueueGenerator::ReportRequestQueueGenerator()
-    : maximum_report_size_(kMaximumReportSize) {}
+    : maximum_report_size_(kMaximumReportSize) {
+#if defined(OS_CHROMEOS)
+  // For Chrome OS, policy information needn't be uploaded to DM server.
+  profile_report_generator_.set_policies_enabled(false);
+#endif
+}
 
 ReportRequestQueueGenerator::~ReportRequestQueueGenerator() = default;
 
diff --git a/chrome/browser/enterprise_reporting/report_request_queue_generator_unittest.cc b/chrome/browser/enterprise_reporting/report_request_queue_generator_unittest.cc
index b5a82f5..15a583c 100644
--- a/chrome/browser/enterprise_reporting/report_request_queue_generator_unittest.cc
+++ b/chrome/browser/enterprise_reporting/report_request_queue_generator_unittest.cc
@@ -17,6 +17,9 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/account_id/account_id.h"
+#include "components/policy/core/common/mock_policy_service.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/sync_preferences/pref_service_syncable.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/browser/extension_registry.h"
@@ -80,6 +83,15 @@
     return profile_manager_.CreateTestingProfile(profile_name);
   }
 
+  TestingProfile* CreateActiveProfileWithPolicies(
+      std::string profile_name,
+      std::unique_ptr<policy::PolicyService> policy_service) {
+    return profile_manager_.CreateTestingProfile(
+        profile_name, {}, base::UTF8ToUTF16(profile_name), 0, {},
+        TestingProfile::TestingFactories(), base::nullopt,
+        std::move(policy_service));
+  }
+
   void CreateActiveProfileWithContent(std::string profile_name) {
     TestingProfile* active_profile = CreateActiveProfile(profile_name);
 
@@ -273,4 +285,42 @@
                                         /*report size floor to KB*/ 0, 2);
 }
 
+TEST_F(ReportRequestQueueGeneratorTest, ChromePoliciesCollection) {
+  auto policy_service = std::make_unique<policy::MockPolicyService>();
+  policy::PolicyMap policy_map;
+
+  ON_CALL(*policy_service.get(),
+          GetPolicies(::testing::Eq(policy::PolicyNamespace(
+              policy::POLICY_DOMAIN_CHROME, std::string()))))
+      .WillByDefault(::testing::ReturnRef(policy_map));
+
+  policy_map.Set("kPolicyName1", policy::POLICY_LEVEL_MANDATORY,
+                 policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+                 std::make_unique<base::Value>(std::vector<base::Value>()),
+                 nullptr);
+  policy_map.Set("kPolicyName2", policy::POLICY_LEVEL_RECOMMENDED,
+                 policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_MERGED,
+                 std::make_unique<base::Value>(true), nullptr);
+
+  CreateActiveProfileWithPolicies(kActiveProfileName1,
+                                  std::move(policy_service));
+
+  auto basic_request = GenerateBasicRequest();
+  auto requests = GenerateRequests(*basic_request);
+  EXPECT_EQ(1u, requests.size());
+
+  auto browser_report = requests[0]->browser_report();
+  EXPECT_EQ(1, browser_report.chrome_user_profile_infos_size());
+
+  auto profile_info = browser_report.chrome_user_profile_infos(0);
+
+#if defined(OS_CHROMEOS)
+  // In Chrome OS, the collection of policies is disabled.
+  EXPECT_EQ(0, profile_info.chrome_policies_size());
+#else
+  // In desktop Chrome, the collection of policies is enabled.
+  EXPECT_EQ(2, profile_info.chrome_policies_size());
+#endif
+}
+
 }  // namespace enterprise_reporting
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index c4e7af9..e1aa079 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -840,6 +840,7 @@
     "//components/safe_browsing:features",
     "//components/safe_browsing/common:safe_browsing_prefs",
     "//components/safe_browsing/db:database_manager",
+    "//components/safe_browsing/web_ui:web_ui",
     "//components/search_engines",
     "//components/services/patch/content",
     "//components/services/unzip/content",
diff --git a/chrome/browser/extensions/api/BUILD.gn b/chrome/browser/extensions/api/BUILD.gn
index 0200a00b..82da612 100644
--- a/chrome/browser/extensions/api/BUILD.gn
+++ b/chrome/browser/extensions/api/BUILD.gn
@@ -22,6 +22,7 @@
   deps = [
     # Different APIs include headers from these targets.
     "//chrome/common:mojo_bindings",
+    "//components/zoom",
     "//content/public/browser",
     "//extensions/browser",
 
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index 6628823..7143ac4 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -419,9 +419,11 @@
     event.shift_key = key_event.shift_key ? *(key_event.shift_key) : false;
     event.caps_lock = key_event.caps_lock ? *(key_event.caps_lock) : false;
   }
-  if (!engine->SendKeyEvents(params.context_id, key_data_out))
-    return RespondNow(
-        Error(InformativeError(kErrorSetKeyEventsFail, function_name())));
+
+  if (!engine->SendKeyEvents(params.context_id, key_data_out, &error))
+    return RespondNow(Error(InformativeError(
+        base::StringPrintf("%s %s", kErrorSetKeyEventsFail, error.c_str()),
+        function_name())));
   return RespondNow(NoArguments());
 }
 
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
index 80104420..7b98df3 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -12,6 +12,7 @@
 #include "ash/public/cpp/keyboard/keyboard_config.h"
 #include "base/feature_list.h"
 #include "base/macros.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
 #include "chrome/browser/chromeos/input_method/native_input_method_engine.h"
 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
@@ -699,9 +700,11 @@
     SetMenuItemToMenu(item_in, &items_out.back());
   }
 
-  if (!engine->SetMenuItems(items_out))
-    return RespondNow(
-        Error(InformativeError(kErrorSetMenuItemsFail, function_name())));
+  if (!engine->SetMenuItems(items_out, &error)) {
+    return RespondNow(Error(InformativeError(
+        base::StringPrintf("%s %s", kErrorSetMenuItemsFail, error.c_str()),
+        function_name())));
+  }
   return RespondNow(NoArguments());
 }
 
@@ -724,9 +727,11 @@
     SetMenuItemToMenu(item_in, &items_out.back());
   }
 
-  if (!engine->UpdateMenuItems(items_out))
-    return RespondNow(
-        Error(InformativeError(kErrorUpdateMenuItemsFail, function_name())));
+  if (!engine->UpdateMenuItems(items_out, &error)) {
+    return RespondNow(Error(InformativeError(
+        base::StringPrintf("%s %s", kErrorUpdateMenuItemsFail, error.c_str()),
+        function_name())));
+  }
   return RespondNow(NoArguments());
 }
 
diff --git a/chrome/browser/extensions/api/resources_private/resources_private_api.cc b/chrome/browser/extensions/api/resources_private/resources_private_api.cc
index 3f4c269..f3645106 100644
--- a/chrome/browser/extensions/api/resources_private/resources_private_api.cc
+++ b/chrome/browser/extensions/api/resources_private/resources_private_api.cc
@@ -13,6 +13,7 @@
 #include "chrome/common/extensions/api/resources_private.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/zoom/page_zoom_constants.h"
 #include "pdf/buildflags.h"
 #include "printing/buildflags/buildflags.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -114,6 +115,8 @@
   };
   for (const auto& resource : kPdfResources)
     dict->SetString(resource.name, l10n_util::GetStringUTF16(resource.id));
+
+  dict->SetString("presetZoomFactors", zoom::GetPresetZoomFactorsAsJSON());
 }
 
 void AddAdditionalDataForPdf(base::DictionaryValue* dict) {
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
index ff2386af..172b282 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "components/safe_browsing/web_ui/safe_browsing_ui.h"
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -759,6 +760,10 @@
   wrapper.SetStringKey("time", now_str);
   wrapper.SetKey(name, std::move(event_builder).Run());
 
+  // Show the report on chrome://safe-browsing, if appropriate.
+  safe_browsing::WebUIInfoSingleton::GetInstance()->AddToReportingEvents(
+      wrapper);
+
   base::Value event_list(base::Value::Type::LIST);
   event_list.Append(std::move(wrapper));
 
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc
index 5117c2aa..08bcdb27 100644
--- a/chrome/browser/extensions/app_background_page_apitest.cc
+++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -25,7 +25,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
+#include "components/embedder_support/switches.h"
 #include "components/nacl/common/buildflags.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_frame_host.h"
@@ -84,7 +84,7 @@
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     extensions::ExtensionApiTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitch(switches::kDisablePopupBlocking);
+    command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
     command_line->AppendSwitch(extensions::switches::kAllowHTTPBackgroundPage);
   }
 
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index b0a3ee7c..71168e72 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/view_ids.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "components/sync/model/string_ordinal.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
@@ -63,7 +63,7 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     extensions::ExtensionApiTest::SetUpCommandLine(command_line);
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kDisablePopupBlocking);
+        embedder_support::kDisablePopupBlocking);
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         extensions::switches::kAllowHTTPBackgroundPage);
   }
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
index 0672833..d0a8e7c 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -172,8 +172,8 @@
     }
   }
 
-  if (extension->id().compare(extension_misc::kChromeCameraAppId) == 0 ||
-      extension->id().compare(extension_misc::kChromeCameraAppDevId) == 0) {
+  if (extension->id().compare(extension_misc::kCameraAppId) == 0 ||
+      extension->id().compare(extension_misc::kCameraAppDevId) == 0) {
     binder_map->Add<cros::mojom::CameraAppDeviceProvider>(
         base::BindRepeating(&ConnectToCameraAppDeviceProvider));
     binder_map->Add<chromeos_camera::mojom::CameraAppHelper>(
diff --git a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
index 5b98694..7e4d8a58 100644
--- a/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
+++ b/chrome/browser/extensions/component_extensions_whitelist/whitelist.cc
@@ -38,7 +38,7 @@
     extension_misc::kSelectToSpeakExtensionId,
     extension_misc::kSwitchAccessExtensionId,
     extension_misc::kZipArchiverExtensionId,
-    extension_misc::kChromeCameraAppId,
+    extension_misc::kCameraAppId,
 #endif
   };
 
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index a881e3b..f4472d5 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -387,9 +387,8 @@
 void ComponentLoader::AddChromeCameraApp() {
   base::FilePath resources_path;
   if (base::PathService::Get(chrome::DIR_RESOURCES, &resources_path)) {
-    AddComponentFromDir(
-        resources_path.Append(extension_misc::kChromeCameraAppPath),
-        extension_misc::kChromeCameraAppId, base::RepeatingClosure());
+    AddComponentFromDir(resources_path.Append(extension_misc::kCameraAppPath),
+                        extension_misc::kCameraAppId, base::RepeatingClosure());
   }
 }
 
diff --git a/chrome/browser/extensions/extension_bindings_apitest.cc b/chrome/browser/extensions/extension_bindings_apitest.cc
index 9b90eda1..36dadd2 100644
--- a/chrome/browser/extensions/extension_bindings_apitest.cc
+++ b/chrome/browser/extensions/extension_bindings_apitest.cc
@@ -12,8 +12,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -87,7 +87,8 @@
 
 // Tests that an error raised during an async function still fires
 // the callback, but sets chrome.runtime.lastError.
-IN_PROC_BROWSER_TEST_F(ExtensionBindingsApiTest, LastError) {
+// Flaky on all platforms: https://crbug.com/1035011
+IN_PROC_BROWSER_TEST_F(ExtensionBindingsApiTest, DISABLED_LastError) {
   ASSERT_TRUE(LoadExtension(
       test_data_dir_.AppendASCII("bindings").AppendASCII("last_error")));
 
@@ -253,7 +254,7 @@
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     ExtensionBindingsApiTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitch(::switches::kDisablePopupBlocking);
+    command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
   }
 };
 
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index 635ea56..329321e 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -37,9 +37,9 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/crx_file/id_util.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_registrar.h"
@@ -1016,7 +1016,7 @@
 
 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, FromPopup) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      ::switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
 
   scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
 
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc
index 85d4e76..d9236fec 100644
--- a/chrome/browser/extensions/external_pref_loader.cc
+++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -221,7 +221,7 @@
 void ExternalPrefLoader::StartLoading() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if ((options_ & DELAY_LOAD_UNTIL_PRIORITY_SYNC) &&
-      (profile_ && profile_->IsSyncAllowed())) {
+      (profile_ && ProfileSyncServiceFactory::IsSyncAllowed(profile_))) {
     pending_waiter_list_.push_back(
         std::make_unique<PrioritySyncReadyWaiter>(profile_));
     PrioritySyncReadyWaiter* waiter_ptr = pending_waiter_list_.back().get();
diff --git a/chrome/browser/fast_shutdown_browsertest.cc b/chrome/browser/fast_shutdown_browsertest.cc
index e9f86fe..319eb6c 100644
--- a/chrome/browser/fast_shutdown_browsertest.cc
+++ b/chrome/browser/fast_shutdown_browsertest.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/test/browser_test_utils.h"
@@ -29,7 +29,7 @@
   }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitch(switches::kDisablePopupBlocking);
+    command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
   }
 
  private:
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index d7ca9945..ae09893 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1612,11 +1612,6 @@
     "expiry_milestone": 83
   },
   {
-    "name": "enable-ntp-remote-suggestions",
-    "owners": [ "//chrome/android/feed/OWNERS", "feed@chromium.org" ],
-    "expiry_milestone": 80
-  },
-  {
     "name": "enable-offer-store-unmasked-wallet-cards",
     "owners": [ "jsaul@google.com" ],
     "expiry_milestone": 86
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e5245daa..5c2b3f3 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2568,14 +2568,6 @@
     "Enables a revamped context menu when a link, image, or video is long "
     "pressed within Chrome.";
 
-const char kEnableNtpRemoteSuggestionsName[] =
-    "Show server-side suggestions on the New Tab page";
-const char kEnableNtpRemoteSuggestionsDescription[] =
-    "If enabled, the list of content suggestions on the New Tab page will "
-    "contain server-side suggestions (e.g., Articles for you). Furthermore, it "
-    "allows to override the source used to retrieve these server-side "
-    "suggestions.";
-
 const char kEnableOfflinePreviewsName[] = "Offline Page Previews";
 const char kEnableOfflinePreviewsDescription[] =
     "Enable showing offline page previews on slow networks.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index d6dfbab..384a7bed 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1521,9 +1521,6 @@
 extern const char kEnableRevampedContextMenuName[];
 extern const char kEnableRevampedContextMenuDescription[];
 
-extern const char kEnableNtpRemoteSuggestionsName[];
-extern const char kEnableNtpRemoteSuggestionsDescription[];
-
 extern const char kEnableOfflinePreviewsName[];
 extern const char kEnableOfflinePreviewsDescription[];
 
diff --git a/chrome/browser/metrics/first_web_contents_profiler.cc b/chrome/browser/metrics/first_web_contents_profiler.cc
index 6feea3d2..9e48c4c 100644
--- a/chrome/browser/metrics/first_web_contents_profiler.cc
+++ b/chrome/browser/metrics/first_web_contents_profiler.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/debug/dump_without_crashing.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
@@ -144,9 +145,25 @@
     // |first_navigation_id_| may be set in DidStartNavigation() or
     // DidFinishNavigation().
     first_navigation_id_ = navigation_handle->GetNavigationId();
+  } else if (first_navigation_id_ != navigation_handle->GetNavigationId()) {
+    // Abandon if this is not the first observed top-level navigation.
+    FinishedCollectingMetrics(FinishReason::kAbandonNewNavigation);
+
+    // TODO(https://crbug.com/1027947): If FirstWebContentsProfiler is created
+    // after 2 DidStartNavigation(), but before the 2 corresponding
+    // DidFinishNavigation(), this condition will be entered on the 2nd
+    // DidFinishNavigation(). Also, if FirstWebContentsProfiler is created after
+    // 1 DidStartNavigation() but before another DidStartNavigation() and 2
+    // DidFinishNavigation(), this condition will be entered for one of the 2
+    // DidFinishNavigation(). These cases aren't expected, but a fuzzer suggests
+    // that they do happen. The DumpWithoutCrashing() below will allow us to
+    // determine whether this happens in the wild. Remove it once the problem is
+    // understood.
+    base::debug::DumpWithoutCrashing();
+
+    return;
   }
 
-  DCHECK_EQ(first_navigation_id_, navigation_handle->GetNavigationId());
   DCHECK(!did_finish_first_navigation_);
   did_finish_first_navigation_ = true;
 
diff --git a/chrome/browser/nfc/nfc_permission_context_android.cc b/chrome/browser/nfc/nfc_permission_context_android.cc
new file mode 100644
index 0000000..595cd77b
--- /dev/null
+++ b/chrome/browser/nfc/nfc_permission_context_android.cc
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nfc/nfc_permission_context_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/bind.h"
+#include "chrome/browser/android/nfc_system_level_setting_impl.h"
+#include "chrome/browser/android/tab_android.h"
+#include "chrome/browser/permissions/permission_request_id.h"
+#include "content/public/browser/web_contents.h"
+
+NfcPermissionContextAndroid::NfcPermissionContextAndroid(Profile* profile)
+    : NfcPermissionContext(profile),
+      nfc_system_level_setting_(std::make_unique<NfcSystemLevelSettingImpl>()) {
+}
+
+NfcPermissionContextAndroid::~NfcPermissionContextAndroid() = default;
+
+void NfcPermissionContextAndroid::NotifyPermissionSet(
+    const PermissionRequestID& id,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    BrowserPermissionCallback callback,
+    bool persist,
+    ContentSetting content_setting) {
+  if (content_setting != CONTENT_SETTING_ALLOW ||
+      !nfc_system_level_setting_->IsNfcAccessPossible() ||
+      nfc_system_level_setting_->IsNfcSystemLevelSettingEnabled()) {
+    NfcPermissionContext::NotifyPermissionSet(
+        id, requesting_origin, embedding_origin, std::move(callback), persist,
+        content_setting);
+    return;
+  }
+
+  content::WebContents* web_contents =
+      content::WebContents::FromRenderFrameHost(
+          content::RenderFrameHost::FromID(id.render_process_id(),
+                                           id.render_frame_id()));
+
+  // Ignore when the associated RenderFrameHost has already been destroyed.
+  if (!web_contents)
+    return;
+
+  // Only show the NFC system level setting prompt if the tab for |web_contents|
+  // is user-interactable (i.e. is the current tab, and Chrome is active and not
+  // in tab-switching mode).
+  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
+  if (tab && !tab->IsUserInteractable()) {
+    PermissionContextBase::NotifyPermissionSet(
+        id, requesting_origin, embedding_origin, std::move(callback),
+        false /* persist */, CONTENT_SETTING_BLOCK);
+    return;
+  }
+
+  // TODO(crbug.com/1034607): Close prompt when there is a navigation in a tab
+  nfc_system_level_setting_->PromptToEnableNfcSystemLevelSetting(
+      web_contents,
+      base::BindOnce(
+          &NfcPermissionContextAndroid::OnNfcSystemLevelSettingPromptClosed,
+          weak_factory_.GetWeakPtr(), id, requesting_origin, embedding_origin,
+          std::move(callback), persist, content_setting));
+}
+
+void NfcPermissionContextAndroid::OnNfcSystemLevelSettingPromptClosed(
+    const PermissionRequestID& id,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    BrowserPermissionCallback callback,
+    bool persist,
+    ContentSetting content_setting) {
+  NfcPermissionContext::NotifyPermissionSet(
+      id, requesting_origin, embedding_origin, std::move(callback), persist,
+      content_setting);
+}
diff --git a/chrome/browser/nfc/nfc_permission_context_android.h b/chrome/browser/nfc/nfc_permission_context_android.h
new file mode 100644
index 0000000..0bbb337
--- /dev/null
+++ b/chrome/browser/nfc/nfc_permission_context_android.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NFC_NFC_PERMISSION_CONTEXT_ANDROID_H_
+#define CHROME_BROWSER_NFC_NFC_PERMISSION_CONTEXT_ANDROID_H_
+
+#include "chrome/browser/android/nfc_system_level_setting.h"
+#include "chrome/browser/nfc/nfc_permission_context.h"
+
+class PermissionRequestID;
+
+class NfcPermissionContextAndroid : public NfcPermissionContext {
+ public:
+  explicit NfcPermissionContextAndroid(Profile* profile);
+  ~NfcPermissionContextAndroid() override;
+
+ private:
+  friend class NfcPermissionContextTests;
+  friend class PermissionManagerTest;
+
+  // NfcPermissionContext:
+  void NotifyPermissionSet(const PermissionRequestID& id,
+                           const GURL& requesting_origin,
+                           const GURL& embedding_origin,
+                           BrowserPermissionCallback callback,
+                           bool persist,
+                           ContentSetting content_setting) override;
+
+  void OnNfcSystemLevelSettingPromptClosed(const PermissionRequestID& id,
+                                           const GURL& requesting_origin,
+                                           const GURL& embedding_origin,
+                                           BrowserPermissionCallback callback,
+                                           bool persist,
+                                           ContentSetting content_setting);
+
+  // Overrides the NfcSystemLevelSetting object used to determine whether NFC is
+  // enabled system-wide on the device.
+  void set_nfc_system_level_setting_for_testing(
+      std::unique_ptr<NfcSystemLevelSetting> nfc_system_level_setting) {
+    nfc_system_level_setting_ = std::move(nfc_system_level_setting);
+  }
+
+  std::unique_ptr<NfcSystemLevelSetting> nfc_system_level_setting_;
+
+  base::WeakPtrFactory<NfcPermissionContextAndroid> weak_factory_{this};
+};
+
+#endif  // CHROME_BROWSER_NFC_NFC_PERMISSION_CONTEXT_ANDROID_H_
diff --git a/chrome/browser/nfc/nfc_permission_context_unittest.cc b/chrome/browser/nfc/nfc_permission_context_unittest.cc
new file mode 100644
index 0000000..1efa7490
--- /dev/null
+++ b/chrome/browser/nfc/nfc_permission_context_unittest.cc
@@ -0,0 +1,374 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nfc/nfc_permission_context.h"
+
+#include "build/build_config.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/permissions/permission_manager.h"
+#include "chrome/browser/permissions/permission_request_id.h"
+#include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_utils.h"
+
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/mock_nfc_system_level_setting.h"
+#include "chrome/browser/nfc/nfc_permission_context_android.h"
+#endif
+
+using content::MockRenderProcessHost;
+
+// NfcPermissionContextTests ------------------------------------------
+
+class NfcPermissionContextTests : public ChromeRenderViewHostTestHarness {
+ protected:
+  // ChromeRenderViewHostTestHarness:
+  void SetUp() override;
+  void TearDown() override;
+
+  PermissionRequestID RequestID(int request_id);
+
+  void RequestNfcPermission(content::WebContents* web_contents,
+                            const PermissionRequestID& id,
+                            const GURL& requesting_frame,
+                            bool user_gesture);
+
+  void PermissionResponse(const PermissionRequestID& id,
+                          ContentSetting content_setting);
+  void CheckPermissionMessageSent(int request_id, bool allowed);
+  void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
+                                          int request_id,
+                                          bool allowed);
+  void SetupRequestManager(content::WebContents* web_contents);
+  void RequestManagerDocumentLoadCompleted();
+  void RequestManagerDocumentLoadCompleted(content::WebContents* web_contents);
+  ContentSetting GetNfcContentSetting(GURL frame_0, GURL frame_1);
+  void SetNfcContentSetting(GURL frame_0,
+                            GURL frame_1,
+                            ContentSetting content_setting);
+  bool HasActivePrompt();
+  bool HasActivePrompt(content::WebContents* web_contents);
+  void AcceptPrompt();
+  void AcceptPrompt(content::WebContents* web_contents);
+  void DenyPrompt();
+  void ClosePrompt();
+
+  // owned by the browser context
+  NfcPermissionContext* nfc_permission_context_;
+  std::vector<std::unique_ptr<MockPermissionPromptFactory>>
+      mock_permission_prompt_factories_;
+
+  // A map between renderer child id and a pair represending the bridge id and
+  // whether the requested permission was allowed.
+  std::map<int, std::pair<int, bool>> responses_;
+};
+
+PermissionRequestID NfcPermissionContextTests::RequestID(int request_id) {
+  return PermissionRequestID(
+      web_contents()->GetMainFrame()->GetProcess()->GetID(),
+      web_contents()->GetMainFrame()->GetRoutingID(), request_id);
+}
+
+void NfcPermissionContextTests::RequestNfcPermission(
+    content::WebContents* web_contents,
+    const PermissionRequestID& id,
+    const GURL& requesting_frame,
+    bool user_gesture) {
+  nfc_permission_context_->RequestPermission(
+      web_contents, id, requesting_frame, user_gesture,
+      base::Bind(&NfcPermissionContextTests::PermissionResponse,
+                 base::Unretained(this), id));
+  content::RunAllTasksUntilIdle();
+}
+
+void NfcPermissionContextTests::PermissionResponse(
+    const PermissionRequestID& id,
+    ContentSetting content_setting) {
+  responses_[id.render_process_id()] =
+      std::make_pair(id.request_id(), content_setting == CONTENT_SETTING_ALLOW);
+}
+
+void NfcPermissionContextTests::CheckPermissionMessageSent(int request_id,
+                                                           bool allowed) {
+  CheckPermissionMessageSentInternal(process(), request_id, allowed);
+}
+
+void NfcPermissionContextTests::CheckPermissionMessageSentInternal(
+    MockRenderProcessHost* process,
+    int request_id,
+    bool allowed) {
+  ASSERT_EQ(responses_.count(process->GetID()), 1U);
+  EXPECT_EQ(request_id, responses_[process->GetID()].first);
+  EXPECT_EQ(allowed, responses_[process->GetID()].second);
+  responses_.erase(process->GetID());
+}
+
+void NfcPermissionContextTests::SetUp() {
+  ChromeRenderViewHostTestHarness::SetUp();
+
+  TabSpecificContentSettings::CreateForWebContents(web_contents());
+  nfc_permission_context_ = static_cast<NfcPermissionContext*>(
+      PermissionManager::Get(profile())->GetPermissionContext(
+          ContentSettingsType::NFC));
+  SetupRequestManager(web_contents());
+
+#if defined(OS_ANDROID)
+  static_cast<NfcPermissionContextAndroid*>(nfc_permission_context_)
+      ->set_nfc_system_level_setting_for_testing(
+          std::unique_ptr<NfcSystemLevelSetting>(
+              new MockNfcSystemLevelSetting()));
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(true);
+  MockNfcSystemLevelSetting::SetNfcAccessIsPossible(true);
+  MockNfcSystemLevelSetting::ClearHasShownNfcSettingPrompt();
+#endif
+}
+
+void NfcPermissionContextTests::TearDown() {
+  mock_permission_prompt_factories_.clear();
+  ChromeRenderViewHostTestHarness::TearDown();
+}
+
+void NfcPermissionContextTests::SetupRequestManager(
+    content::WebContents* web_contents) {
+  // Create PermissionRequestManager.
+  PermissionRequestManager::CreateForWebContents(web_contents);
+  PermissionRequestManager* permission_request_manager =
+      PermissionRequestManager::FromWebContents(web_contents);
+
+  // Create a MockPermissionPromptFactory for the PermissionRequestManager.
+  mock_permission_prompt_factories_.push_back(
+      std::make_unique<MockPermissionPromptFactory>(
+          permission_request_manager));
+}
+
+void NfcPermissionContextTests::RequestManagerDocumentLoadCompleted() {
+  NfcPermissionContextTests::RequestManagerDocumentLoadCompleted(
+      web_contents());
+}
+
+void NfcPermissionContextTests::RequestManagerDocumentLoadCompleted(
+    content::WebContents* web_contents) {
+  PermissionRequestManager::FromWebContents(web_contents)
+      ->DocumentOnLoadCompletedInMainFrame();
+}
+
+ContentSetting NfcPermissionContextTests::GetNfcContentSetting(GURL frame_0,
+                                                               GURL frame_1) {
+  return HostContentSettingsMapFactory::GetForProfile(profile())
+      ->GetContentSetting(frame_0, frame_1, ContentSettingsType::NFC,
+                          std::string());
+}
+
+void NfcPermissionContextTests::SetNfcContentSetting(
+    GURL frame_0,
+    GURL frame_1,
+    ContentSetting content_setting) {
+  return HostContentSettingsMapFactory::GetForProfile(profile())
+      ->SetContentSettingDefaultScope(frame_0, frame_1,
+                                      ContentSettingsType::NFC, std::string(),
+                                      content_setting);
+}
+
+bool NfcPermissionContextTests::HasActivePrompt() {
+  return HasActivePrompt(web_contents());
+}
+
+bool NfcPermissionContextTests::HasActivePrompt(
+    content::WebContents* web_contents) {
+  PermissionRequestManager* manager =
+      PermissionRequestManager::FromWebContents(web_contents);
+  return manager->IsRequestInProgress();
+}
+
+void NfcPermissionContextTests::AcceptPrompt() {
+  return AcceptPrompt(web_contents());
+  base::RunLoop().RunUntilIdle();
+}
+
+void NfcPermissionContextTests::AcceptPrompt(
+    content::WebContents* web_contents) {
+  PermissionRequestManager* manager =
+      PermissionRequestManager::FromWebContents(web_contents);
+  manager->Accept();
+  base::RunLoop().RunUntilIdle();
+}
+
+void NfcPermissionContextTests::DenyPrompt() {
+  PermissionRequestManager* manager =
+      PermissionRequestManager::FromWebContents(web_contents());
+  manager->Deny();
+  base::RunLoop().RunUntilIdle();
+}
+
+void NfcPermissionContextTests::ClosePrompt() {
+  PermissionRequestManager* manager =
+      PermissionRequestManager::FromWebContents(web_contents());
+  manager->Closing();
+  base::RunLoop().RunUntilIdle();
+}
+
+// Tests ----------------------------------------------------------------------
+
+TEST_F(NfcPermissionContextTests, SinglePermissionPrompt) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame,
+                       true /* user_gesture */);
+
+#if defined(OS_ANDROID)
+  ASSERT_TRUE(HasActivePrompt());
+#else
+  ASSERT_FALSE(HasActivePrompt());
+#endif
+}
+
+TEST_F(NfcPermissionContextTests, SinglePermissionPromptFailsOnInsecureOrigin) {
+  GURL requesting_frame("http://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_FALSE(HasActivePrompt());
+}
+
+#if defined(OS_ANDROID)
+// Tests concerning Android NFC setting
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingDisabledWhenNfcPermissionGetsGranted) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_TRUE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  AcceptPrompt();
+  ASSERT_TRUE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingDisabledWhenNfcPermissionGetsDenied) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_TRUE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  DenyPrompt();
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  CheckPermissionMessageSent(0 /* request _id */, false /* allowed */);
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingDisabledWhenNfcPermissionAlreadyGranted) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  SetNfcContentSetting(requesting_frame, requesting_frame,
+                       CONTENT_SETTING_ALLOW);
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_FALSE(HasActivePrompt());
+  ASSERT_TRUE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingEnabledWhenNfcPermissionAlreadyGranted) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  SetNfcContentSetting(requesting_frame, requesting_frame,
+                       CONTENT_SETTING_ALLOW);
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_FALSE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingCantBeEnabledWhenNfcPermissionGetsGranted) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_TRUE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  AcceptPrompt();
+  ASSERT_FALSE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingCantBeEnabledWhenNfcPermissionGetsDenied) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_TRUE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  DenyPrompt();
+  ASSERT_FALSE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  CheckPermissionMessageSent(0 /* request _id */, false /* allowed */);
+}
+
+TEST_F(NfcPermissionContextTests,
+       SystemNfcSettingCantBeEnabledWhenNfcPermissionAlreadyGranted) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  SetNfcContentSetting(requesting_frame, requesting_frame,
+                       CONTENT_SETTING_ALLOW);
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+  MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
+  MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
+  EXPECT_FALSE(HasActivePrompt());
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+  ASSERT_FALSE(HasActivePrompt());
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+  CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
+}
+
+TEST_F(NfcPermissionContextTests, CancelNfcPermissionRequest) {
+  GURL requesting_frame("https://www.example.com/nfc");
+  EXPECT_EQ(CONTENT_SETTING_ASK,
+            GetNfcContentSetting(requesting_frame, requesting_frame));
+
+  NavigateAndCommit(requesting_frame);
+  RequestManagerDocumentLoadCompleted();
+
+  ASSERT_FALSE(HasActivePrompt());
+
+  RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
+
+  ASSERT_TRUE(HasActivePrompt());
+
+  // Simulate the frame going away; the request should be removed.
+  ClosePrompt();
+
+  ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
+
+  // Ensure permission isn't persisted.
+  EXPECT_EQ(CONTENT_SETTING_ASK,
+            GetNfcContentSetting(requesting_frame, requesting_frame));
+}
+#endif
diff --git a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
index 52769d7..2cc9f718 100644
--- a/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
+++ b/chrome/browser/optimization_guide/optimization_guide_hints_manager_unittest.cc
@@ -1511,8 +1511,17 @@
   EXPECT_FALSE(navigation_data->has_page_hint_value());
 }
 
-TEST_F(OptimizationGuideHintsManagerTest,
-       CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp) {
+#if defined(THREAD_SANITIZER)
+// Data race which TSan detects: https://crbug.com/1035004
+#define MAYBE_CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp \
+  DISABLED_CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp
+#else
+#define MAYBE_CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp \
+  CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp
+#endif
+TEST_F(
+    OptimizationGuideHintsManagerTest,
+    MAYBE_CanApplyOptimizationAndPopulatesMetadataWithFirstOptThatMatchesWithExp) {
   base::test::ScopedFeatureList scoped_list;
   scoped_list.InitAndEnableFeatureWithParameters(
       optimization_guide::features::kOptimizationHintsExperiments,
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index a8a1864..c00a6aa 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -465,8 +465,9 @@
 // has the correct URL for the PDF extension.
 // TODO(wjmaclean): Are there any attributes we can/should test with respect to
 // the extension's loaded html?
+// TODO(https://crbug.com/1034972): Re-enable. Flaky on all platforms.
 IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithTestGuestViewManager,
-                       PdfExtensionLoadedInGuest) {
+                       DISABLED_PdfExtensionLoadedInGuest) {
   // Load test HTML, and verify the text area has focus.
   GURL main_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
   ui_test_utils::NavigateToURL(browser(), main_url);
diff --git a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.cc b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.cc
index 4f69f55..7d8fe99 100644
--- a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.cc
+++ b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.cc
@@ -6,19 +6,98 @@
 
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "components/performance_manager/public/decorators/page_live_state_decorator.h"
+#include "components/performance_manager/public/performance_manager.h"
+#include "content/public/browser/web_contents_observer.h"
 
 namespace performance_manager {
 
+// Listens to content::WebContentsObserver notifications for a given WebContents
+// and updates the PageLiveStateDecorator accordingly. Destroys itself when the
+// WebContents it observes is destroyed.
+class PageLiveStateDecoratorHelper::WebContentsObserver
+    : public content::WebContentsObserver {
+ public:
+  explicit WebContentsObserver(content::WebContents* web_contents,
+                               PageLiveStateDecoratorHelper* outer)
+      : content::WebContentsObserver(web_contents),
+        outer_(outer),
+        prev_(nullptr),
+        next_(outer->first_web_contents_observer_) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    if (next_) {
+      DCHECK(!next_->prev_);
+      next_->prev_ = this;
+    }
+    outer_->first_web_contents_observer_ = this;
+  }
+
+  WebContentsObserver(const WebContentsObserver&) = delete;
+  WebContentsObserver& operator=(const WebContentsObserver&) = delete;
+
+  ~WebContentsObserver() override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  }
+
+  // content::WebContentsObserver:
+  void OnIsConnectedToBluetoothDeviceChanged(
+      bool is_connected_to_bluetooth_device) override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    PageLiveStateDecorator::OnIsConnectedToBluetoothDeviceChanged(
+        web_contents(), is_connected_to_bluetooth_device);
+  }
+
+  void WebContentsDestroyed() override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    DetachAndDestroy();
+  }
+
+  // Removes the WebContentsObserver from the linked list and deletes it.
+  void DetachAndDestroy() {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    if (prev_) {
+      DCHECK_EQ(prev_->next_, this);
+      prev_->next_ = next_;
+    } else {
+      DCHECK_EQ(outer_->first_web_contents_observer_, this);
+      outer_->first_web_contents_observer_ = next_;
+    }
+    if (next_) {
+      DCHECK_EQ(next_->prev_, this);
+      next_->prev_ = prev_;
+    }
+
+    delete this;
+  }
+
+ private:
+  PageLiveStateDecoratorHelper* const outer_;
+  WebContentsObserver* prev_;
+  WebContentsObserver* next_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+};
+
 PageLiveStateDecoratorHelper::PageLiveStateDecoratorHelper() {
+  PerformanceManager::AddObserver(this);
+
   MediaCaptureDevicesDispatcher::GetInstance()
       ->GetMediaStreamCaptureIndicator()
       ->AddObserver(this);
 }
 
 PageLiveStateDecoratorHelper::~PageLiveStateDecoratorHelper() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   MediaCaptureDevicesDispatcher::GetInstance()
       ->GetMediaStreamCaptureIndicator()
       ->RemoveObserver(this);
+
+  // Destroy all WebContentsObserver to ensure that PageLiveStateDecorators are
+  // no longer maintained.
+  while (first_web_contents_observer_)
+    first_web_contents_observer_->DetachAndDestroy();
+
+  PerformanceManager::RemoveObserver(this);
 }
 
 void PageLiveStateDecoratorHelper::OnIsCapturingVideoChanged(
@@ -52,4 +131,12 @@
                                                       is_capturing_desktop);
 }
 
+void PageLiveStateDecoratorHelper::OnPageNodeCreatedForWebContents(
+    content::WebContents* web_contents) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Start observing the WebContents. See comment on
+  // |first_web_contents_observer_| for lifetime management details.
+  new WebContentsObserver(web_contents, this);
+}
+
 }  // namespace performance_manager
diff --git a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.h b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.h
index 1bd5d20..6475e43 100644
--- a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.h
+++ b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper.h
@@ -5,13 +5,16 @@
 #ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_DECORATORS_HELPERS_PAGE_LIVE_STATE_DECORATOR_HELPER_H_
 #define CHROME_BROWSER_PERFORMANCE_MANAGER_DECORATORS_HELPERS_PAGE_LIVE_STATE_DECORATOR_HELPER_H_
 
+#include "base/containers/flat_set.h"
 #include "base/sequence_checker.h"
 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
+#include "components/performance_manager/public/performance_manager_main_thread_observer.h"
 
 namespace performance_manager {
 
 class PageLiveStateDecoratorHelper
-    : public MediaStreamCaptureIndicator::Observer {
+    : public MediaStreamCaptureIndicator::Observer,
+      public PerformanceManagerMainThreadObserver {
  public:
   PageLiveStateDecoratorHelper();
   ~PageLiveStateDecoratorHelper() override;
@@ -30,7 +33,20 @@
   void OnIsCapturingDesktopChanged(content::WebContents* contents,
                                    bool is_capturing_desktop) override;
 
+  // PerformanceManagerMainThreadObserver:
+  void OnPageNodeCreatedForWebContents(
+      content::WebContents* web_contents) override;
+
  private:
+  class WebContentsObserver;
+
+  // Linked list of WebContentsObservers created by this
+  // PageLiveStateDecoratorHelper. Each WebContentsObservers removes itself from
+  // the list and destroys itself when its associated WebContents is destroyed.
+  // Additionally, all WebContentsObservers that are still in this list when the
+  // destructor of PageLiveStateDecoratorHelper is invoked are destroyed.
+  WebContentsObserver* first_web_contents_observer_ = nullptr;
+
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
index a3e2f8f..66f56361 100644
--- a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
+++ b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
@@ -10,6 +10,7 @@
 #include "components/performance_manager/embedder/performance_manager_registry.h"
 #include "components/performance_manager/performance_manager_test_harness.h"
 #include "components/performance_manager/test_support/page_live_state_decorator.h"
+#include "content/public/test/web_contents_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace performance_manager {
@@ -30,20 +31,22 @@
     ChromeRenderViewHostTestHarness::SetUp();
     perf_man_ = PerformanceManagerImpl::Create(base::DoNothing());
     registry_ = PerformanceManagerRegistry::Create();
+    helper_ = std::make_unique<PageLiveStateDecoratorHelper>();
     indicator_ = MediaCaptureDevicesDispatcher::GetInstance()
                      ->GetMediaStreamCaptureIndicator();
     auto contents = CreateTestWebContents();
-    helper_ = std::make_unique<PageLiveStateDecoratorHelper>();
     SetContents(std::move(contents));
   }
 
   void TearDown() override {
-    helper_.reset();
-    indicator_.reset();
     DeleteContents();
-    registry_->TearDown();
-    registry_.reset();
+    helper_.reset();
+    if (registry_) {
+      registry_->TearDown();
+      registry_.reset();
+    }
     // Have the performance manager destroy itself.
+    indicator_.reset();
     PerformanceManagerImpl::Destroy(std::move(perf_man_));
     task_environment()->RunUntilIdle();
 
@@ -63,6 +66,9 @@
       blink::mojom::MediaStreamType stream_type,
       bool (PageLiveStateDecorator::Data::*pm_getter)() const);
 
+  // Forces deletion of the PageLiveStateDecoratorHelper.
+  void ResetHelper() { helper_.reset(); }
+
  private:
   scoped_refptr<MediaStreamCaptureIndicator> indicator_;
   std::unique_ptr<PerformanceManagerImpl> perf_man_;
@@ -116,4 +122,40 @@
       &PageLiveStateDecorator::Data::IsCapturingDesktop);
 }
 
+TEST_F(PageLiveStateDecoratorHelperTest, IsConnectedToBluetoothDevice) {
+  TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &PageLiveStateDecorator::Data::IsConnectedToBluetoothDevice, false);
+  content::WebContentsTester::For(web_contents())
+      ->TestIncrementBluetoothConnectedDeviceCount();
+  TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &PageLiveStateDecorator::Data::IsConnectedToBluetoothDevice, true);
+  content::WebContentsTester::For(web_contents())
+      ->TestDecrementBluetoothConnectedDeviceCount();
+  TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &PageLiveStateDecorator::Data::IsConnectedToBluetoothDevice, false);
+}
+
+// Create many WebContents to exercice the code that maintains the linked list
+// of PageLiveStateDecoratorHelper::WebContentsObservers.
+TEST_F(PageLiveStateDecoratorHelperTest, ManyPageNodes) {
+  std::unique_ptr<content::WebContents> c1 = CreateTestWebContents();
+  std::unique_ptr<content::WebContents> c2 = CreateTestWebContents();
+  std::unique_ptr<content::WebContents> c3 = CreateTestWebContents();
+  std::unique_ptr<content::WebContents> c4 = CreateTestWebContents();
+  std::unique_ptr<content::WebContents> c5 = CreateTestWebContents();
+
+  // Expect no crash when WebContentsObservers are destroyed.
+
+  // This deletes WebContentsObservers associated with |c1|, |c3| and |c5|.
+  c1.reset();
+  c3.reset();
+  c5.reset();
+
+  // This deletes remaining WebContentsObservers.
+  ResetHelper();
+}
+
 }  // namespace performance_manager
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index fa9febb..007fa992 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/media/midi_permission_context.h"
 #include "chrome/browser/media/midi_sysex_permission_context.h"
 #include "chrome/browser/media/webrtc/media_stream_device_permission_context.h"
-#include "chrome/browser/nfc/nfc_permission_context.h"
 #include "chrome/browser/notifications/notification_permission_context.h"
 #include "chrome/browser/payments/payment_handler_permission_context.h"
 #include "chrome/browser/permissions/permission_context_base.h"
@@ -60,8 +59,10 @@
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
+#include "chrome/browser/nfc/nfc_permission_context_android.h"
 #else
 #include "chrome/browser/geolocation/geolocation_permission_context.h"
+#include "chrome/browser/nfc/nfc_permission_context.h"
 #endif
 
 using blink::mojom::PermissionStatus;
@@ -358,8 +359,13 @@
   permission_contexts_[ContentSettingsType::WAKE_LOCK_SYSTEM] =
       std::make_unique<WakeLockPermissionContext>(
           profile, ContentSettingsType::WAKE_LOCK_SYSTEM);
+#if !defined(OS_ANDROID)
   permission_contexts_[ContentSettingsType::NFC] =
       std::make_unique<NfcPermissionContext>(profile);
+#else
+  permission_contexts_[ContentSettingsType::NFC] =
+      std::make_unique<NfcPermissionContextAndroid>(profile);
+#endif
 }
 
 PermissionManager::~PermissionManager() {
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h
index a3b90b9..ceedc68 100644
--- a/chrome/browser/permissions/permission_manager.h
+++ b/chrome/browser/permissions/permission_manager.h
@@ -132,6 +132,7 @@
  private:
   friend class PermissionManagerTest;
   friend class GeolocationPermissionContextTests;
+  friend class NfcPermissionContextTests;
 
   class PendingRequest;
   using PendingRequestsMap = base::IDMap<std::unique_ptr<PendingRequest>>;
diff --git a/chrome/browser/permissions/permission_request_impl.cc b/chrome/browser/permissions/permission_request_impl.cc
index 1ba9186..4182ddc 100644
--- a/chrome/browser/permissions/permission_request_impl.cc
+++ b/chrome/browser/permissions/permission_request_impl.cc
@@ -228,6 +228,9 @@
     case ContentSettingsType::CLIPBOARD_READ_WRITE:
       message_id = IDS_CLIPBOARD_PERMISSION_FRAGMENT;
       break;
+    case ContentSettingsType::NFC:
+      message_id = IDS_NFC_PERMISSION_FRAGMENT;
+      break;
     default:
       NOTREACHED();
       return base::string16();
diff --git a/chrome/browser/permissions/permission_request_manager.h b/chrome/browser/permissions/permission_request_manager.h
index 11ac39e..bfc33bed 100644
--- a/chrome/browser/permissions/permission_request_manager.h
+++ b/chrome/browser/permissions/permission_request_manager.h
@@ -127,6 +127,7 @@
   // lot of friends.
   friend class GeolocationBrowserTest;
   friend class GeolocationPermissionContextTests;
+  friend class NfcPermissionContextTests;
   friend class MockPermissionPromptFactory;
   friend class PermissionContextBaseTests;
   friend class PermissionRequestManagerTest;
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index cce23ae..d471deb 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -683,6 +683,9 @@
   { key::kDeviceLoginScreenShowOptionsInSystemTrayMenu,
     nullptr,
     base::Value::Type::BOOLEAN },
+  { key::kDeviceLoginScreenPrimaryMouseButtonSwitch,
+    nullptr,
+    base::Value::Type::BOOLEAN },
   { key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
     nullptr,
     base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/e2e_test/.style.yapf b/chrome/browser/policy/e2e_test/.style.yapf
deleted file mode 100644
index 5a64936..0000000
--- a/chrome/browser/policy/e2e_test/.style.yapf
+++ /dev/null
@@ -1,2 +0,0 @@
-[style]

-based_on_style = chromium
\ No newline at end of file
diff --git a/chrome/browser/policy/e2e_test/.vpython b/chrome/browser/policy/e2e_test/.vpython
deleted file mode 100644
index b68566c..0000000
--- a/chrome/browser/policy/e2e_test/.vpython
+++ /dev/null
@@ -1,100 +0,0 @@
-# This file defines all the extra packages we need to install to run the python
-# scripts in our repo and is used in LUCI to create reproducible bubbles in
-# which to run our ./test.py script.
-#
-# You can also use this locally by invoking `vpython` instead of `python` when
-# running the test scripts.
-#
-# More information:
-# https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md
-python_version: "2.7"
-
-wheel: <
-  name: "infra/celab/celab/windows-amd64"
-  # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8900225462594660384
-  version: "Q1ebL0sPA1vX4tcIGj6d0IXxXa02M5CsBm3p0SbeGZUC"
->
-
-# googleapiclient
-wheel: <
-  name: "infra/python/wheels/google_api_python_client-py2_py3"
-  version: "version:1.6.2"
->
-
-# googleapiclient's dependencies
-wheel: <
-  name: "infra/python/wheels/httplib2-py2_py3"
-  version: "version:0.10.3"
->
-wheel: <
-  name: "infra/python/wheels/oauth2client-py2_py3"
-  version: "version:4.1.3"
->
-wheel: <
-  name: "infra/python/wheels/pyasn1-py2_py3"
-  version: "version:0.2.3"
->
-wheel: <
-  name: "infra/python/wheels/pyasn1_modules-py2_py3"
-  version: "version:0.0.8"
->
-wheel: <
-  name: "infra/python/wheels/rsa-py2_py3"
-  version: "version:3.4.2"
->
-wheel: <
-  name: "infra/python/wheels/six-py2_py3"
-  version: "version:1.10.0"
->
-wheel: <
-  name: "infra/python/wheels/uritemplate-py2_py3"
-  version: "version:3.0.0"
->
-
-# google.protobuf
-wheel: <
-  name: "infra/python/wheels/protobuf-py2_py3"
-  version: "version:3.6.1"
->
-
-# iam.admin.v1
-wheel: <
-  name: "infra/python/wheels/grpc-google-iam-admin-v1-py2_py3"
-  version: "version:0.10.0"
->
-
-# iam.admin.v1's dependencies
-wheel: <
-  name: "infra/python/wheels/grpc-google-iam-v1-py2_py3"
-  version: "version:0.11.4"
->
-
-wheel: <
-  name: "infra/python/wheels/googleapis-common-protos-py2_py3"
-  version: "version:1.5.3"
->
-
-wheel: <
-  name: "infra/python/wheels/grpcio/${vpython_platform}"
-  version: "version:1.4.0"
->
-
-wheel: <
-  name: "infra/python/wheels/futures-py2_py3"
-  version: "version:3.1.1"
->
-
-wheel: <
-  name: "infra/python/wheels/enum34-py2"
-  version: "version:1.1.6"
->
-
-wheel: <
-  name: "infra/python/wheels/absl-py-py2_py3"
-  version: "version:0.7.1"
->
-
-wheel: <
-  name: "infra/python/wheels/wheel-py2_py3"
-  version: "version:0.33.1"
->
diff --git a/chrome/browser/policy/e2e_test/infra/chrome_ent_test_case.py b/chrome/browser/policy/e2e_test/infra/chrome_ent_test_case.py
deleted file mode 100644
index fec0453a..0000000
--- a/chrome/browser/policy/e2e_test/infra/chrome_ent_test_case.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import random
-import string
-import subprocess
-import time
-
-from absl import flags
-from chrome_ent_test.infra.core import EnterpriseTestCase
-
-FLAGS = flags.FLAGS
-flags.DEFINE_string('chrome_installer', None,
-                    'The path to the chrome installer')
-flags.mark_flag_as_required('chrome_installer')
-
-flags.DEFINE_string(
-    'chromedriver', None,
-    'The path to the chromedriver executable. If not specified, '
-    'a chocholatey chromedriver packae will be installed and used.')
-
-
-class ChromeEnterpriseTestCase(EnterpriseTestCase):
-  """Base class for Chrome enterprise test cases."""
-
-  def InstallChrome(self, instance_name):
-    """Installs chrome.
-
-    Currently supports two types of installer:
-    - mini_installer.exe, and
-    - *.msi
-    """
-    self.RunCommand(instance_name, r'md -Force c:\temp')
-    file_name = self.UploadFile(instance_name, FLAGS.chrome_installer,
-                                r'c:\temp')
-
-    if file_name.lower().endswith('mini_installer.exe'):
-      dir = os.path.dirname(os.path.abspath(__file__))
-      self.UploadFile(instance_name, os.path.join(dir, 'installer_data'),
-                      r'c:\temp')
-      cmd = file_name + r' --installerdata=c:\temp\installer_data'
-    else:
-      cmd = 'msiexec /i %s' % file_name
-
-    self.RunCommand(instance_name, cmd)
-
-    cmd = (
-        r'powershell -File c:\cel\supporting_files\ensure_chromium_api_keys.ps1'
-        r' -Path gs://%s/api/key') % self.gsbucket
-    self.RunCommand(instance_name, cmd)
-
-  def SetPolicy(self, instance_name, policy_name, policy_value, policy_type):
-    r"""Sets a Google Chrome policy in registry.
-
-    Args:
-      policy_name: the policy name.
-        The name can contain \. In this case, the last segment will be the
-        real policy name, while anything before will be part of the key.
-    """
-    segments = policy_name.split('\\')
-    policy_name = segments[-1]
-
-    # The policy will be set for both Chrome and Chromium, since only
-    # googlers can build Chrome-branded executable.
-    keys = [
-        r'HKLM\Software\Policies\Google\Chrome',
-        r'HKLM\Software\Policies\Chromium'
-    ]
-    for key in keys:
-      if len(segments) >= 2:
-        key += '\\' + '\\'.join(segments[:-1])
-
-      cmd = (r"Set-GPRegistryValue -Name 'Default Domain Policy' "
-             "-Key %s -ValueName %s -Value %s -Type %s") % (
-                 key, policy_name, policy_value, policy_type)
-      self.clients[instance_name].RunPowershell(cmd)
-
-  def RemovePolicy(self, instance_name, policy_name):
-    """Removes a Google Chrome policy in registry.
-    Args:
-      policy_name: the policy name.
-    """
-    segments = policy_name.split('\\')
-    policy_name = segments[-1]
-
-    keys = [
-        r'HKLM\Software\Policies\Google\Chrome',
-        r'HKLM\Software\Policies\Chromium'
-    ]
-    for key in keys:
-      if len(segments) >= 2:
-        key += '\\' + '\\'.join(segments[:-1])
-
-      cmd = (r"Remove-GPRegistryValue -Name 'Default Domain Policy' "
-             "-Key %s -ValueName %s") % (key, policy_name)
-      self.clients[instance_name].RunPowershell(cmd)
-
-  def InstallWebDriver(self, instance_name):
-    self.InstallPipPackagesLatest(instance_name,
-                                  ['selenium', 'absl-py', 'pywin32'])
-
-    temp_dir = 'C:\\temp\\'
-    if FLAGS.chromedriver is None:
-      # chromedriver flag is not specified. Install the chocolatey package.
-      self.InstallChocolateyPackage(instance_name, 'chromedriver',
-                                    '74.0.3729.60')
-      self.RunCommand(
-          instance_name, "copy %s %s" %
-          (r"C:\ProgramData\chocolatey\lib\chromedriver\tools\chromedriver.exe",
-           temp_dir))
-    else:
-      self.UploadFile(instance_name, FLAGS.chromedriver, temp_dir)
-
-    dir = os.path.dirname(os.path.abspath(__file__))
-    self.UploadFile(instance_name, os.path.join(dir, 'test_util.py'), temp_dir)
-
-  def RunWebDriverTest(self, instance_name, test_file, args=[]):
-    """Runs a python webdriver test on an instance.
-
-    Args:
-      instance_name: name of the instance.
-      test_file: the path of the webdriver test file.
-      args: the list of arguments passed to the test.
-
-    Returns:
-      the output."""
-    self.EnsurePythonInstalled(instance_name)
-
-    # upload the test
-    file_name = self.UploadFile(instance_name, test_file, r'c:\temp')
-
-    # run the test
-    args = subprocess.list2cmdline(args)
-    cmd = r'c:\Python27\python.exe %s %s' % (file_name, args)
-    return self.RunCommand(instance_name, cmd)
-
-  def RunUITest(self, instance_name, test_file, timeout=300, args=[]):
-    """Runs a UI test on an instance.
-
-    Args:
-      instance_name: name of the instance.
-      test_file: the path of the UI test file.
-      timeout: the timeout in seconds. Default is 300,
-               i.e. 5 minutes.
-      args: the list of arguments passed to the test.
-
-    Returns:
-      the output."""
-    self.EnsurePythonInstalled(instance_name)
-
-    # upload the test
-    file_name = self.UploadFile(instance_name, test_file, r'c:\temp')
-
-    # run the test.
-    # note that '-u' flag is passed to enable unbuffered stdout and stderr.
-    # Without this flag, if the test is killed because of timeout, we will not
-    # get any output from stdout because the output is buffered. When this
-    # happens it makes debugging really hard.
-    args = subprocess.list2cmdline(args)
-    ui_test_cmd = r'c:\Python27\python.exe -u %s %s' % (file_name, args)
-    cmd = (r'python c:\cel\supporting_files\run_ui_test.py --timeout %s -- %s'
-          ) % (timeout, ui_test_cmd)
-    return self.RunCommand(instance_name, cmd)
-
-  def _generatePassword(self):
-    """Generates a random password."""
-    s = [random.choice(string.ascii_lowercase) for _ in range(4)]
-    s += [random.choice(string.ascii_uppercase) for _ in range(4)]
-    s += [random.choice(string.digits) for _ in range(4)]
-    random.shuffle(s)
-    return ''.join(s)
-
-  def _rebootInstance(self, instance_name):
-    self.RunCommand(instance_name, 'shutdown /r /t 0')
-
-    # wait a while for the instance to boot up
-    time.sleep(2 * 60)
-
-  def EnableUITest(self, instance_name):
-    """Configures the instance so that UI tests can be run on it."""
-    self.InstallWebDriver(instance_name)
-    self.InstallChocolateyPackageLatest(instance_name, 'sysinternals')
-    self.InstallPipPackagesLatest(instance_name, ['pywinauto', 'requests'])
-
-    password = self._generatePassword()
-    user_name = 'ui_user'
-    cmd = (r'powershell -File c:\cel\supporting_files\enable_auto_logon.ps1 '
-           r'-userName %s -password %s') % (user_name, password)
-    self.RunCommand(instance_name, cmd)
-    self._rebootInstance(instance_name)
-
-    cmd = (r'powershell -File c:\cel\supporting_files\set_ui_agent.ps1 '
-           '-username %s') % user_name
-    self.RunCommand(instance_name, cmd)
-    self._rebootInstance(instance_name)
diff --git a/chrome/browser/policy/e2e_test/infra/generate_host_files.py b/chrome/browser/policy/e2e_test/infra/generate_host_files.py
deleted file mode 100644
index 801d047..0000000
--- a/chrome/browser/policy/e2e_test/infra/generate_host_files.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import os
-import sys
-
-
-def ParseArgs():
-  parser = argparse.ArgumentParser(
-      description='Host file generator for CELab E2E tests')
-
-  all_tokens = ['project_id', 'storage_bucket', 'storage_prefix']
-  template_help = 'The full path to the *.host.textpb template file to use. '
-  template_help += 'Must contain the following tokens: %s' % all_tokens
-  parser.add_argument(
-      '--template', metavar='<host_file>', required=True, help=template_help)
-  parser.add_argument(
-      '--projects',
-      metavar='<projectA;projectB;...>',
-      dest="projects",
-      required=True,
-      help='The values to replace "<project_id>" with.')
-  parser.add_argument(
-      '--storage_bucket',
-      metavar='<token>',
-      dest="storage_bucket",
-      required=True,
-      help='The value to replace "<storage_bucket>" with.')
-  parser.add_argument(
-      '--storage_prefix',
-      metavar='<token>',
-      dest="storage_prefix",
-      required=True,
-      help='The value to replace "<storage_prefix>" with.')
-  parser.add_argument(
-      '--destination_dir',
-      metavar='<path>',
-      dest='destination',
-      required=True,
-      action='store',
-      help='Where to collect extra logs on test failures')
-
-  return parser.parse_args()
-
-
-def ConfigureLogging(args):
-  logfmt = '%(asctime)s %(filename)s:%(lineno)s: [%(levelname)s] %(message)s'
-  datefmt = '%Y/%m/%d %H:%M:%S'
-
-  logging.basicConfig(level=logging.INFO, format=logfmt, datefmt=datefmt)
-
-
-if __name__ == '__main__':
-  args = ParseArgs()
-
-  ConfigureLogging(args)
-
-  logging.info("Arguments: %s" % args)
-
-  if not os.path.exists(args.template):
-    raise ValueError('Template host file not found: %s' % args.template)
-
-  if not os.path.exists(args.destination):
-    raise ValueError('Destination directory not found: %s' % args.destination)
-
-  # Generate all the host files based off the arguments passed.
-  with open(args.template, 'r') as f:
-    template = f.read()
-
-  for project_id in args.projects.split(';'):
-    filename = "%s.host.textpb" % project_id
-    destination = os.path.join(args.destination, filename)
-    with open(destination, 'w') as f:
-      logging.info("Generating %s" % destination)
-      content = template.replace("<project_id>", project_id)
-      content = content.replace("<storage_bucket>", args.storage_bucket)
-      content = content.replace("<storage_prefix>", args.storage_prefix)
-      f.write(content)
-
-  sys.exit(0)
diff --git a/chrome/browser/policy/e2e_test/infra/installer_data b/chrome/browser/policy/e2e_test/infra/installer_data
deleted file mode 100644
index 75f0c017..0000000
--- a/chrome/browser/policy/e2e_test/infra/installer_data
+++ /dev/null
@@ -1,18 +0,0 @@
-{

-  "distribution":{

-     "make_chrome_default":true,

-     "system_level":true,

-     "multi_install":true,

-     "verbose_logging":true,

-     "chrome":true,

-     "require_eula":false,

-     "skip_first_run_ui":true,

-     "import_bookmarks":false,

-     "show_welcome_page":true,

-     "import_search_engine":false,

-     "import_history":false,

-     "alternate_shortcut_text":false,

-     "create_all_shortcuts":true,

-     "do_not_launch_chrome":true

-  }

-}
\ No newline at end of file
diff --git a/chrome/browser/policy/e2e_test/infra/template.host.textpb b/chrome/browser/policy/e2e_test/infra/template.host.textpb
deleted file mode 100644
index c8a16b5..0000000
--- a/chrome/browser/policy/e2e_test/infra/template.host.textpb
+++ /dev/null
@@ -1,108 +0,0 @@
-# This file is used as a template to generate host files for our CI tests.
-# <xyz> tokens are replaced with real values by generate_host_files.py.
-
-project {
-  # ID of the project. Note that it's not the name of the project.
-  name: '<project_id>'
-
-  # All assets will be created in this zone. Note that this is NOT the region name.
-  zone: 'us-west1-b'
-}
-
-# Where the logs go.
-log_settings { admin_log: "admin" }
-
-
-storage {
-  # The GCS storage bucket.
-  bucket: "<storage_bucket>",
-
-  # all files used by CEL will be put under this directory.
-  prefix: "<storage_prefix>"
-}
-
-machine_type {
-  # Name must match the host_machine_type field in the windows_machine asset
-  # entries.
-  name: 'win2012r2'
-
-  # Going to specify instance properties for a new GCE instance. Alternatively,
-  # we could specify a GCE instance template name.
-  instance_properties {
-    # Go with 2 CPUs and 7.5GB of RAM. This is the GCE machine type, not to be
-    # confused with the CEL machine_type.
-    machineType: 'projects/${host.project.name}/zones/${host.project.zone}/machineTypes/n1-standard-2'
-
-    # Scheduling options. By default instances are not pre-emptible.
-    scheduling {
-      automaticRestart: true
-    }
-
-    # Disks. We only need one disk
-    disks {
-      # autoDelete must be set to true when specifying initializeParams.
-      # Otherwise the toolchain will remind you.
-      autoDelete: true
-
-      # ... which is a boot disk. This can be left out since the first disk
-      # will become the boot disk by default.
-      boot: true
-
-      initializeParams {
-        # This is a special form for referencing the URL property of the image
-        # object named windows-2012-r2. Furthermore, this image type is not
-        # defined in this file. Instead see the builtins.textpb file for a list
-        # of builtin host assets that can be included for convenience.
-        sourceImage: '${host.image.windows-2012-r2.url}'
-      }
-    }
-
-    # Note that we are leaving a bunch of fields out because their defaults are
-    # reasonable. See the GCE documentation, and in particular the REST API
-    # documentation for what these fields do. For our convenience, we generate
-    # a .proto file containing the Compute API schema which has the same
-    # information. This generated .proto file can be found at
-    # /schema/gcp/compute/compute-api.proto.
-  }
-}
-
-machine_type {
-  # Name must match the host_machine_type field in the windows_machine asset
-  # entries.
-  name: 'win2016'
-
-  instance_properties {
-    machineType: 'projects/${host.project.name}/zones/${host.project.zone}/machineTypes/n1-standard-2'
-
-    scheduling {
-      automaticRestart: true
-    }
-
-    disks {
-      autoDelete: true
-      boot: true
-
-      initializeParams {
-        sourceImage: '${host.image.windows-2016.url}'
-      }
-    }
-  }
-}
-
-machine_type {
-  name: 'win7'
-  nested_vm {
-    image: 'gs://<storage_bucket>/images/win7_sp1_ent_unlicensed.img'
-    user_name: 'win7'
-    password: 'pass@word!'
-  }
-}
-
-machine_type {
-  name: 'win10'
-  nested_vm {
-    image: 'gs://<storage_bucket>/images/win10_pro_1803.img'
-    user_name: 'win10'
-    password: 'pass@word!'
-  }
-}
diff --git a/chrome/browser/policy/e2e_test/infra/test_util.py b/chrome/browser/policy/e2e_test/infra/test_util.py
deleted file mode 100644
index f08eed66..0000000
--- a/chrome/browser/policy/e2e_test/infra/test_util.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Contains utility methods that can be used by python tests on Windows."""
-
-import os
-import time
-import win32con
-import win32gui
-from selenium import webdriver
-from selenium.webdriver.chrome.options import Options
-
-
-def _window_enum_handler(hwnd, window_list):
-  win_title = win32gui.GetWindowText(hwnd)
-  if 'Google Chrome' in win_title or 'Chromium' in win_title:
-    window_list.append(hwnd)
-
-
-def _get_chrome_windows():
-  """Gets the list of hwnd of Chrome windows."""
-  window_list = []
-  win32gui.EnumWindows(_window_enum_handler, window_list)
-  return window_list
-
-
-def shutdown_chrome():
-  """Shutdown Chrome cleanly.
-
-    Surprisingly there is no easy way in chromedriver to shutdown Chrome
-    cleanly on Windows. So we have to use win32 API to do that: we find
-    the chrome window first, then send WM_CLOSE message to it.
-  """
-  window_list = _get_chrome_windows()
-  if not window_list:
-    raise RuntimeError("Cannot find chrome windows")
-
-  for win in window_list:
-    win32gui.SendMessage(win, win32con.WM_CLOSE, 0, 0)
-
-  # wait a little bit for chrome processes to end.
-  # TODO: the right way is to wait until there are no chrome.exe processes.
-  time.sleep(2)
-
-
-def create_chrome_webdriver(chrome_options=None, incognito=False, prefs=None):
-  """Configures and returns a Chrome WebDriver object."
-
-  Args:
-    chrome_options: The default ChromeOptions to use.
-    incognito: Whether or not to launch Chrome in incognito mode.
-    prefs: Profile preferences. None for defaults.
-  """
-  if chrome_options == None:
-    chrome_options = Options()
-
-  if incognito:
-    chrome_options.add_argument('incognito')
-
-  if prefs != None:
-    chrome_options.add_experimental_option("prefs", prefs)
-
-  os.environ["CHROME_LOG_FILE"] = r"c:\temp\chrome_log.txt"
-
-  return webdriver.Chrome(
-      executable_path=r"C:\temp\chromedriver.exe",
-      service_args=["--verbose", r"--log-path=c:\temp\chromedriver.log"],
-      chrome_options=chrome_options)
diff --git a/chrome/browser/policy/e2e_test/run_tests.py b/chrome/browser/policy/e2e_test/run_tests.py
deleted file mode 100644
index 220bc341..0000000
--- a/chrome/browser/policy/e2e_test/run_tests.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import os
-import sys
-from chrome_ent_test.infra.multi import ArgsParser, SimpleHostProvider, SharedHostProvider, MultiTestController
-import traceback
-import warnings
-
-# Import all known tests
-from tests import *
-
-
-def ParseArgs():
-  example = '%s --hosts ./hosts/' % sys.argv[0]
-
-  parser = argparse.ArgumentParser(
-      description='Test suite runner for CELab', epilog='example: %s' % example)
-
-  parser.add_argument(
-      '--hosts',
-      required=True,
-      metavar='<host_file;...>',
-      help='Full paths to *.host.textpb files to use for tests (or directory)')
-  parser.add_argument(
-      '--tests',
-      metavar='<test_class;...>',
-      default='*',
-      help='Fully qualified names of TestCases to run (supports my.package.*)')
-  parser.add_argument(
-      '--include',
-      metavar='<categoryA;...>',
-      default=None,
-      help='Categories of tests to include')
-  parser.add_argument(
-      '--exclude',
-      metavar='<categoryA;...>',
-      default=None,
-      help='Categories of tests to exclude')
-  parser.add_argument(
-      '--noprogress',
-      dest='show_progress',
-      default=True,
-      action='store_false',
-      help='Don\'t show progress while running tests')
-  parser.add_argument(
-      '--test_py',
-      dest='test_py',
-      default=os.path.join('test.py'),
-      help='Path to the script to use to launch a single test')
-  parser.add_argument(
-      '--test_py_args',
-      dest='test_py_args',
-      default=None,
-      help='Arguments to pass to the --test_py script.')
-  parser.add_argument(
-      '--shared_provider_storage',
-      metavar='<bucketName>',
-      dest='shared_provider_storage',
-      default=None,
-      action='store',
-      help='Where to store locks for the SharedHostProvider hosts')
-  parser.add_argument(
-      '--error_logs_dir',
-      metavar='<path>',
-      dest='error_logs_dir',
-      default=None,
-      action='store',
-      help='Where to collect extra logs on test failures')
-  parser.add_argument(
-      '-v',
-      '--verbosity',
-      dest='verbosity',
-      default=-1,
-      help='Logging verbosity level. Messages logged at this level or lower' +
-      'will be included. Set to 1 for debug logging.')
-
-  return parser.parse_args()
-
-
-def ConfigureLogging(args):
-  level = logging.WARNING
-  if args.verbosity == "0":
-    level = logging.INFO
-  if args.verbosity == "1":
-    level = logging.DEBUG
-
-  # Filter out logs from low level loggers
-  errorOnlyLoggers = ['googleapiclient', 'google.auth', 'google_auth_httplib2']
-  for logger in errorOnlyLoggers:
-    logging.getLogger(logger).setLevel(logging.ERROR)
-  message = 'We recommend that most server applications use service accounts.'
-  warnings.filterwarnings('ignore', '.*%s' % message)
-
-  logfmt = '%(asctime)s %(filename)s:%(lineno)s: [%(levelname)s] %(message)s'
-  datefmt = '%Y/%m/%d %H:%M:%S'
-
-  logging.basicConfig(level=level, format=logfmt, datefmt=datefmt)
-
-  logging.error("%s: Logging level error is visible." % __file__)
-  logging.warning("%s: Logging level warning is visible." % __file__)
-  logging.info("%s: Logging level info is visible." % __file__)
-  logging.debug("%s: Logging level debug is visible." % __file__)
-
-
-if __name__ == '__main__':
-  args = ParseArgs()
-
-  ConfigureLogging(args)
-
-  logging.info("Arguments: %s" % args)
-
-  tests = ArgsParser.ParseTestsArg(args.tests)
-  logging.debug('Found tests: %s', tests)
-
-  if args.include or args.exclude:
-    tests = ArgsParser.ProcessTestFilterArg(tests, args.include, args.exclude)
-    logging.debug('Got filtered tests: %s', tests)
-
-  hostFiles = ArgsParser.ParseHostsArg(args.hosts)
-  logging.debug('Found hosts: %s', hostFiles)
-
-  hostProvider = None
-  if args.shared_provider_storage == None:
-    hostProvider = SimpleHostProvider(hostFiles)
-  else:
-    hostProvider = SharedHostProvider(hostFiles, args.shared_provider_storage)
-
-  c = MultiTestController(tests, hostProvider, args.error_logs_dir)
-
-  success = False
-  try:
-    success = c.ExecuteTestCases(args.test_py, args.test_py_args,
-                                 args.show_progress)
-  except KeyboardInterrupt:
-    logging.error('Test run aborted.')
-    should_write_logs = False
-  except:
-    print(traceback.format_exc())
-    logging.error('Test run failed.')
-
-  sys.exit(0 if success else 1)
diff --git a/chrome/browser/policy/e2e_test/test.py b/chrome/browser/policy/e2e_test/test.py
deleted file mode 100644
index e07c078..0000000
--- a/chrome/browser/policy/e2e_test/test.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""The test runner that runs enterprise end-to-end tests."""
-
-import logging
-import sys
-import traceback
-import warnings
-from absl import app
-from absl import flags
-import chrome_ent_test.infra.controller as controller
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_string(
-    'test', None,
-    'The full class name of the EnterpriseTestCase class (w/ package)')
-flags.mark_flag_as_required('test')
-
-flags.DEFINE_string('test_filter', None,
-                    'The name of the test to run in the test class')
-
-flags.DEFINE_string('host', None,
-                    'The full path to the *.host.textpb file to use')
-flags.mark_flag_as_required('host')
-
-flags.DEFINE_string('cel_ctl', None,
-                    'Which binary to use to deploy the environment')
-flags.mark_flag_as_required('cel_ctl')
-
-flags.DEFINE_bool(
-    'deploy', True, 'Depoly the test environment. '
-    'Set to false to skip the deployment phase and go straight to tests')
-flags.DEFINE_bool(
-    'skip_before_all', False, 'True to skip @before_all methods. '
-    'Like --nodeploy, this is used to skip set up steps. '
-    'Useful when developing new tests.')
-flags.DEFINE_bool('cleanup', False,
-                  'Clean up the host environment after the test')
-flags.DEFINE_string('error_logs_dir', None,
-                    'Where to collect extra logs on test failures')
-flags.DEFINE_multi_string('test_arg', None, 'Flags passed to tests')
-
-
-def ConfigureLogging():
-  # Filter out logs from low level loggers
-  errorOnlyLoggers = [
-      'googleapiclient.discovery_cache', 'google.auth', 'google_auth_httplib2'
-  ]
-  for logger in errorOnlyLoggers:
-    logging.getLogger(logger).setLevel(logging.ERROR)
-  message = 'We recommend that most server applications use service accounts.'
-  warnings.filterwarnings('ignore', '.*%s' % message)
-
-  logging.error("%s: Logging level error is visible." % __file__)
-  logging.warning("%s: Logging level warning is visible." % __file__)
-  logging.info("%s: Logging level info is visible." % __file__)
-  logging.debug("%s: Logging level debug is visible." % __file__)
-
-
-def main(argv):
-  ConfigureLogging()
-
-  c = controller.SingleTestController(
-      FLAGS.test,
-      FLAGS.host,
-      FLAGS.cel_ctl,
-      test_filter=FLAGS.test_filter,
-      skip_before_all=FLAGS.skip_before_all)
-
-  # Parse test specific flags. Note that we need to use a dummy element
-  # as the first element of the list since absl.flags ignores the first element
-  # during parsing.
-  if FLAGS.test_arg is not None:
-    FLAGS([''] + FLAGS.test_arg)
-
-  success = False
-  should_write_logs = (FLAGS.error_logs_dir != None)
-  try:
-    if FLAGS.deploy:
-      c.DeployNewEnvironment()
-
-    success = c.ExecuteTestCase()
-  except KeyboardInterrupt:
-    logging.error('Test aborted.')
-  except:
-    print(traceback.format_exc())
-    logging.error('Test failed.')
-  finally:
-    if not success and should_write_logs:
-      print('Writing Compute logs to "%s"...' % FLAGS.error_logs_dir)
-      c.TryWriteComputeLogsTo(FLAGS.error_logs_dir)
-
-    if FLAGS.cleanup:
-      print('Cleaning up host environment...')
-      c.TryCleanHostEnvironment()
-
-  sys.exit(0 if success else 1)
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/__init__.py b/chrome/browser/policy/e2e_test/tests/__init__.py
deleted file mode 100644
index a30f476..0000000
--- a/chrome/browser/policy/e2e_test/tests/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from allow_deleting_browser_history.allow_deleting_browser_history import *
-from apps_shortcut.apps_shortcut import *
-from bookmarkbar_enabled.bookmarkbar_enabled import *
-from cloud_management_enrollment_token.cloud_management_enrollment_token import *
-from default_search_provider.default_search_provider import *
-from extension_blacklist.extension_blacklist import *
-from extension_forcelist.extension_forcelist import *
-from extension_whitelist.extension_whitelist import *
-from force_google_safe_search.force_google_safe_search import *
-from fullscreen_allowed.fullscreen_allowed import *
-from homepage.homepage import *
-from password_manager_enabled.password_manager_enabled import *
-from popups_allowed.popups_allowed import *
-from restore_on_startup.restore_on_startup import *
-from safe_browsing.safe_browsing import *
-from translate_enabled.translate_enabled import *
-from url_blacklist.url_blacklist import *
-from url_whitelist.url_whitelist import *
-from user_data_dir.user_data_dir import *
-from youtube_restrict.youtube_restrict import *
diff --git a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/__init__.py b/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py b/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py
deleted file mode 100644
index 2a22c622..0000000
--- a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from chrome_ent_test.infra.core import before_all, environment, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class AllowDeletingBrowserHistory(ChromeEnterpriseTestCase):
-  """Test the AllowDeletingBrowserHistory policy:
-
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=AllowDeletingBrowserHistory.
-    """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def allowDeletingBrowserHistoryEnabled(self, instance_name):
-    """Returns true if AllowDeletingBrowserHistory is enabled."""
-    directory = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012',
-        os.path.join(directory,
-                     'allow_deleting_browser_history_webdriver_test.py'))
-    return 'ENABLED' in output
-
-  @test
-  def test_allow_deleting_browser_history_enabled(self):
-    self.SetPolicy('win2012-dc', r'AllowDeletingBrowserHistory', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    policy_enabled = self.allowDeletingBrowserHistoryEnabled('client2012')
-    self.assertTrue(policy_enabled)
-
-  @test
-  def test_allow_deleting_browser_history_disabled(self):
-    self.SetPolicy('win2012-dc', r'AllowDeletingBrowserHistory', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    policy_enabled = self.allowDeletingBrowserHistoryEnabled('client2012')
-    self.assertFalse(policy_enabled)
diff --git a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history_webdriver_test.py
deleted file mode 100644
index d4dbb1b..0000000
--- a/chrome/browser/policy/e2e_test/tests/allow_deleting_browser_history/allow_deleting_browser_history_webdriver_test.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from absl import app
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support import expected_conditions
-from selenium.webdriver.support.ui import WebDriverWait
-
-import test_util
-
-# Detect if history deletion is enabled or disabled and print the result.
-
-# The way to check is:
-# - visit chrome://history;
-# - get the first history item;
-# - check the checkbox. If history deletion is disabled, then the check
-#   box has attribute 'disabled';
-
-
-# TODO(crbug.com/986444): move those helper methods into test_util.py once
-# it's moved from CELab into Chromium.
-def getShadowRoot(driver, element):
-  return driver.execute_script("return arguments[0].shadowRoot", element)
-
-
-def getShadowDom(driver, root, selector):
-  el = root.find_element_by_css_selector(selector)
-  return getShadowRoot(driver, el)
-
-
-def getNestedShadowDom(driver, selectors):
-  el = driver
-  for selector in selectors:
-    el = getShadowDom(driver, el, selector)
-  return el
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver()
-
-  try:
-    driver.get('http://www.google.com')
-    driver.get('chrome://history')
-
-    # wait for page to be loaded
-    wait = WebDriverWait(driver, 10)
-    wait.until(
-        expected_conditions.visibility_of_element_located((By.TAG_NAME,
-                                                           'history-app')))
-
-    histroy_list = getNestedShadowDom(driver, ["history-app", "history-list"])
-
-    # get the checkbox of the first history item
-    histroy_item = histroy_list.find_elements_by_css_selector('history-item')[0]
-    checkbox = getShadowRoot(driver, histroy_item).find_element_by_css_selector(
-        '#main-container cr-checkbox')
-
-    disabled = checkbox.get_attribute('disabled')
-    if disabled == 'true':
-      print 'DISABLED'
-    else:
-      print 'ENABLED'
-
-  finally:
-    driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/apps_shortcut/__init__.py b/chrome/browser/policy/e2e_test/tests/apps_shortcut/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/apps_shortcut/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/apps_shortcut/apps_shortcut.py b/chrome/browser/policy/e2e_test/tests/apps_shortcut/apps_shortcut.py
deleted file mode 100644
index 1970103..0000000
--- a/chrome/browser/policy/e2e_test/tests/apps_shortcut/apps_shortcut.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class AppsShortcutEnabledTest(ChromeEnterpriseTestCase):
-  """Test the ShowAppsShortcutInBookmarkBar policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ShowAppsShortcutInBookmarkBar"""
-
-  Policy = 'ShowAppsShortcutInBookmarkBar'
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-    # Enable the bookmark bar so we can see the Apps Shortcut that lives there.
-    self.SetPolicy('win2012-dc', 'BookmarkBarEnabled', 1, 'DWORD')
-
-  def isAppsShortcutVisible(self, instance):
-    local = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(instance,
-                            os.path.join(local, 'is_apps_shortcut_visible.py'))
-    return "TRUE" in output
-
-  @test
-  def test_AppShortcutEnabled(self):
-    self.SetPolicy('win2012-dc', AppsShortcutEnabledTest.Policy, 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    visible = self.isAppsShortcutVisible('client2012')
-    self.assertTrue(visible)
-
-  @test
-  def test_AppShortcutDisabled(self):
-    self.SetPolicy('win2012-dc', AppsShortcutEnabledTest.Policy, 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    visible = self.isAppsShortcutVisible('client2012')
-    self.assertFalse(visible)
diff --git a/chrome/browser/policy/e2e_test/tests/apps_shortcut/is_apps_shortcut_visible.py b/chrome/browser/policy/e2e_test/tests/apps_shortcut/is_apps_shortcut_visible.py
deleted file mode 100644
index 19af716..0000000
--- a/chrome/browser/policy/e2e_test/tests/apps_shortcut/is_apps_shortcut_visible.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import test_util
-from absl import app
-from pywinauto.application import Application
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver()
-  try:
-    application = Application(backend="uia")
-    application.connect(title_re='.*Chrome|.*Chromium')
-
-    print "Looking for apps shortcut..."
-    for desc in application.top_window().descendants():
-      print desc.window_text()
-      if "Apps" == desc.window_text():
-        print "TRUE"
-        return
-
-    print "FALSE"
-  finally:
-    driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/__init__.py b/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_enabled.py b/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_enabled.py
deleted file mode 100644
index b33de5d2..0000000
--- a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_enabled.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from absl import flags
-
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-FLAGS = flags.FLAGS
-
-
-@environment(file="../policy_test.asset.textpb")
-class BookmarkBarEnabledTest(ChromeEnterpriseTestCase):
-  """Test the BookmarkBarEnabled
-
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=BookmarkBarEnabled.
-
-    If this setting is left not set the user can decide to use this function
-    or not.
-    """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-  def _getUIStructure(self, instance_name):
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(instance_name,
-                            os.path.join(local_dir, 'bookmarkbar_webdriver.py'))
-    return output
-
-  @test
-  def test_bookmark_bar_enabled(self):
-    # Enable bookmark bar
-    self.SetPolicy('win2012-dc', r'BookmarkBarEnabled', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Enabled bookmark bar')
-
-    output = self._getUIStructure('client2012')
-    self.assertIn('Bookmarkbar is found', output)
-
-  @test
-  def test_bookmark_bar_disabled(self):
-    # Disable bookmark bar
-    self.SetPolicy('win2012-dc', r'BookmarkBarEnabled', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Disabled bookmark bar')
-
-    output = self._getUIStructure('client2012')
-    self.assertIn('Bookmarkbar is missing', output)
diff --git a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_webdriver.py b/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_webdriver.py
deleted file mode 100644
index 76d089f..0000000
--- a/chrome/browser/policy/e2e_test/tests/bookmarkbar_enabled/bookmarkbar_webdriver.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pywinauto.application import Application
-from pywinauto.findwindows import ElementNotFoundError
-from selenium import webdriver
-
-import test_util
-
-options = webdriver.ChromeOptions()
-options.add_argument("--force-renderer-accessibility")
-
-driver = test_util.create_chrome_webdriver(chrome_options=options)
-
-try:
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-  app.top_window().child_window(title="Bookmarks", control_type="ToolBar") \
-      .print_control_identifiers()
-  print "Bookmarkbar is found"
-except ElementNotFoundError as error:
-  print error
-  print "Bookmarkbar is missing"
-finally:
-  driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/__init__.py b/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_enrollment_webdriver.py b/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_enrollment_webdriver.py
deleted file mode 100644
index 2811adf..0000000
--- a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_enrollment_webdriver.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from absl import app
-import time
-from selenium import webdriver
-import test_util
-
-
-def main(argv):
-  options = webdriver.ChromeOptions()
-  # Add option for enrolling to the dev DMServer
-  options.add_argument(
-      "device-management-url=https://crosman-qa.sandbox.google.com/devicemanagement/data/api"
-  )
-  os.environ["CHROME_LOG_FILE"] = r"c:\temp\chrome_log.txt"
-  driver = test_util.create_chrome_webdriver(chrome_options=options)
-
-  # Give some time for browser to enroll
-  time.sleep(10)
-
-  try:
-    # Verify Policy status legend in chrome://policy page
-    policy_url = "chrome://policy"
-    driver.get(policy_url)
-    driver.find_element_by_id('reload-policies').click
-    print driver.find_element_by_class_name('legend').text
-    print driver.find_element_by_class_name('machine-enrollment-name').text
-    print driver.find_element_by_class_name('machine-enrollment-token').text
-    print driver.find_element_by_class_name('status').text
-  except Exception as error:
-    print error
-  finally:
-    driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_management_enrollment_token.py b/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_management_enrollment_token.py
deleted file mode 100644
index eb7bbdc..0000000
--- a/chrome/browser/policy/e2e_test/tests/cloud_management_enrollment_token/cloud_management_enrollment_token.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from infra import ChromeEnterpriseTestCase
-from chrome_ent_test.infra.core import before_all, category, environment, test
-
-
-@category("chrome_only")
-@environment(file="../policy_test.asset.textpb")
-class CloudManagementEnrollmentTokenTest(ChromeEnterpriseTestCase):
-  """Test the CloudManagementEnrollmentToken policy:
-  https://cloud.google.com/docs/chrome-enterprise/policies/?policy=CloudManagementEnrollmentToken."""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  @test
-  def test_browser_enrolled(self):
-    path = "gs://%s/secrets/enrollToken" % self.gsbucket
-    cmd = r'gsutil cat ' + path
-    token = self.RunCommand('win2012-dc', cmd).rstrip()
-    self.SetPolicy('win2012-dc', r'CloudManagementEnrollmentToken', token,
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(local_dir, 'cloud_enrollment_webdriver.py'))
-    # Verify CBCM status legend
-    self.assertIn('Machine policies', output)
-    self.assertIn('CLIENT2012', output)
-    self.assertIn(token, output)
-    self.assertIn('Policy cache OK', output)
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py
deleted file mode 100644
index e216935..0000000
--- a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class DefaultSearchProviderTest(ChromeEnterpriseTestCase):
-  """Test the DefaultSearchProviderEnabled,
-              DefaultSearchProviderName,
-              DefaultSearchProviderSearchURL
-
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderEnabled
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderName
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderSearchURL
-
-    """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-  def _get_search_url(self, instance_name):
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(
-        instance_name,
-        os.path.join(local_dir, 'default_search_provider_webdriver.py'))
-    return output
-
-  @test
-  def test_default_search_provider_bing(self):
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 1, 'DWORD')
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderName', 'Bing', 'String')
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderSearchURL',
-                   '"https://www.bing.com/search?q={searchTerms}"', 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self._get_search_url('client2012')
-    self.assertIn('www.bing.com', output)
-
-  @test
-  def test_default_search_provider_yahoo(self):
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 1, 'DWORD')
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderName', 'Yahoo', 'String')
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderSearchURL',
-                   '"https://search.yahoo.com/search?p={searchTerms}"',
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self._get_search_url('client2012')
-    self.assertIn('search.yahoo.com', output)
-
-  @test
-  def test_default_search_provider_disabled(self):
-    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self._get_search_url('client2012')
-    self.assertIn('http://anything', output)
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py
deleted file mode 100644
index 6a7684d..0000000
--- a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pywinauto.application import Application
-from selenium import webdriver
-
-import test_util
-
-# Set up ChromeDriver
-options = webdriver.ChromeOptions()
-options.add_argument("--force-renderer-accessibility")
-
-driver = test_util.create_chrome_webdriver(chrome_options=options)
-
-try:
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-  omnibox = app.top_window() \
-            .child_window(title="Address and search bar", control_type="Edit")
-  omnibox.set_edit_text('anything').type_keys('{ENTER}')
-  print driver.current_url
-except Exception as error:
-  print error
-finally:
-  driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/extension_blacklist/__init__.py b/chrome/browser/policy/e2e_test/tests/extension_blacklist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_blacklist/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/extension_blacklist/extension_blacklist.py b/chrome/browser/policy/e2e_test/tests/extension_blacklist/extension_blacklist.py
deleted file mode 100644
index d14b00fa..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_blacklist/extension_blacklist.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class ExtensionInstallBlacklistTest(ChromeEnterpriseTestCase):
-  """Test the ExtensionInstallBlacklist policy.
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExtensionInstallBlacklist"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def installExtension(self, url):
-    args = ['--url', url, '--text_only', '--wait', '5']
-
-    dir = os.path.dirname(os.path.abspath(__file__))
-    logging.info('Opening page: %s' % url)
-    output = self.RunWebDriverTest('client2012',
-                                   os.path.join(dir, '../install_extension.py'),
-                                   args)
-    return output
-
-  @test
-  def test_ExtensionBlacklist_all(self):
-    extension = '*'
-    self.SetPolicy('win2012-dc', r'ExtensionInstallBlacklist\1', extension,
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Disabled extension install for ' + extension)
-
-    test_url = 'https://chrome.google.com/webstore/detail/google-hangouts/nckgahadagoaajjgafhacjanaoiihapd'
-    output = self.installExtension(test_url)
-    self.assertIn('blocked', output)
-
-  @test
-  def test_ExtensionBlacklist_hangout(self):
-    extension = 'nckgahadagoaajjgafhacjanaoiihapd'
-    self.SetPolicy('win2012-dc', r'ExtensionInstallBlacklist\1', extension,
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Disabled extension install for ' + extension)
-
-    test_url = 'https://chrome.google.com/webstore/detail/google-hangouts/nckgahadagoaajjgafhacjanaoiihapd'
-    output = self.installExtension(test_url)
-    self.assertIn('blocked', output)
-
-    positive_test_url = 'https://chrome.google.com/webstore/detail/grammarly-for-chrome/kbfnbcaeplbcioakkpcpgfkobkghlhen'
-    output = self.installExtension(positive_test_url)
-    self.assertNotIn('blocked', output)
diff --git a/chrome/browser/policy/e2e_test/tests/extension_forcelist/__init__.py b/chrome/browser/policy/e2e_test/tests/extension_forcelist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_forcelist/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/extension_forcelist/extension_forcelist.py b/chrome/browser/policy/e2e_test/tests/extension_forcelist/extension_forcelist.py
deleted file mode 100644
index 546d176f..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_forcelist/extension_forcelist.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class ExtensionInstallForcelistTest(ChromeEnterpriseTestCase):
-  """Test the ExtensionInstallForcelist policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExtensionInstallForcelist"""
-
-  # This is the extension id of the Google Keep extension.
-  ExtensionId = 'lpcaedmchfhocbbapmcbpinfpgnhiddi'
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def isExtensionInstalled(self, incognito=False):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012',
-        os.path.join(dir, 'is_extension_installed.py'),
-        args=["--extension_id", ExtensionInstallForcelistTest.ExtensionId])
-
-    if "ERROR" in output:
-      raise Exception(
-          "is_extension_installed.py returned an error: %s" % output)
-
-    return "TRUE" in output
-
-  @test
-  def test_NoForcelistNoExtensionInstalled(self):
-    self.SetPolicy('win2012-dc', r'ExtensionInstallForcelist\1', '""', 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    installed = self.isExtensionInstalled()
-    self.assertFalse(installed)
-
-  @test
-  def test_ForcelistExtensionInstalled(self):
-    url = 'https://clients2.google.com/service/update2/crx'
-    extension = '"%s;%s"' % (ExtensionInstallForcelistTest.ExtensionId, url)
-    self.SetPolicy('win2012-dc', r'ExtensionInstallForcelist\1', extension,
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    installed = self.isExtensionInstalled()
-    self.assertTrue(installed)
diff --git a/chrome/browser/policy/e2e_test/tests/extension_forcelist/is_extension_installed.py b/chrome/browser/policy/e2e_test/tests/extension_forcelist/is_extension_installed.py
deleted file mode 100644
index 2bf876f..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_forcelist/is_extension_installed.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import test_util
-import time
-import traceback
-from absl import app, flags
-from selenium import webdriver
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_string('extension_id', None,
-                    'The id of the extension to look for.')
-flags.mark_flag_as_required('extension_id')
-
-
-def getShadowDom(driver, root, selector):
-  el = root.find_element_by_css_selector(selector)
-  return driver.execute_script("return arguments[0].shadowRoot", el)
-
-
-def getNestedShadowDom(driver, selectors):
-  el = driver
-  for selector in selectors:
-    el = getShadowDom(driver, el, selector)
-    if el == None:
-      return None
-  return el
-
-
-def RunTest(driver):
-  # The extension must be visible on the extensions page.
-  driver.get("chrome://extensions")
-
-  # It's nested within a couple of shadow doms on the page - extract it.
-  print "Looking for extension on extensions page: %s" % FLAGS.extension_id
-  extension_page = False
-  try:
-    selectors = ["extensions-manager", "extensions-item-list"]
-    el = getNestedShadowDom(driver, selectors)
-    el = el.find_element_by_css_selector(
-        "extensions-item#%s" % FLAGS.extension_id)
-    extension_page = (el != None)
-  except:
-    print(traceback.format_exc())
-
-  if extension_page:
-    print "TRUE"
-  else:
-    print "FALSE"
-
-
-def main(argv):
-  try:
-    chrome_options = webdriver.ChromeOptions()
-    chrome_options.add_experimental_option("excludeSwitches",
-                                           ["disable-background-networking"])
-
-    driver = test_util.create_chrome_webdriver(chrome_options=chrome_options)
-
-    # Wait for the extension to install on this new profile.
-    time.sleep(10)
-
-    RunTest(driver)
-  finally:
-    driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/extension_whitelist/__init__.py b/chrome/browser/policy/e2e_test/tests/extension_whitelist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_whitelist/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/extension_whitelist/extension_whitelist.py b/chrome/browser/policy/e2e_test/tests/extension_whitelist/extension_whitelist.py
deleted file mode 100644
index c4e48dc9..0000000
--- a/chrome/browser/policy/e2e_test/tests/extension_whitelist/extension_whitelist.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class ExtensionInstallWhitelistTest(ChromeEnterpriseTestCase):
-  """Test the ExtensionInstallBlacklist policy.
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExtensionInstallWhitelist"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def installExtension(self, url):
-    args = ['--url', url, '--text_only', '--wait', '5']
-
-    dir = os.path.dirname(os.path.abspath(__file__))
-    logging.info('Opening page: %s' % url)
-    output = self.RunWebDriverTest('client2012',
-                                   os.path.join(dir, '../install_extension.py'),
-                                   args)
-    return output
-
-  @test
-  def test_ExtensionWhitelist_hangout(self):
-    extension = 'nckgahadagoaajjgafhacjanaoiihapd'
-    self.SetPolicy('win2012-dc', r'ExtensionInstallBlacklist\1', '*', 'String')
-    self.SetPolicy('win2012-dc', r'ExtensionInstallWhitelist\1', extension,
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Whitelist extension install for ' + extension +
-                 ' while disabling others')
-
-    test_url = 'https://chrome.google.com/webstore/detail/google-hangouts/nckgahadagoaajjgafhacjanaoiihapd'
-    output = self.installExtension(test_url)
-    self.assertNotIn('blocked', output)
-
-    negative_test_url = 'https://chrome.google.com/webstore/detail/grammarly-for-chrome/kbfnbcaeplbcioakkpcpgfkobkghlhen'
-    output = self.installExtension(negative_test_url)
-    self.assertIn('blocked', output)
\ No newline at end of file
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py
deleted file mode 100644
index 7955660..0000000
--- a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import logging
-from absl import flags
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-FLAGS = flags.FLAGS
-
-
-@environment(file="../policy_test.asset.textpb")
-class ForceGoogleSafeSearchTest(ChromeEnterpriseTestCase):
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  @test
-  def test_ForceGoogleSafeSearchEnabled(self):
-    # enable policy ForceGoogleSafeSearch
-    self.SetPolicy('win2012-dc', 'ForceGoogleSafeSearch', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('ForceGoogleSafeSearch ENABLED')
-    d = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012',
-        os.path.join(d, 'force_google_safe_search_webdriver_test.py'))
-    logging.info('url used: %s', output)
-
-    # assert that safe search is enabled
-    self.assertIn('safe=active', output)
-    self.assertIn('ssui=on', output)
-
-  @test
-  def test_ForceGoogleSafeSearchDisabled(self):
-    # disable policy ForceGoogleSafeSearch
-    self.SetPolicy('win2012-dc', 'ForceGoogleSafeSearch', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-    d = os.path.dirname(os.path.abspath(__file__))
-    logging.info('ForceGoogleSafeSearch DISABLED')
-    output = self.RunWebDriverTest(
-        'client2012',
-        os.path.join(d, 'force_google_safe_search_webdriver_test.py'))
-    logging.info('url used: %s', output)
-
-    # assert that safe search is NOT enabled
-    self.assertNotIn('safe=active', output)
-    self.assertNotIn('ssui=on', output)
diff --git a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py
deleted file mode 100644
index 078225e..0000000
--- a/chrome/browser/policy/e2e_test/tests/force_google_safe_search/force_google_safe_search_webdriver_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support import expected_conditions as EC
-from selenium.webdriver.support.ui import WebDriverWait
-
-import test_util
-
-driver = test_util.create_chrome_webdriver()
-driver.get('http://www.google.com/xhtml')
-
-# wait for page to be loaded
-wait = WebDriverWait(driver, 10)
-wait.until(EC.visibility_of_element_located((By.NAME, 'q')))
-
-search_box = driver.find_element_by_name('q')
-search_box.send_keys('searchTerm')
-search_box.submit()
-
-# wait for the search result page to be loaded
-wait.until(EC.visibility_of_element_located((By.ID, 'search')))
-
-print driver.current_url
-driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/__init__.py b/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/fullscreen_allowed.py b/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/fullscreen_allowed.py
deleted file mode 100644
index ce66eef7..0000000
--- a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/fullscreen_allowed.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class FullscreenAllowedTest(ChromeEnterpriseTestCase):
-  """Test the FullscreenAllowed policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=FullscreenAllowed"""
-
-  Policy = 'FullscreenAllowed'
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-    # Enable the bookmark bar so we can see the Apps Shortcut that lives there.
-    self.SetPolicy('win2012-dc', 'BookmarkBarEnabled', 1, 'DWORD')
-
-  def isFullscreenAllowed(self, instance):
-    local = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(instance,
-                            os.path.join(local, 'is_fullscreen_allowed.py'))
-    return "FullscreenAllowed: True" in output
-
-  @test
-  def test_FullscreenAllowed(self):
-    self.SetPolicy('win2012-dc', FullscreenAllowedTest.Policy, 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    allowed = self.isFullscreenAllowed('client2012')
-    self.assertTrue(allowed)
-
-  @test
-  def test_FullscreenNotAllowed(self):
-    self.SetPolicy('win2012-dc', FullscreenAllowedTest.Policy, 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    allowed = self.isFullscreenAllowed('client2012')
-    self.assertFalse(allowed)
diff --git a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/is_fullscreen_allowed.py b/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/is_fullscreen_allowed.py
deleted file mode 100644
index c4891c3..0000000
--- a/chrome/browser/policy/e2e_test/tests/fullscreen_allowed/is_fullscreen_allowed.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import test_util
-from absl import app
-from pywinauto.application import Application
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver()
-  try:
-    application = Application(backend="uia")
-    application.connect(title_re='.*Chrome|.*Chromium')
-    w = application.top_window()
-
-    for desc in w.descendants():
-      print "item: %s" % desc
-
-    print "Closing info bar."
-    container = w.child_window(best_match="Infobar Container")
-    container.child_window(best_match="Close").click_input()
-
-    print "Clicking on the Fullscreen button."
-    button = w.child_window(title_re="^Chrom(e|ium)$", control_type="Button")
-    button.click_input()
-    w.child_window(best_match="Full screen").click_input()
-
-    window_rect = w.rectangle()
-    window_width = window_rect.width()
-    window_height = window_rect.height()
-    content_width = driver.execute_script("return window.innerWidth")
-    content_height = driver.execute_script("return window.innerHeight")
-
-    # The content area should be the same size as the full window.
-    print "window_rect: %s" % window_rect
-    print "window_width: %s" % window_width
-    print "window_height: %s" % window_height
-    print "content_width: %s" % content_width
-    print "content_height: %s" % content_height
-
-    fs = window_width == content_width and window_height == content_height
-    print "FullscreenAllowed: %s" % fs
-  finally:
-    driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/homepage/__init__.py b/chrome/browser/policy/e2e_test/tests/homepage/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/homepage/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/homepage/get_home_button.py b/chrome/browser/policy/e2e_test/tests/homepage/get_home_button.py
deleted file mode 100644
index c34b2774..0000000
--- a/chrome/browser/policy/e2e_test/tests/homepage/get_home_button.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pywinauto.application import Application
-import test_util
-
-# Print 'home button exists' if the home button exists.
-
-driver = test_util.create_chrome_webdriver()
-
-try:
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-
-  home_button = app.top_window().child_window(
-      title="Home", control_type="Button")
-  if home_button.exists(timeout=1):
-    print 'home button exists'
-
-finally:
-  driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/homepage/get_homepage_url.py b/chrome/browser/policy/e2e_test/tests/homepage/get_homepage_url.py
deleted file mode 100644
index af07d707..0000000
--- a/chrome/browser/policy/e2e_test/tests/homepage/get_homepage_url.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pywinauto.application import Application
-
-import test_util
-
-driver = test_util.create_chrome_webdriver()
-
-try:
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-
-  # Use shortcut Alt+HOME to go to the home page
-  app.top_window().type_keys("%{HOME}")
-
-  print 'homepage:%s' % driver.current_url
-finally:
-  driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/homepage/homepage.py b/chrome/browser/policy/e2e_test/tests/homepage/homepage.py
deleted file mode 100644
index de0b63a2..0000000
--- a/chrome/browser/policy/e2e_test/tests/homepage/homepage.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (c) 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import logging
-import re
-from absl import flags
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-FLAGS = flags.FLAGS
-
-
-@environment(file="../policy_test.asset.textpb")
-class HomepageTest(ChromeEnterpriseTestCase):
-  """Test HomepageIsNewTabPage and HomepageLocation policies.
-
-  See:
-     https://cloud.google.com/docs/chrome-enterprise/policies/?policy=HomepageLocation
-     https://cloud.google.com/docs/chrome-enterprise/policies/?policy=HomepageIsNewTabPage
-     https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ShowHomeButton
-  """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-  def _getHomepageLocation(self, instance_name):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(instance_name,
-                            os.path.join(dir, 'get_homepage_url.py'))
-    m = re.search(r"homepage:([^ \r\n]+)", output)
-    return m.group(1)
-
-  def _isHomeButtonShown(self, instance_name):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(instance_name,
-                            os.path.join(dir, 'get_home_button.py'))
-    return 'home button exists' in output
-
-  @test
-  def test_HomepageLocation(self):
-    # Test the case where
-    # -  HomepageIsNewTabPage is false
-    # -  HomepageLocation is set
-    # In this case, when a home page is opened, the HomepageLocation is used
-    self.SetPolicy('win2012-dc', 'HomepageIsNewTabPage', 0, 'DWORD')
-    self.SetPolicy('win2012-dc', 'HomepageLocation',
-                   '"http://www.example.com/"', 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    # verify the home page is the value of HomepageLocation
-    homepage = self._getHomepageLocation('client2012')
-    self.assertEqual(homepage, 'http://www.example.com/')
-
-  @test
-  def test_HomepageIsNewTab(self):
-    # Test the case when HomepageIsNewTabPage is true
-    # In this case, when a home page is opened, the new tab page will be used.
-    self.SetPolicy('win2012-dc', 'HomepageIsNewTabPage', 1, 'DWORD')
-    self.SetPolicy('win2012-dc', 'HomepageLocation',
-                   '"http://www.example.com/"', 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    # verify that the home page is the new tab page.
-    homepage = self._getHomepageLocation('client2012')
-
-    # The URL of the new tab can be one of the following:
-    # - https://www.google.com/_/chrome/newtab?ie=UTF-8
-    # - chrome://newtab
-    # - chrome-search://local-ntp/local-ntp.html
-    if ('newtab' in homepage
-       ) or homepage == 'chrome-search://local-ntp/local-ntp.html':
-      pass
-    else:
-      self.fail('homepage url is not new tab: %s' % homepage)
-
-  @test
-  def test_ShowHomeButton(self):
-    # Test the case when ShowHomeButton is true
-    self.SetPolicy('win2012-dc', 'ShowHomeButton', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    isHomeButtonShown = self._isHomeButtonShown('client2012')
-    self.assertTrue(isHomeButtonShown)
-
-    # Test the case when ShowHomeButton is false
-    self.SetPolicy('win2012-dc', 'ShowHomeButton', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    isHomeButtonShown = self._isHomeButtonShown('client2012')
-    self.assertFalse(isHomeButtonShown)
diff --git a/chrome/browser/policy/e2e_test/tests/install_extension.py b/chrome/browser/policy/e2e_test/tests/install_extension.py
deleted file mode 100644
index fd22bdb..0000000
--- a/chrome/browser/policy/e2e_test/tests/install_extension.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from absl import app, flags
-from selenium import webdriver
-
-import test_util
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_string('url', None, 'The url to open in Chrome.')
-flags.mark_flag_as_required('url')
-
-flags.DEFINE_integer(
-    'wait', 0,
-    'How many seconds to wait between loading the page and printing the source.'
-)
-
-flags.DEFINE_bool('incognito', False,
-                  'Set flag to open Chrome in incognito mode.')
-
-flags.DEFINE_bool(
-    'text_only', False,
-    'Set flag to print only page text (defaults to full source).')
-
-
-def main(argv):
-  chrome_options = webdriver.ChromeOptions()
-
-  if FLAGS.incognito:
-    chrome_options.add_argument('incognito')
-
-  #Always set useAutomationExtension as false to avoid failing launch Chrome
-  #https://bugs.chromium.org/p/chromedriver/issues/detail?id=2930
-  chrome_options.add_experimental_option("useAutomationExtension", False)
-
-  driver = test_util.create_chrome_webdriver(chrome_options=chrome_options)
-  driver.implicitly_wait(FLAGS.wait)
-  driver.get(FLAGS.url)
-
-  driver.find_element_by_xpath("//div[@aria-label='Add to Chrome']").click()
-  if FLAGS.wait > 0:
-    time.sleep(FLAGS.wait)
-
-  if FLAGS.text_only:
-    print driver.find_element_by_css_selector('html').text.encode('utf-8')
-  else:
-    print driver.page_source.encode('utf-8')
-
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/open_page.py b/chrome/browser/policy/e2e_test/tests/open_page.py
deleted file mode 100644
index d54237a..0000000
--- a/chrome/browser/policy/e2e_test/tests/open_page.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import test_util
-import time
-from absl import app, flags
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_string('url', None, 'The url to open in Chrome.')
-flags.mark_flag_as_required('url')
-
-flags.DEFINE_integer(
-    'wait', 0,
-    'How many seconds to wait between loading the page and printing the source.'
-)
-
-flags.DEFINE_bool('incognito', False,
-                  'Set flag to open Chrome in incognito mode.')
-
-flags.DEFINE_bool(
-    'text_only', False,
-    'Set flag to print only page text (defaults to full source).')
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver(incognito=FLAGS.incognito)
-  driver.get(FLAGS.url)
-
-  if FLAGS.wait > 0:
-    time.sleep(FLAGS.wait)
-
-  if FLAGS.text_only:
-    print driver.find_element_by_css_selector('html').text.encode('utf-8')
-  else:
-    print driver.page_source.encode('utf-8')
-
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/__init__.py b/chrome/browser/policy/e2e_test/tests/password_manager_enabled/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled.py b/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled.py
deleted file mode 100644
index a747fcf6..0000000
--- a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class PasswordManagerEnabledTest(ChromeEnterpriseTestCase):
-  """Test the PasswordManagerEnabled policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=PasswordManagerEnabled"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def isPasswordManagerEnabled(self):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012',
-        os.path.join(dir, 'password_manager_enabled_webdriver_test.py'))
-    return "TRUE" in output
-
-  @test
-  def test_PasswordManagerDisabled(self):
-    self.SetPolicy('win2012-dc', 'PasswordManagerEnabled', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    enabled = self.isPasswordManagerEnabled()
-    self.assertFalse(enabled)
-
-  @test
-  def test_PasswordManagerEnabled(self):
-    self.SetPolicy('win2012-dc', 'PasswordManagerEnabled', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    enabled = self.isPasswordManagerEnabled()
-    self.assertTrue(enabled)
diff --git a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled_webdriver_test.py
deleted file mode 100644
index 320d5a0..0000000
--- a/chrome/browser/policy/e2e_test/tests/password_manager_enabled/password_manager_enabled_webdriver_test.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import test_util
-from absl import app
-
-
-def getShadowDom(driver, root, selector):
-  el = root.find_element_by_css_selector(selector)
-  return driver.execute_script("return arguments[0].shadowRoot", el)
-
-
-def getNestedShadowDom(driver, selectors):
-  el = driver
-  for selector in selectors:
-    el = getShadowDom(driver, el, selector)
-  return el
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver()
-  driver.get("chrome://settings/passwords")
-
-  # The settings is nested within multiple shadow doms - extract it.
-  el = getNestedShadowDom(driver, [
-      "settings-ui", "settings-main", "settings-basic-page",
-      "settings-autofill-page", "passwords-section", "#passwordToggle"
-  ])
-
-  if el.find_element_by_css_selector("cr-toggle").get_attribute("checked"):
-    print "TRUE"
-  else:
-    print "FALSE"
-
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb b/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb
deleted file mode 100644
index 978fc119..0000000
--- a/chrome/browser/policy/e2e_test/tests/policy_test.asset.textpb
+++ /dev/null
@@ -1,29 +0,0 @@
-# The test configuration used by most policy tests.

-# It consists of one domain controller and one client.

-network {

-  name: 'primary'

-}

-

-# An ActiveDirectory domain.

-ad_domain {

-  name: 'test1.com'

-  netbios_name: 'example'

-

-  domain_controller {

-    windows_machine: 'win2012-dc'

-  }

-}

-

-# the domain controller.

-windows_machine {

-  name: 'win2012-dc'

-  machine_type: 'win2012r2'

-  network_interface { network: 'primary' }

-}

-

-windows_machine {

-  name: 'client2012'

-  machine_type: 'win2012r2'

-  network_interface { network: 'primary' }

-  container { ad_domain: 'test1.com' }

-}
\ No newline at end of file
diff --git a/chrome/browser/policy/e2e_test/tests/popups_allowed/__init__.py b/chrome/browser/policy/e2e_test/tests/popups_allowed/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/popups_allowed/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/popups_allowed/popup_allowed_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/popups_allowed/popup_allowed_webdriver_test.py
deleted file mode 100644
index 9a76f6c..0000000
--- a/chrome/browser/policy/e2e_test/tests/popups_allowed/popup_allowed_webdriver_test.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from absl import app
-from selenium import webdriver
-
-import test_util
-
-
-def main(argv):
-  testSite = "http://www.dummysoftware.com/popupdummy_testpage.html"
-  options = webdriver.ChromeOptions()
-  options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
-  driver = test_util.create_chrome_webdriver(chrome_options=options)
-  driver.implicitly_wait(5)
-  driver.get(testSite)
-  handles = driver.window_handles
-  print len(handles)
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/popups_allowed/popups_allowed.py b/chrome/browser/policy/e2e_test/tests/popups_allowed/popups_allowed.py
deleted file mode 100644
index cbc1e2a..0000000
--- a/chrome/browser/policy/e2e_test/tests/popups_allowed/popups_allowed.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from absl import flags
-
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-FLAGS = flags.FLAGS
-
-
-@environment(file="../policy_test.asset.textpb")
-class PopupsAllowedForUrlsTest(ChromeEnterpriseTestCase):
-  """Test the PopupsAllowedForUrls
-
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=PopupsAllowedForUrls.
-    """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  @test
-  def test_popup_allow_for_url(self):
-    # Enable "Allow popups on these sites" with testing URL
-    # TODO(jxiang, crbug/1020231)
-    test_site = 'www.dummysoftware.com'
-    self.SetPolicy('win2012-dc', r'PopupsAllowedForUrls\1', test_site, 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Enabled Allow pop-ups on' + test_site)
-
-    # Run webdriver test
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(local_dir,
-                                   'popup_allowed_webdriver_test.py'))
-    # Check if new pop up window comes up
-    self.assertTrue(int(output) > 1)
-
-  @test
-  def test_allow_for_other_url(self):
-    # Set the allow popup site using google.com, so popuptest.com is disabled
-    test_site = 'www.google.com'
-    self.SetPolicy('win2012-dc', r'PopupsAllowedForUrls\1', test_site, 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Enabled Allow pop-ups on' + test_site)
-
-    # Run webdriver test
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(local_dir,
-                                   'popup_allowed_webdriver_test.py'))
-    # Check if the new pop-up windows are blocked
-    self.assertEquals(int(output), 1)
diff --git a/chrome/browser/policy/e2e_test/tests/restore_on_startup/__init__.py b/chrome/browser/policy/e2e_test/tests/restore_on_startup/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/restore_on_startup/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup.py b/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup.py
deleted file mode 100644
index d38740b9..0000000
--- a/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import os
-
-from absl import flags
-
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-FLAGS = flags.FLAGS
-
-
-@environment(file="../policy_test.asset.textpb")
-class RestoreOnStartupTest(ChromeEnterpriseTestCase):
-  """Test the RestoreOnStartup policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=RestoreOnStartup."""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  @test
-  def test_RestoreTheLastSession(self):
-    logging.info('RestoreOnStartup is set to RestoreTheLastSession')
-
-    self.SetPolicy('win2012-dc', 'RestoreOnStartup', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    # delete the user data directory to make sure we start from a clean slate.
-    user_data_dir = r'c:\temp\user1'
-    self.RunCommand(
-        'client2012',
-        'cmd /C if exist %s rmdir /s /q %s' % (user_data_dir, user_data_dir))
-    dir = os.path.dirname(os.path.abspath(__file__))
-    user_data_dir_arg = '--user_data_dir=%s' % user_data_dir
-    urls = ['https://www.cnn.com/', 'https://www.youtube.com/']
-    list.sort(urls)
-
-    # create a session: start Chrome and open several URLs.
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=open_urls',
-            user_data_dir_arg,
-        ] + ['--urls=%s' % url for url in urls])
-    output_urls = json.loads(output)
-    self.assertEqual(urls, output_urls)
-
-    # start Chrome. The last session should be restored.
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=start_chrome',
-            user_data_dir_arg,
-        ])
-    output_urls = json.loads(output)
-    self.assertEqual(urls, output_urls)
-
-  @test
-  def test_OpenNewTabPage(self):
-    logging.info('RestoreOnStartup is set to Open New Tab Page')
-
-    self.SetPolicy('win2012-dc', 'RestoreOnStartup', 5, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-    dir = os.path.dirname(os.path.abspath(__file__))
-    user_data_dir_arg = r'--user_data_dir=c:\temp\user2'
-    urls = ['https://www.cnn.com/', 'https://www.youtube.com/']
-    list.sort(urls)
-
-    # create a session: start Chrome and open several URLs.
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=open_urls',
-            user_data_dir_arg,
-        ] + ['--urls=%s' % url for url in urls])
-    output_urls = json.loads(output)
-    self.assertEqual(urls, output_urls)
-
-    # start Chrome. There should be just one New Tab page.
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=start_chrome',
-            user_data_dir_arg,
-        ])
-    output_urls = json.loads(output)
-    self.assertEqual(len(output_urls), 1)
-
-    # The URL of the new tab can be one of the following:
-    # - https://www.google.com/_/chrome/newtab?ie=UTF-8
-    # - chrome://newtab
-    # - chrome-search://local-ntp/local-ntp.html
-    self.assertTrue('/newtab' in output_urls[0] or
-                    'local-ntp.html' in output_urls[0])
-
-  @test
-  def test_OpenListOfUrls(self):
-    logging.info('RestoreOnStartup is set to Open a list of URLs')
-
-    self.SetPolicy('win2012-dc', 'RestoreOnStartup', 4, 'DWORD')
-    urls_to_open = ['https://www.wikipedia.org/']
-    for i in range(len(urls_to_open)):
-      self.SetPolicy('win2012-dc', r'RestoreOnStartupURLs\%s' % (i + 1),
-                     '"%s"' % urls_to_open[i], 'String')
-
-    self.RunCommand('client2012', 'gpupdate /force')
-    dir = os.path.dirname(os.path.abspath(__file__))
-    user_data_dir_arg = r'--user_data_dir=c:\temp\user3'
-    urls = ['https://www.cnn.com/', 'https://www.youtube.com/']
-    list.sort(urls)
-
-    # start Chrome and open several URLs.
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=open_urls',
-            user_data_dir_arg,
-        ] + ['--urls=%s' % url for url in urls])
-    output_urls = json.loads(output)
-    self.assertEqual(urls, output_urls)
-
-    # start Chrome. Urls specified by RestoreOnStartupURLs should be opened
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(dir, 'restore_on_startup_webdriver_test.py'),
-        [
-            '--action=start_chrome',
-            user_data_dir_arg,
-        ])
-    output_urls = json.loads(output)
-    self.assertEqual(urls_to_open, output_urls)
diff --git a/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup_webdriver_test.py
deleted file mode 100644
index 2127046..0000000
--- a/chrome/browser/policy/e2e_test/tests/restore_on_startup/restore_on_startup_webdriver_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import time
-
-from absl import app, flags
-from selenium.webdriver.chrome.options import Options
-
-import test_util
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_enum(
-    'action', None, ['open_urls', 'start_chrome'], """The action to take.
-
-    - open_urls: start chrome, then open urls passed through --urls in tabs.
-    - start_chrome: start chrome.
-    """)
-
-flags.DEFINE_multi_string('urls', None, "List of urls to open")
-flags.DEFINE_string('user_data_dir', None,
-                    "The user data directory used by chrome")
-
-
-def _create_driver():
-  chrome_options = Options()
-  chrome_options.add_argument(r'user-data-dir=%s' % FLAGS.user_data_dir)
-  return test_util.create_chrome_webdriver(chrome_options=chrome_options)
-
-
-def _get_urls(driver):
-  """Returns the list of URLs in tabs."""
-  urls = []
-  for w in driver.window_handles:
-    driver.switch_to.window(w)
-    urls.append(driver.current_url)
-  list.sort(urls)
-  return urls
-
-
-def open_urls():
-  driver = _create_driver()
-
-  # open the first url in the current New Tab tab
-  driver.get(FLAGS.urls[0])
-
-  # open the rest of urls in new tabs
-  for url in FLAGS.urls[1:]:
-    driver.execute_script("window.open('%s');" % url)
-
-  # give chrome some time to load everything
-  time.sleep(2)
-
-  print json.dumps(_get_urls(driver))
-  test_util.shutdown_chrome()
-
-
-def start_chrome():
-  """Start chrome.
-
-  Write the list of URLs in tabs to stdout.
-  """
-  driver = _create_driver()
-
-  # give chrome some time to load everything. This is less than ideal, but
-  # currently there's no statisfactory solution.
-  time.sleep(10)
-
-  print json.dumps(_get_urls(driver))
-  test_util.shutdown_chrome()
-
-
-def main(argv):
-  if FLAGS.action == 'open_urls':
-    open_urls()
-  elif FLAGS.action == 'start_chrome':
-    start_chrome()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/safe_browsing/__init__.py b/chrome/browser/policy/e2e_test/tests/safe_browsing/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/safe_browsing/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py b/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py
deleted file mode 100644
index ea4a36c..0000000
--- a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class SafeBrowsingEnabledTest(ChromeEnterpriseTestCase):
-  """Test the SafeBrowsingEnabled policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=SafeBrowsingEnabled"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-  def isSafeBrowsingEnabled(self):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    return self.RunUITest(
-        'client2012',
-        os.path.join(dir, 'safe_browsing_ui_test.py'),
-        timeout=600)
-
-  @test
-  def test_SafeBrowsingDisabledNoWarning(self):
-    self.SetPolicy('win2012-dc', r'SafeBrowsingEnabled', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self.isSafeBrowsingEnabled()
-    self.assertIn("RESULTS.unsafe_page: False", output)
-    self.assertIn("RESULTS.unsafe_download: False", output)
-
-  @test
-  def test_SafeBrowsingEnabledShowsWarning(self):
-    self.SetPolicy('win2012-dc', r'SafeBrowsingEnabled', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self.isSafeBrowsingEnabled()
-    self.assertIn("RESULTS.unsafe_page: True", output)
-    self.assertIn("RESULTS.unsafe_download: True", output)
diff --git a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing_ui_test.py b/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing_ui_test.py
deleted file mode 100644
index 1181f090..0000000
--- a/chrome/browser/policy/e2e_test/tests/safe_browsing/safe_browsing_ui_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-import test_util
-import time
-from absl import app
-from selenium import webdriver
-from pywinauto.application import Application
-
-UnsafePageLink = "http://testsafebrowsing.appspot.com/s/malware.html"
-UnsafePageLinkTabText = "Security error"
-
-UnsafeDownloadLink = "http://testsafebrowsing.appspot.com/s/content.exe"
-UnsafeDownloadTextRe = ".* is dangerous,\s*so\s*Chrom.* has blocked it"
-
-
-def visit(window, url):
-  """Visit a specific URL through pywinauto.Application.
-
-  SafeBrowsing intercepts HTTP requests & hangs WebDriver.get(), which prevents
-  us from getting the page source. Using pywinauto to visit the pages instead.
-  """
-  window.Edit.set_edit_text(url).type_keys("%{ENTER}")
-  time.sleep(10)
-
-
-def main(argv):
-  exclude_switches = ["disable-background-networking"]
-  chrome_options = webdriver.ChromeOptions()
-  chrome_options.add_experimental_option("excludeSwitches", exclude_switches)
-
-  driver = test_util.create_chrome_webdriver(chrome_options=chrome_options)
-
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-  window = app.top_window()
-
-  # Wait for Chrome to download SafeBrowsing lists in the background.
-  # There's no trigger to force this operation or synchronize on it, but quick
-  # experiments have shown 3-4 minutes in most cases, so 5 should be plenty.
-  time.sleep(60 * 5)
-
-  print "Visiting unsafe page: %s" % UnsafePageLink
-  visit(window, UnsafePageLink)
-
-  unsafe_page = False
-  for desc in app.top_window().descendants():
-    if desc.window_text():
-      print "unsafe_page.item: %s" % desc.window_text()
-      if UnsafePageLinkTabText in desc.window_text():
-        unsafe_page = True
-        break
-
-  print "Downloading unsafe file: %s" % UnsafeDownloadLink
-  visit(window, UnsafeDownloadLink)
-
-  unsafe_download = False
-  for desc in app.top_window().descendants():
-    if desc.window_text():
-      print "unsafe_download.item: %s" % desc.window_text()
-      if re.search(UnsafeDownloadTextRe, desc.window_text()):
-        unsafe_download = True
-        break
-
-  print "RESULTS.unsafe_page: %s" % unsafe_page
-  print "RESULTS.unsafe_download: %s" % unsafe_download
-
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/translate_enabled/__init__.py b/chrome/browser/policy/e2e_test/tests/translate_enabled/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/translate_enabled/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py
deleted file mode 100644
index 270e3bc..0000000
--- a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class TranslateEnabledTest(ChromeEnterpriseTestCase):
-  """Test the TranslateEnabled policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=TranslateEnabled"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.EnableUITest('client2012')
-
-  def isChromeTranslateEnabled(self, incognito=False):
-    dir = os.path.dirname(os.path.abspath(__file__))
-    output = self.RunUITest(
-        'client2012',
-        os.path.join(dir, 'translate_enabled_webdriver_test.py'),
-        args=['--incognito'] if incognito else [])
-    return "TRUE" in output
-
-  @test
-  def test_TranslatedDisabled(self, incognito=False):
-    self.SetPolicy('win2012-dc', 'TranslateEnabled', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    enabled = self.isChromeTranslateEnabled()
-    self.assertFalse(enabled)
-
-  @test
-  def test_TranslatedEnabled(self, incognito=False):
-    self.SetPolicy('win2012-dc', 'TranslateEnabled', 1, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    enabled = self.isChromeTranslateEnabled()
-    self.assertTrue(enabled)
-
-  @test
-  def test_TranslatedDisabledIncognito(self):
-    self.test_TranslatedDisabled(incognito=True)
-
-  @test
-  def test_TranslatedEnabledIncognito(self):
-    self.test_TranslatedEnabled(incognito=True)
diff --git a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py b/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py
deleted file mode 100644
index aec81fd1..0000000
--- a/chrome/browser/policy/e2e_test/tests/translate_enabled/translate_enabled_webdriver_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-import test_util
-from absl import app, flags
-from pywinauto.application import Application
-from selenium import webdriver
-from selenium.webdriver.chrome.options import Options
-
-# A URL that is in a different language than our Chrome language.
-URL = "https://zh.wikipedia.org/wiki/Chromium"
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_bool('incognito', False,
-                  'Set flag to open Chrome in incognito mode.')
-
-
-def main(argv):
-  driver = test_util.create_chrome_webdriver(incognito=FLAGS.incognito)
-  driver.get(URL)
-
-  time.sleep(10)
-
-  app = Application(backend="uia")
-  app.connect(title_re='.*Chrome|.*Chromium')
-
-  translatePopupVisible = False
-  for desc in app.top_window().descendants():
-    if 'Translate this page?' in desc.window_text():
-      translatePopupVisible = True
-      break
-
-  if translatePopupVisible:
-    print "TRUE"
-  else:
-    print "FALSE"
-
-  driver.quit()
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/url_blacklist/__init__.py b/chrome/browser/policy/e2e_test/tests/url_blacklist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/url_blacklist/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/url_blacklist/url_blacklist.py b/chrome/browser/policy/e2e_test/tests/url_blacklist/url_blacklist.py
deleted file mode 100644
index 2ac8c23..0000000
--- a/chrome/browser/policy/e2e_test/tests/url_blacklist/url_blacklist.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class UrlBlacklistTest(ChromeEnterpriseTestCase):
-  """Test the URLBlacklist policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=URLBlacklist"""
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def openPage(self, url, incognito=False):
-    args = ['--url', url, '--text_only']
-    if incognito:
-      args += ['--incognito']
-
-    dir = os.path.dirname(os.path.abspath(__file__))
-    logging.info('Opening page: %s' % url)
-    output = self.RunWebDriverTest('client2012',
-                                   os.path.join(dir, '../open_page.py'), args)
-    return output
-
-  @test
-  def test_BlacklistAllCantVisit(self, incognito=False):
-    self.SetPolicy('win2012-dc', r'URLBlacklist\1', '*', 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    # Verify that we can't visit any site.
-    output = self.openPage('https://youtube.com/yt/about/', incognito=incognito)
-    self.assertIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-    output = self.openPage('https://google.com', incognito=incognito)
-    self.assertIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-  @test
-  def test_BlacklistYouTubeCantVisit(self, incognito=False):
-    self.SetPolicy('win2012-dc', r'URLBlacklist\1', 'https://youtube.com',
-                   'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    # Verify that we can't visit YouTube, but can still visit other sites.
-    output = self.openPage('https://youtube.com/yt/about/', incognito=incognito)
-    self.assertIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-    output = self.openPage('https://google.com', incognito=incognito)
-    self.assertNotIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-  @test
-  def test_BlacklistAllCantVisitIncognito(self):
-    self.test_BlacklistAllCantVisit(incognito=True)
-
-  @test
-  def test_BlacklistYouTubeCantVisitIncognito(self):
-    self.test_BlacklistYouTubeCantVisit(incognito=True)
diff --git a/chrome/browser/policy/e2e_test/tests/url_whitelist/__init__.py b/chrome/browser/policy/e2e_test/tests/url_whitelist/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/url_whitelist/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/url_whitelist/url_whitelist.py b/chrome/browser/policy/e2e_test/tests/url_whitelist/url_whitelist.py
deleted file mode 100644
index 9185837..0000000
--- a/chrome/browser/policy/e2e_test/tests/url_whitelist/url_whitelist.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class UrlWhitelistTest(ChromeEnterpriseTestCase):
-  """Test the URLWhitelist policy.
-
-  This policy provides exceptions to the URLBlacklist policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=URLBlacklist
-  and https://cloud.google.com/docs/chrome-enterprise/policies/?policy=URLWhitelist"""
-
-  @before_all
-  def setup(self):
-    client = 'client2012'
-    dc = 'win2012-dc'
-    self.InstallChrome(client)
-    self.InstallWebDriver(client)
-
-    # Blacklist all sites and add an exception with URLWhitelist.
-    self.SetPolicy(dc, r'URLBlacklist\1', '*', 'String')
-    self.SetPolicy(dc, r'URLWhitelist\1', 'https://youtube.com', 'String')
-    self.RunCommand(client, 'gpupdate /force')
-
-  def openPage(self, url, incognito=False):
-    args = ['--url', url, '--text_only']
-    if incognito:
-      args += ['--incognito']
-
-    dir = os.path.dirname(os.path.abspath(__file__))
-    logging.info('Opening page: %s' % url)
-    output = self.RunWebDriverTest('client2012',
-                                   os.path.join(dir, '../open_page.py'), args)
-    return output
-
-  @test
-  def test_AllowedUrlCanVisit(self):
-    output = self.openPage('https://youtube.com/yt/about/')
-    self.assertNotIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-  @test
-  def test_NotAllowedUrlCantVisit(self):
-    output = self.openPage('https://google.com')
-    self.assertIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-  @test
-  def test_AllowedUrlCanVisitIncognito(self):
-    output = self.openPage('https://youtube.com/yt/about/', incognito=True)
-    self.assertNotIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
-
-  @test
-  def test_NotAllowedUrlCantVisitIncognito(self):
-    output = self.openPage('https://google.com', incognito=True)
-    self.assertIn("ERR_BLOCKED_BY_ADMINISTRATOR", output)
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py
deleted file mode 100644
index e8ab764..0000000
--- a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class UserDataDirTest(ChromeEnterpriseTestCase):
-  """Test the UserDataDir
-
-    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=UserDataDir.
-
-    """
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  @test
-  def test_user_data_dir(self):
-    user_data_dir = r'C:\Temp\Browser\Google\Chrome\UserData'
-    self.SetPolicy('win2012-dc', r'UserDataDir', user_data_dir, 'String')
-    self.RunCommand('client2012', 'gpupdate /force')
-    logging.info('Updated User data dir to: ' + user_data_dir)
-
-    local_dir = os.path.dirname(os.path.abspath(__file__))
-    args = ['--user_data_dir', user_data_dir]
-    output = self.RunWebDriverTest(
-        'client2012', os.path.join(local_dir, 'user_data_dir_webdriver.py'),
-        args)
-
-    # Verify user data dir not exsiting before chrome launch
-    self.assertIn('User data before running chrome is False', output)
-    # Verify policy in chrome://policy page
-    self.assertIn('UserDataDir', output)
-    self.assertIn(user_data_dir, output)
-    # Verify profile path in chrome:// version
-    self.assertIn("Profile path is " + user_data_dir, output)
-    # Verify user data dir folder creation
-    self.assertIn('User data dir creation is True', output)
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py
deleted file mode 100644
index 77f8386..0000000
--- a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from absl import app, flags
-from selenium import webdriver
-
-import test_util
-
-FLAGS = flags.FLAGS
-flags.DEFINE_string('user_data_dir', None, 'Need specify user data dir to test')
-flags.mark_flag_as_required('user_data_dir')
-
-
-def main(argv):
-  policy_url = "chrome://policy"
-  version_url = "chrome://version"
-
-  # Verify the user data dir is not exsiting before launch the Chrome
-  print "User data before running chrome is " + str(
-      os.path.isdir(FLAGS.user_data_dir))
-
-  # Launch real Chrome
-  os.system('start chrome --remote-debugging-port=9222')
-
-  options = webdriver.ChromeOptions()
-  # Add option for connecting chromedriver with Chrome
-  options.add_experimental_option("debuggerAddress", "localhost:9222")
-
-  driver = test_util.create_chrome_webdriver(chrome_options=options)
-
-  try:
-    # Verify User Data Dir in chrome://policy page
-    driver.get(policy_url)
-    print driver.find_element_by_css_selector('html').text.encode('utf-8')
-
-    # Verfiy User Data Dir used in chrome://version
-    driver.get(version_url)
-    print "Profile path is " + driver.find_element_by_id("profile_path").text
-
-    # Verify if UserDataDir folder is created
-    print "User data dir creation is " + str(os.path.isdir(FLAGS.user_data_dir))
-  except Exception as error:
-    print error
-  finally:
-    driver.quit()
-    os.system('taskkill /f /im chrome.exe')
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/chrome/browser/policy/e2e_test/tests/youtube_restrict/__init__.py b/chrome/browser/policy/e2e_test/tests/youtube_restrict/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chrome/browser/policy/e2e_test/tests/youtube_restrict/__init__.py
+++ /dev/null
diff --git a/chrome/browser/policy/e2e_test/tests/youtube_restrict/youtube_restrict.py b/chrome/browser/policy/e2e_test/tests/youtube_restrict/youtube_restrict.py
deleted file mode 100644
index f04ab7f..0000000
--- a/chrome/browser/policy/e2e_test/tests/youtube_restrict/youtube_restrict.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-from chrome_ent_test.infra.core import environment, before_all, test
-from infra import ChromeEnterpriseTestCase
-
-
-@environment(file="../policy_test.asset.textpb")
-class YouTubeRestrictTest(ChromeEnterpriseTestCase):
-  """Test the ForceYouTubeRestrict policy.
-
-  See https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ForceYouTubeRestrict"""
-
-  RestrictedText = "This video is restricted. " \
-      + "Try signing in with a Google Apps account."
-
-  @before_all
-  def setup(self):
-    self.InstallChrome('client2012')
-    self.InstallWebDriver('client2012')
-
-  def openRestrictedVideo(self):
-    url = "https://www.youtube.com/watch?v=JtvhQ6klunk"
-    dir = os.path.dirname(os.path.abspath(__file__))
-    logging.info('Opening page: %s' % url)
-    output = self.RunWebDriverTest('client2012',
-                                   os.path.join(dir, '../open_page.py'),
-                                   ['--url', url, '--wait=5', '--text_only'])
-    return output
-
-  @test
-  def test_UnrestrictedYouTubeCanWatchVideo(self):
-    self.SetPolicy('win2012-dc', 'ForceYouTubeRestrict', 0, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self.openRestrictedVideo()
-    self.assertNotIn(YouTubeRestrictTest.RestrictedText, output)
-
-  @test
-  def test_StrictRestrictedYouTubeCantWatchVideo(self):
-    self.SetPolicy('win2012-dc', 'ForceYouTubeRestrict', 2, 'DWORD')
-    self.RunCommand('client2012', 'gpupdate /force')
-
-    output = self.openRestrictedVideo()
-    self.assertIn(YouTubeRestrictTest.RestrictedText, output)
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/BaseChromePreferenceKeyChecker.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/BaseChromePreferenceKeyChecker.java
index fd8f261..5b2f409 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/BaseChromePreferenceKeyChecker.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/BaseChromePreferenceKeyChecker.java
@@ -5,10 +5,10 @@
 package org.chromium.chrome.browser.preferences;
 
 /**
- * A dummy key checker that never asserts. Used in production builds.
+ * A dummy key checker that never throws exceptions. Used in production builds.
  */
 class BaseChromePreferenceKeyChecker {
-    void assertIsKeyInUse(String key) {
+    void checkIsKeyInUse(String key) {
         // No-op.
     }
 }
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyChecker.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyChecker.java
index 9562ff9..7b35fd42 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyChecker.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyChecker.java
@@ -57,11 +57,15 @@
     }
 
     /**
-     * Assert that the |key| passed is in use.
+     * Check that the |key| passed is in use.
+     * @throws RuntimeException if the key is not in use.
      */
     @Override
-    void assertIsKeyInUse(String key) {
-        assert isKeyInUse(key);
+    void checkIsKeyInUse(String key) {
+        if (!isKeyInUse(key)) {
+            throw new RuntimeException("SharedPreferences key \"" + key
+                    + "\" is not registered in ChromePreferenceKeys.createKeysInUse()");
+        }
     }
 
     /**
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyCheckerTest.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyCheckerTest.java
index da2fdfd..fd918f4 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyCheckerTest.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyCheckerTest.java
@@ -44,46 +44,46 @@
 
     @Test
     @SmallTest
-    public void testRegularKeys_noAssert() {
-        mSubject.assertIsKeyInUse(KEY1_IN_USE);
-        mSubject.assertIsKeyInUse(KEY2_IN_USE);
-        mSubject.assertIsKeyInUse(GRANDFATHERED_KEY_IN_USE);
+    public void testRegularKeys_registered_noException() {
+        mSubject.checkIsKeyInUse(KEY1_IN_USE);
+        mSubject.checkIsKeyInUse(KEY2_IN_USE);
+        mSubject.checkIsKeyInUse(GRANDFATHERED_KEY_IN_USE);
     }
 
-    @Test(expected = AssertionError.class)
+    @Test(expected = RuntimeException.class)
     @SmallTest
-    public void testRegularKeys_assert() {
-        mSubject.assertIsKeyInUse(KEY3_NOT_IN_USE);
+    public void testRegularKeys_notRegistered_throwsException() {
+        mSubject.checkIsKeyInUse(KEY3_NOT_IN_USE);
     }
 
     @Test
     @SmallTest
-    public void testPrefixedKeys_noAssert() {
-        mSubject.assertIsKeyInUse(KEY_PREFIX1_IN_USE.createKey("restofkey"));
+    public void testPrefixedKeys_noException() {
+        mSubject.checkIsKeyInUse(KEY_PREFIX1_IN_USE.createKey("restofkey"));
     }
 
     @Test
     @SmallTest
-    public void testPrefixedKeys_noAssert_multipleLevels() {
-        mSubject.assertIsKeyInUse(
+    public void testPrefixedKeys_multipleLevels_noException() {
+        mSubject.checkIsKeyInUse(
                 KEY_PREFIX2_IN_USE.createKey("ExtraLevel.DynamicallyGenerated98765"));
     }
 
-    @Test(expected = AssertionError.class)
+    @Test(expected = RuntimeException.class)
     @SmallTest
-    public void testPrefixedKeys_assert_noPrefixMatch() {
-        mSubject.assertIsKeyInUse(KEY_PREFIX3_NOT_IN_USE.createKey("restofkey"));
+    public void testPrefixedKeys_noPrefixMatch_throwsException() {
+        mSubject.checkIsKeyInUse(KEY_PREFIX3_NOT_IN_USE.createKey("restofkey"));
     }
 
-    @Test(expected = AssertionError.class)
+    @Test(expected = RuntimeException.class)
     @SmallTest
-    public void testPrefixedKeys_assert_matchOnlyPrefix() {
-        mSubject.assertIsKeyInUse(KEY_PREFIX1_IN_USE.createKey(""));
+    public void testPrefixedKeys_matchOnlyPrefix_throwsException() {
+        mSubject.checkIsKeyInUse(KEY_PREFIX1_IN_USE.createKey(""));
     }
 
-    @Test(expected = AssertionError.class)
+    @Test(expected = RuntimeException.class)
     @SmallTest
-    public void testPrefixedKeys_assert_matchPattern() {
-        mSubject.assertIsKeyInUse(KEY_PREFIX1_IN_USE.createKey("*"));
+    public void testPrefixedKeys_matchPattern_throwsException() {
+        mSubject.checkIsKeyInUse(KEY_PREFIX1_IN_USE.createKey("*"));
     }
 }
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index 5fd3835..5b04b56 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -270,6 +270,21 @@
     public static final String PREF_SIGNIN_AND_SYNC_PROMO_SHOW_COUNT =
             "enhanced_bookmark_signin_promo_show_count";
 
+    /** First run flags. */
+    public static final String FIRST_RUN_CACHED_TOS_ACCEPTED_PREF = "first_run_tos_accepted";
+    public static final String FIRST_RUN_FLOW_COMPLETE = "first_run_flow";
+    public static final String FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE = "lightweight_first_run_flow";
+    public static final String FIRST_RUN_SKIP_WELCOME_PAGE = "skip_welcome_page";
+
+    /**
+     * SharedPreferences preference names to keep the state of the First Run Experience.
+     */
+    public static final String FIRST_RUN_FLOW_SIGNIN_COMPLETE = "first_run_signin_complete";
+
+    // Needed by ChromeBackupAgent
+    public static final String FIRST_RUN_FLOW_SIGNIN_SETUP = "first_run_signin_setup";
+    public static final String FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME = "first_run_signin_account_name";
+
     ////////////////////////////////////////////////////////////////////////////////////////////////
     // Keys representing cached feature flags                                                     //
     ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -392,6 +407,10 @@
     public static final String SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT =
             "swap_pixel_format_to_fix_convert_from_translucent";
 
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    // End of keys representing cached feature flags                                              //
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
     /**
      * Keys that indicates if an item in the context menu has been clicked or not.
      * Used to hide the "new" tag for the items after they are clicked.
@@ -402,6 +421,7 @@
             "Chrome.Contextmenu.OpenImageInEphemeralTabClicked";
     public static final String CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS_CLICKED =
             "Chrome.ContextMenu.SearchWithGoogleLensClicked";
+
     /**
      * These values are currently used as SharedPreferences keys.
      *
@@ -476,6 +496,13 @@
                 CONTEXT_MENU_OPEN_IN_EPHEMERAL_TAB_CLICKED,
                 CONTEXT_MENU_OPEN_IMAGE_IN_EPHEMERAL_TAB_CLICKED,
                 CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS_CLICKED,
+                FIRST_RUN_CACHED_TOS_ACCEPTED_PREF,
+                FIRST_RUN_FLOW_COMPLETE,
+                FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE,
+                FIRST_RUN_SKIP_WELCOME_PAGE,
+                FIRST_RUN_FLOW_SIGNIN_COMPLETE,
+                FIRST_RUN_FLOW_SIGNIN_SETUP,
+                FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME,
 
                 // Cached feature flags
                 SERVICE_MANAGER_FOR_DOWNLOAD_RESUMPTION_KEY,
@@ -605,6 +632,13 @@
                 OFFLINE_INDICATOR_V2_ENABLED_KEY,
                 PREF_PERSONALIZED_SIGNIN_PROMO_DECLINED,
                 PREF_SIGNIN_AND_SYNC_PROMO_SHOW_COUNT,
+                FIRST_RUN_CACHED_TOS_ACCEPTED_PREF,
+                FIRST_RUN_FLOW_COMPLETE,
+                FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE,
+                FIRST_RUN_SKIP_WELCOME_PAGE,
+                FIRST_RUN_FLOW_SIGNIN_COMPLETE,
+                FIRST_RUN_FLOW_SIGNIN_SETUP,
+                FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME,
 
                 // Cached feature flags
                 SERVICE_MANAGER_FOR_DOWNLOAD_RESUMPTION_KEY,
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java
index 377bb40..9102508 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java
@@ -22,6 +22,7 @@
 /**
  * Layer over android {@link SharedPreferences}.
  */
+@SuppressWarnings("UseSharedPreferencesManagerFromChromeCheck")
 public class SharedPreferencesManager {
     private static class LazyHolder {
         static final SharedPreferencesManager INSTANCE = new SharedPreferencesManager();
@@ -111,7 +112,7 @@
      * Note that you must not modify the set instance returned by this call.
      */
     public Set<String> readStringSet(String key, Set<String> defaultValue) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         return ContextUtils.getAppSharedPreferences().getStringSet(key, defaultValue);
     }
 
@@ -119,7 +120,7 @@
      * Adds a value to string set in shared preferences.
      */
     public void addToStringSet(String key, String value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         Set<String> values = new HashSet<>(
                 ContextUtils.getAppSharedPreferences().getStringSet(key, Collections.emptySet()));
         values.add(value);
@@ -130,7 +131,7 @@
      * Removes value from string set in shared preferences.
      */
     public void removeFromStringSet(String key, String value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         Set<String> values = new HashSet<>(
                 ContextUtils.getAppSharedPreferences().getStringSet(key, Collections.emptySet()));
         if (values.remove(value)) {
@@ -142,7 +143,7 @@
      * Writes string set to shared preferences.
      */
     public void writeStringSet(String key, Set<String> values) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         writeStringSetUnchecked(key, values);
     }
 
@@ -156,7 +157,7 @@
      * @param value The new value for the preference.
      */
     public void writeInt(String key, int value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         writeIntUnchecked(key, value);
     }
 
@@ -182,7 +183,7 @@
      * @return The value of the preference.
      */
     public int readInt(String key, int defaultValue) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
             return ContextUtils.getAppSharedPreferences().getInt(key, defaultValue);
         }
@@ -195,7 +196,7 @@
      * @return The newly incremented value.
      */
     public int incrementInt(String key) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         int value = ContextUtils.getAppSharedPreferences().getInt(key, 0);
         writeIntUnchecked(key, ++value);
         return value;
@@ -208,7 +209,7 @@
      * @param value The new value for the preference.
      */
     public void writeLong(String key, long value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         SharedPreferences.Editor ed = ContextUtils.getAppSharedPreferences().edit();
         ed.putLong(key, value);
         ed.apply();
@@ -232,7 +233,7 @@
      * @return The value of the preference if stored; defaultValue otherwise.
      */
     public long readLong(String key, long defaultValue) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
             return ContextUtils.getAppSharedPreferences().getLong(key, defaultValue);
         }
@@ -245,7 +246,7 @@
      * @param value The new value for the preference.
      */
     public void writeBoolean(String key, boolean value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         SharedPreferences.Editor ed = ContextUtils.getAppSharedPreferences().edit();
         ed.putBoolean(key, value);
         ed.apply();
@@ -259,7 +260,7 @@
      * @return The value of the preference if stored; defaultValue otherwise.
      */
     public boolean readBoolean(String key, boolean defaultValue) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
             return ContextUtils.getAppSharedPreferences().getBoolean(key, defaultValue);
         }
@@ -272,7 +273,7 @@
      * @param value The new value for the preference.
      */
     public void writeString(String key, String value) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         SharedPreferences.Editor ed = ContextUtils.getAppSharedPreferences().edit();
         ed.putString(key, value);
         ed.apply();
@@ -286,7 +287,7 @@
      * @return The value of the preference if stored; defaultValue otherwise.
      */
     public String readString(String key, @Nullable String defaultValue) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
             return ContextUtils.getAppSharedPreferences().getString(key, defaultValue);
         }
@@ -298,9 +299,20 @@
      * @param key The key of the preference to remove.
      */
     public void removeKey(String key) {
-        mKeyChecker.assertIsKeyInUse(key);
+        mKeyChecker.checkIsKeyInUse(key);
         SharedPreferences.Editor ed = ContextUtils.getAppSharedPreferences().edit();
         ed.remove(key);
         ed.apply();
     }
+
+    /**
+     * Checks if any value was written associated to a key in shared preferences.
+     *
+     * @param key The key of the preference to check.
+     * @return Whether any value was written for that key.
+     */
+    public boolean contains(String key) {
+        mKeyChecker.checkIsKeyInUse(key);
+        return ContextUtils.getAppSharedPreferences().contains(key);
+    }
 }
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManagerTest.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManagerTest.java
index 2bc9778..29b471e0 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManagerTest.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManagerTest.java
@@ -7,6 +7,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -47,6 +48,7 @@
         // Verify default return values when no value is written.
         assertEquals(0, mSubject.readInt("int_key"));
         assertEquals(987, mSubject.readInt("int_key", 987));
+        assertFalse(mSubject.contains("int_key"));
 
         // Write a value.
         mSubject.writeInt("int_key", 123);
@@ -54,12 +56,14 @@
         // Verify value written can be read.
         assertEquals(123, mSubject.readInt("int_key"));
         assertEquals(123, mSubject.readInt("int_key", 987));
+        assertTrue(mSubject.contains("int_key"));
 
         // Remove the value.
         mSubject.removeKey("int_key");
 
         // Verify the removed value is not returned anymore.
         assertEquals(0, mSubject.readInt("int_key"));
+        assertFalse(mSubject.contains("int_key"));
     }
 
     @Test
@@ -85,6 +89,7 @@
         // Verify default return values when no value is written.
         assertEquals(false, mSubject.readBoolean("bool_key", false));
         assertEquals(true, mSubject.readBoolean("bool_key", true));
+        assertFalse(mSubject.contains("bool_key"));
 
         // Write a value.
         mSubject.writeBoolean("bool_key", true);
@@ -92,6 +97,7 @@
         // Verify value written can be read.
         assertEquals(true, mSubject.readBoolean("bool_key", false));
         assertEquals(true, mSubject.readBoolean("bool_key", true));
+        assertTrue(mSubject.contains("bool_key"));
 
         // Remove the value.
         mSubject.removeKey("bool_key");
@@ -99,6 +105,7 @@
         // Verify the removed value is not returned anymore.
         assertEquals(false, mSubject.readBoolean("bool_key", false));
         assertEquals(true, mSubject.readBoolean("bool_key", true));
+        assertFalse(mSubject.contains("bool_key"));
     }
 
     @Test
@@ -107,6 +114,7 @@
         // Verify default return values when no value is written.
         assertEquals(0, mSubject.readLong("long_key"));
         assertEquals(9876543210L, mSubject.readLong("long_key", 9876543210L));
+        assertFalse(mSubject.contains("long_key"));
 
         // Write a value.
         mSubject.writeLong("long_key", 9999999999L);
@@ -114,12 +122,14 @@
         // Verify value written can be read.
         assertEquals(9999999999L, mSubject.readLong("long_key"));
         assertEquals(9999999999L, mSubject.readLong("long_key", 9876543210L));
+        assertTrue(mSubject.contains("long_key"));
 
         // Remove the value.
         mSubject.removeKey("long_key");
 
         // Verify the removed value is not returned anymore.
         assertEquals(0, mSubject.readLong("long_key"));
+        assertFalse(mSubject.contains("long_key"));
     }
 
     @Test
@@ -132,6 +142,7 @@
         assertEquals(Collections.emptySet(), mSubject.readStringSet("string_set_key"));
         assertEquals(defaultStringSet, mSubject.readStringSet("string_set_key", defaultStringSet));
         assertNull(mSubject.readStringSet("string_set_key", null));
+        assertFalse(mSubject.contains("string_set_key"));
 
         // Write a value.
         mSubject.writeStringSet("string_set_key", exampleStringSet);
@@ -140,12 +151,14 @@
         assertEquals(exampleStringSet, mSubject.readStringSet("string_set_key"));
         assertEquals(exampleStringSet, mSubject.readStringSet("string_set_key", defaultStringSet));
         assertEquals(exampleStringSet, mSubject.readStringSet("string_set_key", null));
+        assertTrue(mSubject.contains("string_set_key"));
 
         // Remove the value.
         mSubject.removeKey("string_set_key");
 
         // Verify the removed value is not returned anymore.
         assertEquals(Collections.emptySet(), mSubject.readStringSet("string_set_key"));
+        assertFalse(mSubject.contains("string_set_key"));
     }
 
     @Test
@@ -189,38 +202,40 @@
     @SmallTest
     public void testCheckerIsCalled() {
         mSubject.writeInt("int_key", 123);
-        verify(mChecker, times(1)).assertIsKeyInUse("int_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("int_key");
         mSubject.readInt("int_key");
-        verify(mChecker, times(2)).assertIsKeyInUse("int_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("int_key");
         mSubject.incrementInt("int_key");
-        verify(mChecker, times(3)).assertIsKeyInUse("int_key");
+        verify(mChecker, times(3)).checkIsKeyInUse("int_key");
 
         mSubject.writeBoolean("bool_key", true);
-        verify(mChecker, times(1)).assertIsKeyInUse("bool_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("bool_key");
         mSubject.readBoolean("bool_key", false);
-        verify(mChecker, times(2)).assertIsKeyInUse("bool_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("bool_key");
 
         mSubject.writeString("string_key", "foo");
-        verify(mChecker, times(1)).assertIsKeyInUse("string_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("string_key");
         mSubject.readString("string_key", "");
-        verify(mChecker, times(2)).assertIsKeyInUse("string_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("string_key");
 
         mSubject.writeLong("long_key", 999L);
-        verify(mChecker, times(1)).assertIsKeyInUse("long_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("long_key");
         mSubject.readLong("long_key");
-        verify(mChecker, times(2)).assertIsKeyInUse("long_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("long_key");
 
         mSubject.writeStringSet("string_set_key", new HashSet<>());
-        verify(mChecker, times(1)).assertIsKeyInUse("string_set_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("string_set_key");
         mSubject.readStringSet("string_set_key");
-        verify(mChecker, times(2)).assertIsKeyInUse("string_set_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("string_set_key");
         mSubject.addToStringSet("string_set_key", "bar");
-        verify(mChecker, times(3)).assertIsKeyInUse("string_set_key");
+        verify(mChecker, times(3)).checkIsKeyInUse("string_set_key");
         mSubject.removeFromStringSet("string_set_key", "bar");
-        verify(mChecker, times(4)).assertIsKeyInUse("string_set_key");
+        verify(mChecker, times(4)).checkIsKeyInUse("string_set_key");
 
         mSubject.removeKey("some_key");
-        verify(mChecker, times(1)).assertIsKeyInUse("some_key");
+        verify(mChecker, times(1)).checkIsKeyInUse("some_key");
+        mSubject.contains("some_key");
+        verify(mChecker, times(2)).checkIsKeyInUse("some_key");
     }
 
     private static class TestObserver implements SharedPreferencesManager.Observer {
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 78151f0..69c4025 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -1567,13 +1567,6 @@
   PrerenderTestURL(https_url, FINAL_STATUS_SSL_ERROR, 0);
 }
 
-// Checks that we cancel correctly when window.print() is called.
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
-  DisableLoadEventCheck();
-  PrerenderTestURL("/prerender/prerender_print.html", FINAL_STATUS_WINDOW_PRINT,
-                   0);
-}
-
 class TestClientCertStore : public net::ClientCertStore {
  public:
   explicit TestClientCertStore(const net::CertificateList& certs)
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 0a619ade..11e7f40f 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -732,10 +732,6 @@
   NotifyPrerenderStop();
 }
 
-void PrerenderContents::CancelPrerenderForPrinting() {
-  Destroy(FINAL_STATUS_WINDOW_PRINT);
-}
-
 void PrerenderContents::CancelPrerenderForUnsupportedMethod() {
   Destroy(FINAL_STATUS_INVALID_HTTP_METHOD);
 }
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index cec81a38..46e9f6bf 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -292,7 +292,6 @@
       std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
 
   // chrome::mojom::PrerenderCanceler:
-  void CancelPrerenderForPrinting() override;
   void CancelPrerenderForUnsupportedMethod() override;
   void CancelPrerenderForUnsupportedScheme(const GURL& url) override;
   void CancelPrerenderForSyncDeferredRedirect() override;
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h
index 9d6e2eb..8d50045 100644
--- a/chrome/browser/prerender/prerender_final_status.h
+++ b/chrome/browser/prerender/prerender_final_status.h
@@ -41,7 +41,7 @@
   FINAL_STATUS_RENDERER_CRASHED = 21,
   FINAL_STATUS_UNSUPPORTED_SCHEME = 22,
   FINAL_STATUS_INVALID_HTTP_METHOD = 23,
-  FINAL_STATUS_WINDOW_PRINT = 24,
+  // Obsolete: FINAL_STATUS_WINDOW_PRINT = 24,
   FINAL_STATUS_RECENTLY_VISITED = 25,
   FINAL_STATUS_WINDOW_OPENER = 26,
   // Obsolete: FINAL_STATUS_PAGE_ID_CONFLICT = 27,
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 3d026cd1..916b0c9 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -52,6 +52,10 @@
 #include "printing/printed_document.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if defined(OS_WIN)
+#include "printing/common/printing_features.h"
+#endif
+
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 #include "chrome/browser/printing/print_error_dialog.h"
 #endif
@@ -161,9 +165,20 @@
     const gfx::Rect& content_area,
     const gfx::Point& offsets) {
 #if defined(OS_WIN)
-  print_job_->StartConversionToNativeFormat(print_data, page_size, content_area,
-                                            offsets);
-#else
+  // Non-modifiable jobs are PDF, need to check a different flag for those when
+  // determining whether to print with XPS or GDI print API.
+  const bool print_using_xps =
+      print_job_->document()->settings().is_modifiable()
+          ? base::FeatureList::IsEnabled(features::kUseXpsForPrinting)
+          : base::FeatureList::IsEnabled(features::kUseXpsForPrintingFromPdf);
+  if (!print_using_xps) {
+    // Print using GDI, which first requires conversion to EMF.
+    print_job_->StartConversionToNativeFormat(print_data, page_size,
+                                              content_area, offsets);
+    return;
+  }
+#endif
+
   std::unique_ptr<MetafileSkia> metafile = std::make_unique<MetafileSkia>();
   CHECK(metafile->InitFromData(print_data->front(), print_data->size()));
 
@@ -171,7 +186,6 @@
   PrintedDocument* document = print_job_->document();
   document->SetDocument(std::move(metafile), page_size, content_area);
   ShouldQuitFromInnerMessageLoop();
-#endif
 }
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 6a39628..630f4045 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -196,12 +196,6 @@
   }
 
  private:
-  std::unique_ptr<network::SimpleURLLoader> CreateFakeURLLoader(
-      const GURL& url,
-      const std::string& response_data,
-      net::HttpStatusCode response_code,
-      net::URLRequestStatus::Status status);
-
   MOCK_METHOD0(Callback, void(void));
 
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 2b1140f..652d217 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -317,22 +317,6 @@
          PrefService::INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
 }
 
-bool Profile::IsSyncAllowed() {
-  if (ProfileSyncServiceFactory::HasSyncService(this)) {
-    syncer::SyncService* sync_service =
-        ProfileSyncServiceFactory::GetForProfile(this);
-    return !sync_service->HasDisableReason(
-               syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE) &&
-           !sync_service->HasDisableReason(
-               syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
-  }
-
-  // No ProfileSyncService created yet - we don't want to create one, so just
-  // infer the accessible state by looking at prefs/command line flags.
-  syncer::SyncPrefs prefs(GetPrefs());
-  return switches::IsSyncAllowedByFlag() && !prefs.IsManaged();
-}
-
 void Profile::MaybeSendDestroyedNotification() {
   if (!sent_destroyed_notification_) {
     sent_destroyed_notification_ = true;
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 458c4acb..442d722 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -411,10 +411,6 @@
   // This method is virtual in order to be overridden for tests.
   virtual bool IsNewProfile();
 
-  // Checks whether sync is configurable by the user. Returns false if sync is
-  // disallowed by the command line or controlled by configuration management.
-  bool IsSyncAllowed();
-
   // Send NOTIFICATION_PROFILE_DESTROYED for this Profile, if it has not
   // already been sent. It is necessary because most Profiles are destroyed by
   // ProfileDestroyer, but in tests, some are not.
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index 508f2ea..67f9e50 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -647,6 +647,17 @@
     EXPECT_FALSE(otr_profile->IsIndependentOffTheRecordProfile());
   }
 
+  // We are about to destroy a profile. In production that will only happen
+  // as part of the destruction of BrowserProcess's ProfileManager. This
+  // happens in PostMainMessageLoopRun(). This means that to have this test
+  // represent production we have to make sure that no tasks are pending on the
+  // main thread before we destroy the profile. We also would need to prohibit
+  // the posting of new tasks on the main thread as in production the main
+  // thread's message loop will not be accepting them. We fallback on flushing
+  // as many runners as possible here to avoid the posts coming from any of
+  // them.
+  FlushIoTaskRunnerAndSpinThreads();
+
   // Destroy the off-the-record profile.
   {
     content::WindowedNotificationObserver profile_destroyed_observer(
@@ -668,4 +679,8 @@
     profile.reset();
     profile_destroyed_observer.Wait();
   }
+
+  // Pending tasks related to |profile| could depend on |temp_dir|. We need to
+  // let them complete before |temp_dir| goes out of scope.
+  FlushIoTaskRunnerAndSpinThreads();
 }
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
index d657cff..4c39d73 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
@@ -789,7 +789,7 @@
   ExpectCanDiscardTrueAllReasons(&tab_lifecycle_unit);
 
   content::WebContentsTester::For(web_contents_)
-      ->SetIsConnectedToBluetoothDevice(true);
+      ->TestIncrementBluetoothConnectedDeviceCount();
 
   DecisionDetails decision_details;
   EXPECT_FALSE(tab_lifecycle_unit.CanFreeze(&decision_details));
@@ -805,7 +805,7 @@
             decision_details.FailureReason());
 
   content::WebContentsTester::For(web_contents_)
-      ->SetIsConnectedToBluetoothDevice(false);
+      ->TestDecrementBluetoothConnectedDeviceCount();
 }
 
 TEST_F(TabLifecycleUnitTest, CannotFreezeIfHoldingWebLock) {
diff --git a/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn b/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
index b17286e3..0e206c1 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
+++ b/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
@@ -125,6 +125,7 @@
 js_library("util") {
   deps = [
     ":tooltip",
+    ":type",
     "browser_proxy:browser_proxy",
     "mojo:chrome_helper",
   ]
diff --git a/chrome/browser/resources/chromeos/camera/src/js/main.js b/chrome/browser/resources/chromeos/camera/src/js/main.js
index 78c49bc..e2551b0 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/main.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/main.js
@@ -151,8 +151,9 @@
 
   /**
    * Starts the app by loading the model and opening the camera-view.
+   * @return {!Promise}
    */
-  start() {
+  async start() {
     var ackMigrate = false;
     cca.models.FileSystem
         .initialize(() => {
@@ -183,6 +184,7 @@
         .finally(() => {
           cca.metrics.log(cca.metrics.Type.LAUNCH, ackMigrate);
         });
+    await cca.util.fitWindow();
     chrome.app.window.current().show();
     this.backgroundOps_.notifyActivation();
   }
@@ -235,5 +237,5 @@
   assert(window['backgroundOps'] !== undefined);
   cca.App.instance_ = new cca.App(
       /** @type {!cca.bg.BackgroundOps} */ (window['backgroundOps']));
-  cca.App.instance_.start();
+  await cca.App.instance_.start();
 });
diff --git a/chrome/browser/resources/chromeos/camera/src/js/util.js b/chrome/browser/resources/chromeos/camera/src/js/util.js
index d3969255..72db675 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/util.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/util.js
@@ -15,6 +15,11 @@
 cca.util = cca.util || {};
 
 /**
+ * import {Resolution} from '../type.js';
+ */
+var Resolution = Resolution || {};
+
+/**
  * Gets the clockwise rotation and flip that can orient a photo to its upright
  * position.
  * @param {!Blob} blob JPEG blob that might contain EXIF orientation field.
@@ -395,3 +400,53 @@
   element.checked = checked;
   element.dispatchEvent(new Event('change'));
 };
+
+/**
+ * Sets CCA window inner bound to size which can fit in current screen.
+ * @return {!Promise} Promise which is resolved when size change actually
+ *     happen or is resolved immediately when there is no need to change.
+ */
+cca.util.fitWindow = function() {
+  const appWindow = chrome.app.window.current();
+
+  /**
+   * Get a preferred window size which can fit in current screen.
+   * @return {Resolution} Preferred window size.
+   */
+  const getPreferredWindowSize = () => {
+    const inner = appWindow.innerBounds;
+    const outer = appWindow.outerBounds;
+
+    const predefinedWidth = inner.minWidth;
+    const availableWidth = screen.availWidth;
+
+    const topBarHeight = outer.height - inner.height;
+    const fixedRatioMaxWidth =
+        Math.floor((screen.availHeight - topBarHeight) * 16 / 9);
+
+    let preferredWidth =
+        Math.min(predefinedWidth, availableWidth, fixedRatioMaxWidth);
+    preferredWidth -= preferredWidth % 16;
+    const preferredHeight = preferredWidth * 9 / 16;
+
+    return new Resolution(preferredWidth, preferredHeight);
+  };
+
+  const {width, height} = getPreferredWindowSize();
+
+  return new Promise((resolve) => {
+    const inner = appWindow.innerBounds;
+    if (inner.width === width && inner.height === height) {
+      resolve();
+      return;
+    }
+
+    const listener = () => {
+      appWindow.onBoundsChanged.removeListener(listener);
+      resolve();
+    };
+    appWindow.onBoundsChanged.addListener(listener);
+
+    Object.assign(inner, {width, height, minWidth: width, minHeight: height});
+  });
+};
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
index 018b22f..1d67fd3 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
@@ -89,15 +89,6 @@
      */
     this.resizeWindowTimeout_ = null;
 
-    /**
-     * Aspect ratio for the window.
-     * @type {number}
-     * @private
-     */
-    this.aspectRatio_ = 1;
-
-    var inner = chrome.app.window.current().innerBounds;
-    this.aspectRatio_ = inner.width / inner.height;
     window.addEventListener('resize', () => this.onWindowResize_());
 
     ['expert', 'show-metadata'].forEach((state) => {
@@ -400,32 +391,6 @@
   }
 
   /**
-   * Sets CCA window inner bound to specified size.
-   * @param {number} width Width and min width of new window inner bound.
-   * @param {number} height Height and min height of new window inner bound.
-   * @return {!Promise} Promise which is resolved when size change actually
-   *     happen.
-   * @private
-   */
-  setWindowSize_(width, height) {
-    return new Promise((resolve) => {
-      const listener = () => {
-        chrome.app.window.current().onBoundsChanged.removeListener(listener);
-        resolve();
-      };
-      chrome.app.window.current().onBoundsChanged.addListener(listener);
-      const inner = chrome.app.window.current().innerBounds;
-      const prevW = inner.width;
-      const prevH = inner.height;
-      inner.minWidth = inner.width = width;
-      inner.minHeight = inner.height = height;
-      if (prevW === width && prevH === height) {
-        listener();
-      }
-    });
-  }
-
-  /**
    * Handles resizing the window for preview's aspect ratio changes.
    * @param {number=} aspectRatio Aspect ratio changed.
    * @return {!Promise}
@@ -442,7 +407,6 @@
     // by the last known window's aspect ratio.
     return new Promise((resolve) => {
              if (aspectRatio) {
-               this.aspectRatio_ = aspectRatio;
                resolve();
              } else {
                this.resizeWindowTimeout_ = setTimeout(() => {
@@ -457,10 +421,7 @@
           if (cca.util.isWindowFullSize()) {
             return;
           }
-          const width = chrome.app.window.current().innerBounds.minWidth;
-          assert(width !== undefined);
-          const height = Math.round(width * 9 / 16);
-          return this.setWindowSize_(width, height);
+          return cca.util.fitWindow();
         });
   }
 
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html
index 942f32f..d4c847f1 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.html
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -13,21 +13,26 @@
     <link rel="stylesheet" href="oobe_eula.css">
     <link rel="stylesheet" href="oobe_flex_layout.css">
     <oobe-dialog id="eulaLoadingDialog" hidden="[[!eulaLoadingScreenShown]]"
-        role="dialog" i18n-values="aria-label:termsOfServiceLoading"
-        has-buttons full-screen-dialog>
+        role="dialog" aria-labelledby="loadingTitle" has-buttons
+        full-screen-dialog>
       <iron-icon icon="oobe-eula:googleg" slot="oobe-icon"></iron-icon>
-      <h1 slot="title">[[i18nDynamic(locale, 'termsOfServiceLoading')]]</h1>
+      <h1 slot="title" id="loadingTitle">
+        [[i18nDynamic(locale, 'termsOfServiceLoading')]]
+      </h1>
     </oobe-dialog>
     <oobe-dialog id="eulaDialog" hidden="[[eulaLoadingScreenShown]]"
-        role="dialog" i18n-values="aria-label:oobeEulaSectionTitle"
+        role="dialog" aria-labelledby="eulaTitle"
+        aria-describedby="crosEulaFrame"
         has-buttons>
       <hd-iron-icon slot="oobe-icon"
           icon1x="oobe-32:googleg" icon2x="oobe-64:googleg">
       </hd-iron-icon>
-      <h1 slot="title">[[i18nDynamic(locale, 'oobeEulaSectionTitle')]]</h1>
+      <h1 slot="title" id="eulaTitle">
+        [[i18nDynamic(locale, 'oobeEulaSectionTitle')]]
+      </h1>
       <div slot="footer" class="flex layout vertical">
         <webview id="crosEulaFrame" allowTransparency
-            role="document" class="focus-on-show flex oobe-tos-webview"
+            role="document" class="flex oobe-tos-webview"
             i18n-values="aria-label:oobeEulaIframeLabel"
             on-contentload="onFrameLoad_">
         </webview>
@@ -55,6 +60,7 @@
         <div class="flex">
         </div>
         <oobe-text-button id="acceptButton" inverse on-tap="eulaAccepted_"
+            class="focus-on-show"
             disabled="[[acceptButtonDisabled]]">
           <div>
             [[i18nDynamic(locale, 'oobeEulaAcceptAndContinueButtonText')]]
@@ -63,15 +69,15 @@
       </div>
     </oobe-dialog>
     <oobe-dialog id="installationSettingsDialog" role="dialog"
-        has-buttons hidden>
+        aria-labelledby="settingsTitle" has-buttons hidden>
       <hd-iron-icon slot="oobe-icon"
           icon1x="oobe-32:googleg" icon2x="oobe-64:googleg">
       </hd-iron-icon>
-      <h1 slot="title">
+      <h1 slot="title" id="settingsTitle">
         [[i18nDynamic(locale, 'eulaSystemInstallationSettings')]]
       </h1>
       <!-- TODO(antrim): find out why do we have everything in subtitle -->
-      <div slot="subtitle">
+      <div slot="subtitle" id="settingsSubtitle">
         <div>
           [[i18nDynamic(locale, 'eulaTpmDesc')]]
         </div>
@@ -99,6 +105,7 @@
       <div slot="bottom-buttons" class="flex layout horizontal">
         <div class="flex"></div>
         <oobe-text-button id="settings-close-button" inverse
+            class="focus-on-show"
             on-tap="onInstallationSettingsCloseClicked_">
           <div>
             [[i18nDynamic(locale, 'eulaSystemInstallationSettingsOkButton')]]
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.js b/chrome/browser/resources/chromeos/login/oobe_eula.js
index 09f3048..c6c8769 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.js
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.js
@@ -152,7 +152,7 @@
     chrome.send('eulaOnInstallationSettingsPopupOpened');
     this.$.eulaDialog.hidden = true;
     this.$.installationSettingsDialog.hidden = false;
-    this.$['settings-close-button'].focus();
+    this.$.installationSettingsDialog.show();
   },
 
   /**
@@ -163,6 +163,7 @@
   onInstallationSettingsCloseClicked_: function() {
     this.$.installationSettingsDialog.hidden = true;
     this.$.eulaDialog.hidden = false;
+    this.$.eulaDialog.show();
   },
 
   /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_network.js b/chrome/browser/resources/chromeos/login/oobe_network.js
index 52c388c0a..79d4cb7 100644
--- a/chrome/browser/resources/chromeos/login/oobe_network.js
+++ b/chrome/browser/resources/chromeos/login/oobe_network.js
@@ -115,8 +115,13 @@
   onShown_: function() {
     this.async(function() {
       this.$.networkSelectLogin.refresh();
-      this.$.networkSelectLogin.focus();
-    }.bind(this));
+      if (this.isConnected_)
+        this.$.nextButton.focus();
+      else
+        this.$.networkSelectLogin.focus();
+    }.bind(this), 300);
+    // Timeout is a workaround to correctly propagate focus to
+    // RendererFrameHostImpl see https://crbug.com/955129 for details.
   },
 
   /**
diff --git a/chrome/browser/resources/feed_internals/feed_internals.js b/chrome/browser/resources/feed_internals/feed_internals.js
index 597a695..015521338 100644
--- a/chrome/browser/resources/feed_internals/feed_internals.js
+++ b/chrome/browser/resources/feed_internals/feed_internals.js
@@ -158,7 +158,8 @@
 
 document.addEventListener('DOMContentLoaded', function() {
   // Setup backend mojo.
-  pageHandler = feedInternals.mojom.PageHandler.getRemote();
+  pageHandler = feedInternals.mojom.PageHandler.getRemote(
+      /*useBrowserInterfaceBroker=*/ true);
 
   updatePageWithProperties();
   updatePageWithUserClass();
diff --git a/chrome/browser/resources/local_ntp/externs.js b/chrome/browser/resources/local_ntp/externs.js
index dff2b81..37a751b 100644
--- a/chrome/browser/resources/local_ntp/externs.js
+++ b/chrome/browser/resources/local_ntp/externs.js
@@ -537,4 +537,5 @@
 configData.translatedStrings.uploadImage;
 configData.translatedStrings.urlField;
 configData.translatedStrings.voiceCloseTooltip;
+configData.translatedStrings.voiceSearchClosed;
 configData.translatedStrings.waiting;
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html
index 7f2cf92..3c24062 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -400,6 +400,7 @@
       </div>
     </div>
   </dialog>
+  <div id="screen-reader-announcer" role="status" aria-live="polite"></div>
 
   <div id="one-google-end-of-body"></div>
 
diff --git a/chrome/browser/resources/local_ntp/voice.css b/chrome/browser/resources/local_ntp/voice.css
index a3118e7..01a8b4be 100644
--- a/chrome/browser/resources/local_ntp/voice.css
+++ b/chrome/browser/resources/local_ntp/voice.css
@@ -588,3 +588,9 @@
     border-color: rgb(var(--GG200-rgb));
   }
 }
+
+#screen-reader-announcer {
+  clip: rect(0, 0, 0, 0);
+  display: inline-block;
+  position: fixed;
+}
diff --git a/chrome/browser/resources/local_ntp/voice.js b/chrome/browser/resources/local_ntp/voice.js
index 46497631..bb8ce4fa 100644
--- a/chrome/browser/resources/local_ntp/voice.js
+++ b/chrome/browser/resources/local_ntp/voice.js
@@ -96,6 +96,8 @@
  */
 const speech = {};
 
+speech.SCREEN_READER_ANNOUNCER_ = 'screen-reader-announcer';
+
 /**
  * Localized translations for messages used in the Speech UI.
  * @type {{
@@ -321,6 +323,13 @@
     throw new Error('OnFocusChange handler already set on searchbox.');
   }
   searchboxApiHandle.onfocuschange = speech.onOmniboxFocused;
+  const dialog = $(view.DIALOG_ID_);
+  if (dialog) {
+    dialog.addEventListener('close', () => {
+      speech.screenReaderAnnounce_(translatedStrings.voiceSearchClosed);
+      fakeboxMicrophoneElem.focus();
+    });
+  }
 
   // Initialize speech internal state.
   speech.googleBaseUrl_ = googleBaseUrl;
@@ -919,6 +928,18 @@
   }
 };
 
+/**
+ * @param {string} message
+ * @private
+ */
+speech.screenReaderAnnounce_ = function(message) {
+  const annoucer = $(speech.SCREEN_READER_ANNOUNCER_);
+  annoucer.innerText = '';
+  setTimeout(() => {
+    annoucer.innerText = message;
+  }, 100);
+};
+
 /* TEXT VIEW */
 
 /**
diff --git a/chrome/browser/resources/new_tab_page/browser_proxy.js b/chrome/browser/resources/new_tab_page/browser_proxy.js
index 922801f..36ac6e1 100644
--- a/chrome/browser/resources/new_tab_page/browser_proxy.js
+++ b/chrome/browser/resources/new_tab_page/browser_proxy.js
@@ -17,7 +17,8 @@
     /** @type {newTabPage.mojom.PageHandlerRemote} */
     this.handler = new newTabPage.mojom.PageHandlerRemote();
 
-    const factory = newTabPage.mojom.PageHandlerFactory.getRemote();
+    const factory = newTabPage.mojom.PageHandlerFactory.getRemote(
+        /*useBrowserInterfaceBroker=*/ true);
     factory.createPageHandler(
         this.callbackRouter.$.bindNewPipeAndPassRemote(),
         this.handler.$.bindNewPipeAndPassReceiver());
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js
index 5b7d83a4..a25ce97 100644
--- a/chrome/browser/resources/omnibox/omnibox.js
+++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -77,7 +77,8 @@
         omniboxOutput.updateAnswerImage.bind(omniboxOutput));
 
     /** @private {!mojom.OmniboxPageHandlerRemote} */
-    this.handler_ = mojom.OmniboxPageHandler.getRemote();
+    this.handler_ =
+        mojom.OmniboxPageHandler.getRemote(/*useBrowserInterfaceBroker=*/ true);
     this.handler_.setClientPage(
         this.callbackRouter_.$.bindNewPipeAndPassRemote());
 
diff --git a/chrome/browser/resources/optimize_webui.py b/chrome/browser/resources/optimize_webui.py
index 3055403..5c11a65 100755
--- a/chrome/browser/resources/optimize_webui.py
+++ b/chrome/browser/resources/optimize_webui.py
@@ -7,6 +7,7 @@
 import itertools
 import json
 import os
+import glob
 import platform
 import re
 import shutil
@@ -114,10 +115,10 @@
 def _update_dep_file(in_folder, args, manifest):
   in_path = os.path.join(_CWD, in_folder)
 
-  # Gather the dependencies of all bundled root HTML files.
+  # Gather the dependencies of all bundled root files.
   request_list = []
-  for html_file in manifest:
-    request_list += manifest[html_file]
+  for out_file in manifest:
+    request_list += manifest[out_file]
 
   # Add a slash in front of every dependency that is not a chrome:// URL, so
   # that we can map it to the correct source file path below.
@@ -167,23 +168,31 @@
     f.close()
   return rollup_config_file;
 
-# Create the manifest file from the sourcemap generated by rollup.
-def _generate_manifest_file(
-    js_out_file, tmp_out_dir, in_path, manifest_out_path):
-  sourcemap_file = js_out_file + '.map';
-  with open(os.path.join(tmp_out_dir, sourcemap_file), 'r') as f:
-    sourcemap = json.loads(f.read())
-    if not 'sources' in sourcemap:
-      raise Exception('rollup could not construct source map')
-    sources = sourcemap['sources']
-    replaced_sources = []
-    for source in sources:
-      replaced_sources.append(
-          source.replace('../' + os.path.basename(in_path) + "/", ""))
-    manifest = { 'sources': replaced_sources };
-    with open(manifest_out_path, 'w') as f:
-      f.write(json.dumps(manifest))
-      f.close()
+# Create the manifest file from the sourcemap generated by rollup and return the
+# list of bundles.
+def _generate_manifest_file(tmp_out_dir, in_path, manifest_out_path):
+  generated_sourcemaps = glob.glob('%s/*.map' % tmp_out_dir)
+  manifest = {}
+  output_filenames = []
+  for sourcemap_file in generated_sourcemaps:
+    with open(sourcemap_file, 'r') as f:
+      sourcemap = json.loads(f.read())
+      if not 'sources' in sourcemap:
+        raise Exception('rollup could not construct source map')
+      sources = sourcemap['sources']
+      replaced_sources = []
+      for source in sources:
+        replaced_sources.append(
+            source.replace('../' + os.path.basename(in_path) + "/", ""))
+      filename = sourcemap_file[:-len('.map')]
+      manifest[os.path.basename(filename)] = replaced_sources
+      output_filenames.append(filename)
+
+  with open(manifest_out_path, 'w') as f:
+    f.write(json.dumps(manifest))
+    f.close()
+
+  return output_filenames
 
 def _bundle_v3(tmp_out_dir, in_path, out_path, manifest_out_path, args,
                excludes):
@@ -193,26 +202,48 @@
       os.path.abspath(_HERE_PATH), 'tools', 'rollup_plugin.js')
   rollup_config_file = _generate_rollup_config(tmp_out_dir, path_to_plugin,
                                                in_path, args.host, excludes)
+  rollup_args = [os.path.join(in_path, f) for f in args.js_module_in_files]
+
+  # Confirm names are as expected. This is necessary to avoid having to replace
+  # import statements in the generated output files.
+  # TODO(rbpotter): Is it worth adding import statement replacement to support
+  # arbitrary names?
   bundled_paths = []
-  for index, js_module_in_file in enumerate(args.js_module_in_files):
-    js_out_file = args.js_out_files[index]
-    rollup_js_out_file = '%s.rollup.js' % js_out_file[:-3]
-    rollup_js_out_path = os.path.join(tmp_out_dir, rollup_js_out_file)
-    node.RunNode(
-        [node_modules.PathToRollup()] + [
-            '--format', 'esm',
-            '--input', os.path.join(in_path, js_module_in_file),
-            '--file', rollup_js_out_path,
-            '--sourcemap', '--sourcemapExcludeSources',
-            '--config', rollup_config_file,
-            '--silent',
-        ])
+  for index, js_file in enumerate(args.js_module_in_files):
+    expected_name = '%s.rollup.js' % js_file[:-len('.js')]
+    assert args.js_out_files[index] == expected_name, \
+           'Output file corresponding to %s should be named %s.rollup.js' % \
+           (js_file, expected_name)
+    bundled_paths.append(os.path.join(tmp_out_dir, expected_name))
 
-    # Create the manifest file from the sourcemap generated by rollup.
-    _generate_manifest_file(rollup_js_out_file, tmp_out_dir, in_path,
-                            manifest_out_path)
+  # This indicates that rollup is expected to generate a shared chunk file as
+  # well as one file per module. Set its name using --chunkFileNames. Note:
+  # Currently, this only supports 2 entry points, which generate 2 corresponding
+  # outputs and 1 shared output.
+  if (len(args.js_out_files) == 3):
+    assert len(args.js_module_in_files) == 2, \
+           'Expect 2 module entry points for generating 3 outputs'
+    shared_file_name = args.js_out_files[2]
+    rollup_args += [ '--chunkFileNames', shared_file_name ]
+    bundled_paths.append(os.path.join(tmp_out_dir, shared_file_name))
 
-    bundled_paths.append(rollup_js_out_path)
+  node.RunNode(
+      [node_modules.PathToRollup()] + rollup_args + [
+          '--format', 'esm',
+          '--dir', tmp_out_dir,
+          '--entryFileNames', '[name].rollup.js',
+          '--sourcemap', '--sourcemapExcludeSources',
+          '--config', rollup_config_file,
+          '--silent',
+      ])
+
+  # Create the manifest file from the sourcemaps generated by rollup.
+  generated_paths = _generate_manifest_file(tmp_out_dir, in_path,
+                                            manifest_out_path)
+  assert len(generated_paths) == len(bundled_paths), \
+         'unexpected number of bundles - %s - generated by rollup' % \
+         (len(generated_paths))
+
   return bundled_paths
 
 def _bundle_v2(tmp_out_dir, in_path, out_path, manifest_out_path, args,
diff --git a/chrome/browser/resources/optimize_webui_test.py b/chrome/browser/resources/optimize_webui_test.py
index 86be89ab..ed92727a 100755
--- a/chrome/browser/resources/optimize_webui_test.py
+++ b/chrome/browser/resources/optimize_webui_test.py
@@ -44,24 +44,16 @@
     assert self._out_folder
     return open(os.path.join(self._out_folder, file_name), 'r').read()
 
-  def _run_optimize(self, depfile, html_in_file, html_out_file, js_out_file,
-                    js_module_in_file):
-    # TODO(dbeam): make it possible to _run_optimize twice? Is that useful?
+  def _run_optimize(self, input_args):
     assert not self._out_folder
     self._out_folder = self._create_tmp_dir()
-    args = [
-      '--depfile', os.path.join(self._out_folder,'depfile.d'),
+    # TODO(dbeam): make it possible to _run_optimize twice? Is that useful?
+    args = input_args + [
+      '--depfile', os.path.join(self._out_folder, 'depfile.d'),
       '--host', 'fake-host',
       '--input', self._tmp_src_dir,
-      '--js_out_files', js_out_file,
       '--out_folder', self._out_folder,
     ]
-    if (html_in_file):
-      args += [ '--html_in_files', html_in_file ];
-    if (html_out_file):
-      args += [ '--html_out_files', html_out_file ];
-    if (js_module_in_file):
-      args += [ '--js_module_in_files', js_module_in_file ];
     optimize_webui.main(args)
 
   def _write_files_to_src_dir(self):
@@ -140,11 +132,12 @@
 
   def testSimpleOptimize(self):
     self._write_files_to_src_dir()
-    self._run_optimize(depfile='depfile.d',
-                       html_in_file='ui.html',
-                       html_out_file='fast.html',
-                       js_out_file='fast.js',
-                       js_module_in_file='')
+    args = [
+      '--html_in_files', 'ui.html',
+      '--html_out_files', 'fast.html',
+      '--js_out_files', 'fast.js',
+    ]
+    self._run_optimize(args)
 
     fast_html = self._read_out_file('fast.html')
     self._check_output_html(fast_html)
@@ -154,22 +147,22 @@
 
   def testV3SimpleOptimize(self):
     self._write_v3_files_to_src_dir()
-    self._run_optimize(depfile='depfile.d',
-                       html_in_file='',
-                       html_out_file='',
-                       js_out_file='ui.rollup.js',
-                       js_module_in_file='ui.js')
+    args = [
+      '--js_module_in_files', 'ui.js',
+      '--js_out_files', 'ui.rollup.js',
+    ]
+    self._run_optimize(args)
 
     self._check_output_js('ui.rollup.js')
     self._check_output_depfile(False)
 
   def testV3OptimizeWithResources(self):
     self._write_v3_files_with_resources_to_src_dir()
-    self._run_optimize(depfile='depfile.d',
-                       html_in_file='',
-                       html_out_file='',
-                       js_out_file='ui.rollup.js',
-                       js_module_in_file='ui.js')
+    args = [
+      '--js_module_in_files', 'ui.js',
+      '--js_out_files', 'ui.rollup.js',
+    ]
+    self._run_optimize(args)
 
     ui_rollup_js = self._read_out_file('ui.rollup.js')
     self.assertIn('yay', ui_rollup_js)
@@ -187,5 +180,42 @@
         os.path.normpath('../gen/ui/webui/resources/js/fake_resource.m.js'),
         depfile_d)
 
+  def testV3MultiBundleOptimize(self):
+    self._write_v3_files_to_src_dir()
+    self._write_file_to_src_dir('lazy_element.js',
+                                "alert('hello from lazy_element');")
+    self._write_file_to_src_dir('lazy.js', '''
+import './lazy_element.js';
+import './element_in_dir/element_in_dir.js';
+''')
+
+    args = [
+      '--js_module_in_files', 'ui.js', 'lazy.js',
+      '--js_out_files', 'ui.rollup.js', 'lazy.rollup.js', 'shared.rollup.js',
+    ]
+    self._run_optimize(args)
+
+    # Check that the shared element is in the shared bundle and the non-shared
+    # elements are in the individual bundles.
+    ui_js = self._read_out_file('ui.rollup.js')
+    self.assertIn('yay', ui_js)
+    self.assertNotIn('hello from lazy_element', ui_js)
+    self.assertNotIn('hello from element_in_dir', ui_js)
+
+    lazy_js = self._read_out_file('lazy.rollup.js')
+    self.assertNotIn('yay', lazy_js)
+    self.assertIn('hello from lazy_element', lazy_js)
+    self.assertNotIn('hello from element_in_dir', lazy_js)
+
+    shared_js = self._read_out_file('shared.rollup.js')
+    self.assertNotIn('yay', shared_js)
+    self.assertNotIn('hello from lazy_element', shared_js)
+    self.assertIn('hello from element_in_dir', shared_js)
+
+    # All 3 JS files should be in the depfile.
+    self._check_output_depfile(False)
+    depfile_d = self._read_out_file('depfile.d')
+    self.assertIn('lazy_element.js', depfile_d)
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js
index d356d12..22500a2 100644
--- a/chrome/browser/resources/pdf/pdf_viewer.js
+++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -901,6 +901,13 @@
     document.documentElement.lang = stringsDictionary.language;
 
     loadTimeData.data = strings;
+
+    // Predefined zoom factors to be used when zooming in/out. These are in
+    // ascending order.
+    const presetZoomFactors = /** @type {!Array<number>} */ (
+        JSON.parse(loadTimeData.getString('presetZoomFactors')));
+    this.viewport_.setZoomFactorRange(presetZoomFactors);
+
     if (this.isPrintPreview_) {
       this.sendBackgroundColorForPrintPreview_();
     }
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 3034d9e..39c825b0 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -35,17 +35,6 @@
 let ViewportRect;
 
 /**
- * Clamps the zoom factor (or page scale factor) to be within the limits.
- * @param {number} factor The zoom/scale factor.
- * @return {number} The factor clamped within the limits.
- */
-function clampZoom(factor) {
-  return Math.max(
-      Viewport.ZOOM_FACTOR_RANGE.min,
-      Math.min(factor, Viewport.ZOOM_FACTOR_RANGE.max));
-}
-
-/**
  * @param {!ViewportRect} rect1
  * @param {!ViewportRect} rect2
  * @return {number} The area of the intersection of the rects
@@ -128,6 +117,13 @@
     /** @private {number} */
     this.internalZoom_ = 1;
 
+    /**
+     * Predefined zoom factors to be used when zooming in/out. These are in
+     * ascending order.
+     * @private {!Array<number>}
+     */
+    this.presetZoomFactors_ = [];
+
     /** @private {?ZoomManager} */
     this.zoomManager_ = null;
 
@@ -230,6 +226,28 @@
   }
 
   /**
+   * Clamps the zoom factor (or page scale factor) to be within the limits.
+   * @param {number} factor The zoom/scale factor.
+   * @return {number} The factor clamped within the limits.
+   * @private
+   */
+  clampZoom_(factor) {
+    return Math.max(
+        this.presetZoomFactors_[0],
+        Math.min(
+            factor,
+            this.presetZoomFactors_[this.presetZoomFactors_.length - 1]));
+  }
+
+  /**
+   * @param {!Array<number>} factors Array containing zoom/scale factors.
+   */
+  setZoomFactorRange(factors) {
+    assert(factors.length !== 0);
+    this.presetZoomFactors_ = factors;
+  }
+
+  /**
    * Converts a page position (e.g. the location of a bookmark) to a screen
    * position.
    * @param {number} page
@@ -532,7 +550,7 @@
         this.allowedToChangeZoom_,
         'Called Viewport.setPinchZoomInternal_ without calling ' +
             'Viewport.mightZoom_.');
-    this.internalZoom_ = clampZoom(this.internalZoom_ * scaleDelta);
+    this.internalZoom_ = this.clampZoom_(this.internalZoom_ * scaleDelta);
 
     const newCenterInContent = this.frameToContent_(center);
     const delta = {
@@ -574,7 +592,7 @@
   setZoom(newZoom) {
     this.fittingType_ = FittingType.NONE;
     this.mightZoom_(() => {
-      this.setZoomInternal_(clampZoom(newZoom));
+      this.setZoomInternal_(this.clampZoom_(newZoom));
       this.updateViewport_();
     });
   }
@@ -943,10 +961,10 @@
   zoomOut() {
     this.mightZoom_(() => {
       this.fittingType_ = FittingType.NONE;
-      let nextZoom = Viewport.ZOOM_FACTORS[0];
-      for (let i = 0; i < Viewport.ZOOM_FACTORS.length; i++) {
-        if (Viewport.ZOOM_FACTORS[i] < this.internalZoom_) {
-          nextZoom = Viewport.ZOOM_FACTORS[i];
+      let nextZoom = this.presetZoomFactors_[0];
+      for (let i = 0; i < this.presetZoomFactors_.length; i++) {
+        if (this.presetZoomFactors_[i] < this.internalZoom_) {
+          nextZoom = this.presetZoomFactors_[i];
         }
       }
       this.setZoomInternal_(nextZoom);
@@ -958,10 +976,11 @@
   zoomIn() {
     this.mightZoom_(() => {
       this.fittingType_ = FittingType.NONE;
-      let nextZoom = Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1];
-      for (let i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) {
-        if (Viewport.ZOOM_FACTORS[i] > this.internalZoom_) {
-          nextZoom = Viewport.ZOOM_FACTORS[i];
+      const maxZoomIndex = this.presetZoomFactors_.length - 1;
+      let nextZoom = this.presetZoomFactors_[maxZoomIndex];
+      for (let i = maxZoomIndex; i >= 0; i--) {
+        if (this.presetZoomFactors_[i] > this.internalZoom_) {
+          nextZoom = this.presetZoomFactors_[i];
         }
       }
       this.setZoomInternal_(nextZoom);
@@ -987,7 +1006,7 @@
 
       const needsScrollbars =
           this.documentNeedsScrollbars_(this.zoomManager_.applyBrowserZoom(
-              clampZoom(this.internalZoom_ * scaleDelta)));
+              this.clampZoom_(this.internalZoom_ * scaleDelta)));
 
       this.pinchCenter_ = e.center;
 
@@ -1254,23 +1273,6 @@
  */
 Viewport.SCROLL_INCREMENT = 40;
 
-/**
- * Predefined zoom factors to be used when zooming in/out. These are in
- * ascending order. This should match the lists in
- * components/zoom/page_zoom_constants.h and
- * chrome/browser/resources/settings/appearance_page/appearance_page.js
- */
-Viewport.ZOOM_FACTORS = [
-  0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3,
-  4, 5
-];
-
-/** The minimum and maximum range to be used to clip zoom factor. */
-Viewport.ZOOM_FACTOR_RANGE = {
-  min: Viewport.ZOOM_FACTORS[0],
-  max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1]
-};
-
 /** The width of the page shadow around pages in pixels. */
 Viewport.PAGE_SHADOW = {
   top: 3,
diff --git a/chrome/browser/resources/reset_password/reset_password.js b/chrome/browser/resources/reset_password/reset_password.js
index 886c65c..9c21b3c2 100644
--- a/chrome/browser/resources/reset_password/reset_password.js
+++ b/chrome/browser/resources/reset_password/reset_password.js
@@ -16,7 +16,8 @@
 let pageHandler;
 
 document.addEventListener('DOMContentLoaded', function() {
-  pageHandler = mojom.ResetPasswordHandler.getRemote();
+  pageHandler =
+      mojom.ResetPasswordHandler.getRemote(/*useBrowserInterfaceBroker=*/ true);
 
   /** @type {?HTMLElement} */
   const resetPasswordButton = $('reset-password-button');
diff --git a/chrome/browser/resources/settings/a11y_page/BUILD.gn b/chrome/browser/resources/settings/a11y_page/BUILD.gn
index 675ee8c..833247eb 100644
--- a/chrome/browser/resources/settings/a11y_page/BUILD.gn
+++ b/chrome/browser/resources/settings/a11y_page/BUILD.gn
@@ -44,6 +44,7 @@
   deps = [
     "..:route",
     "..:route_origin_behavior",
+    "../chromeos/localized_link:localized_link",
     "../device_page:device_page_browser_proxy",
     "//ui/webui/resources/js:load_time_data",
     "//ui/webui/resources/js:web_ui_listener_behavior",
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
index 0963ddc..22f9ef3 100644
--- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
+++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -12,6 +12,7 @@
 <link rel="import" href="../route.html">
 <link rel="import" href="../route_origin_behavior.html">
 <link rel="import" href="../settings_shared_css.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 
 <dom-module id="settings-manage-a11y-page">
   <template>
@@ -37,14 +38,11 @@
       }
     </style>
     <div class="settings-box row first">
-      <span>
-        $i18n{a11yExplanation}
-        <a href="$i18nRaw{a11yLearnMoreUrl}" target="_blank">
-          $i18n{learnMore}
-        </a>
-      </span>
+      <settings-localized-link
+          localized-string="$i18n{a11yExplanation}"
+          link-url="$i18nRaw{a11yLearnMoreUrl}">
+      </settings-localized-link>
     </div>
-
     <h2>$i18n{textToSpeechHeading}</h2>
     <settings-toggle-button class="first"
         pref="{{prefs.settings.accessibility}}"
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chrome/browser/resources/settings/appearance_page/appearance_page.js
index 582ae814c..ac937b0 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -64,33 +64,12 @@
     },
 
     /**
-     * List of options for the page zoom drop-down menu.
-     * @type {!Array<number>}
+     * Predefined zoom factors to be used when zooming in/out. These are in
+     * ascending order. Values are displayed in the page zoom drop-down menu
+     * as percentages.
+     * @private {!Array<number>}
      */
-    pageZoomLevels_: {
-      readOnly: true,
-      type: Array,
-      value: [
-        // TODO(dbeam): get these dynamically from C++ instead.
-        1 / 4,
-        1 / 3,
-        1 / 2,
-        2 / 3,
-        3 / 4,
-        4 / 5,
-        9 / 10,
-        1,
-        11 / 10,
-        5 / 4,
-        3 / 2,
-        7 / 4,
-        2,
-        5 / 2,
-        3,
-        4,
-        5,
-      ],
-    },
+    pageZoomLevels_: Array,
 
     /** @private */
     themeSublabel_: String,
@@ -154,6 +133,10 @@
     this.appearanceBrowserProxy_.getDefaultZoom().then(zoom => {
       this.defaultZoom_ = zoom;
     });
+
+    this.pageZoomLevels_ = /** @type {!Array<number>} */ (
+        JSON.parse(loadTimeData.getString('presetZoomFactors')));
+
     // <if expr="chromeos">
     this.wallpaperBrowserProxy_.isWallpaperSettingVisible().then(
         isWallpaperSettingVisible => {
diff --git a/chrome/browser/resources/settings/basic_page/BUILD.gn b/chrome/browser/resources/settings/basic_page/BUILD.gn
index 5cbc3c1c31..9a638da 100644
--- a/chrome/browser/resources/settings/basic_page/BUILD.gn
+++ b/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -15,7 +15,6 @@
     "..:page_visibility",
     "..:route",
     "..:search_settings",
-    "../android_apps_page:android_apps_browser_proxy",
     "../change_password_page:change_password_browser_proxy",
     "../chrome_cleanup_page:chrome_cleanup_proxy",
     "../prefs:prefs_behavior",
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html
index 4faf387..9b8eacf0 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -19,8 +19,6 @@
 
 <if expr="chromeos">
 <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="../android_apps_page/android_apps_browser_proxy.html">
-<link rel="import" href="../android_apps_page/android_apps_page.html">
 <link rel="import" href="../prefs/prefs_behavior.html">
 </if>
 
@@ -146,8 +144,8 @@
             </settings-autofill-page>
           </settings-section>
         </template>
-        <template is="dom-if" if="[[showPrivacyPageAndRedesign_(
-            pageVisibility.privacy, 'BASIC')]]" restamp>
+        <template is="dom-if" if="[[showPage_(pageVisibility.privacy)]]"
+            restamp>
           <settings-section page-title="$i18n{privacyPageTitle}"
               section="privacy">
             <settings-privacy-page prefs="{{prefs}}"
@@ -168,18 +166,6 @@
             section="search">
           <settings-search-page prefs="{{prefs}}"></settings-search-page>
         </settings-section>
-<if expr="chromeos">
-        <template is="dom-if" if="[[showAndroidApps]]" restamp>
-          <settings-section page-title="$i18n{androidAppsPageTitle}"
-              section="androidApps" hidden$="[[!shouldShowAndroidAppsSection_(
-              androidAppsInfo)]]">
-            <settings-android-apps-page prefs="{{prefs}}"
-                android-apps-info="[[androidAppsInfo]]"
-                have-play-store-app="[[havePlayStoreApp]]">
-            </settings-android-apps-page>
-          </settings-section>
-        </template>
-</if>
 <if expr="not chromeos">
         <template is="dom-if" if="[[showPage_(pageVisibility.defaultBrowser)]]"
             restamp>
@@ -218,15 +204,6 @@
           <div id="advancedPage" hidden$="[[!showAdvancedPage_(
               currentRoute_, inSearchMode, hasExpandedSection_,
               advancedToggleExpanded)]]">
-            <template is="dom-if" if="[[showPrivacyPageAndRedesign_(
-                pageVisibility.privacy, 'ADVANCED')]]" restamp>
-              <settings-section page-title="$i18n{privacyPageTitle}"
-                  section="privacy">
-                <settings-privacy-page prefs="{{prefs}}"
-                    page-visibility="[[pageVisibility.privacy]]">
-                </settings-privacy-page>
-              </settings-section>
-            </template>
             <template is="dom-if" if="[[showPage_(pageVisibility.languages)]]"
                 restamp>
               <settings-section page-title="$i18n{languagesPageTitle}"
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js
index 44037e3..f30d89c3 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -43,15 +43,6 @@
       notify: true,
     },
 
-    // <if expr="chromeos">
-    showAndroidApps: Boolean,
-
-    havePlayStoreApp: Boolean,
-    // </if>
-
-    /** @type {!AndroidAppsInfo|undefined} */
-    androidAppsInfo: Object,
-
     showChangePassword: {
       type: Boolean,
       value: false,
@@ -145,13 +136,6 @@
     this.addWebUIListener('change-password-visibility', visibility => {
       this.showChangePassword = visibility;
     });
-
-    if (settings.AndroidAppsBrowserProxyImpl) {
-      this.addWebUIListener(
-          'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this));
-      settings.AndroidAppsBrowserProxyImpl.getInstance()
-          .requestAndroidAppsInfo();
-    }
   },
 
   /**
@@ -196,20 +180,6 @@
   },
 
   /**
-   * @param {boolean|undefined} visibility
-   * @param {string} location
-   * @return {boolean}
-   * @private
-   */
-  showPrivacyPageAndRedesign_: function(visibility, location) {
-    if (!this.showPage_(visibility)) {
-      return false;
-    }
-    return (location == 'BASIC') ==
-        loadTimeData.getBoolean('privacySettingsRedesignEnabled');
-  },
-
-  /**
    * Queues a task to search the basic sections, then another for the advanced
    * sections.
    * @param {string} query The text to search for.
@@ -313,29 +283,6 @@
   },
 
   /**
-   * @param {!AndroidAppsInfo} info
-   * @private
-   */
-  androidAppsInfoUpdate_: function(info) {
-    this.androidAppsInfo = info;
-  },
-
-  /**
-   * Returns true in case Android apps settings should be shown. It is not
-   * shown in case we don't have the Play Store app and settings app is not
-   * yet available.
-   * @return {boolean}
-   * @private
-   */
-  shouldShowAndroidAppsSection_: function() {
-    if (this.havePlayStoreApp ||
-        (this.androidAppsInfo && this.androidAppsInfo.settingsAppAvailable)) {
-      return true;
-    }
-    return false;
-  },
-
-  /**
    * Hides everything but the newly expanded subpage.
    * @private
    */
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index 934181a..70a9023 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -75,6 +75,7 @@
     "bluetooth_page:closure_compile",
     "crostini_page:closure_compile",
     "date_time_page:closure_compile",
+    "google_assistant_page:closure_compile",
     "internet_page:closure_compile",
     "localized_link:closure_compile",
     "os_a11y_page:closure_compile",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
index aeb8b4f..6ca3753 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
@@ -20,6 +20,7 @@
   deps = [
     ":crostini_browser_proxy",
     "../..:route",
+    "../localized_link:localized_link",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
     "//ui/webui/resources/js:i18n_behavior",
     "//ui/webui/resources/js:web_ui_listener_behavior",
@@ -44,6 +45,7 @@
     ":crostini_browser_proxy",
     "../..:route",
     "../../prefs:prefs_behavior",
+    "../localized_link:localized_link",
     "//ui/webui/resources/js:i18n_behavior",
   ]
   externs_list = [ "$externs_path/settings_private.js" ]
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html
index 9f1dad8..f0f74bf 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html
@@ -6,6 +6,7 @@
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="crostini_browser_proxy.html">
 <link rel="import" href="crostini_arc_adb_confirmation_dialog.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="../../i18n_setup.html">
 <link rel="import" href="../../settings_shared_css.html">
 
@@ -24,9 +25,11 @@
     <div class="settings-box continuation">
       <div id="enableArcAdbLabel" class="start">
         $i18n{crostiniArcAdbLabel}
-        <div class="secondary" hidden="[[!arcAdbNeedPowerwash_]]"
-            inner-h-t-m-l="[[i18nAdvanced(
+        <div class="secondary" hidden="[[!arcAdbNeedPowerwash_]]">
+          <settings-localized-link
+              localized-string="[[i18nAdvanced(
                 'crostiniArcAdbPowerwashRequiredSublabel')]]">
+          </settings-localized-link>
         </div>
       </div>
       <cr-policy-indicator indicator-type="[[getPolicyIndicatorType_(
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html
index 7171760..37c70ad 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.html
@@ -9,6 +9,7 @@
 <link rel="import" href="../../settings_page/settings_animated_pages.html">
 <link rel="import" href="../../settings_page/settings_subpage.html">
 <link rel="import" href="../../settings_shared_css.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="crostini_arc_adb.html">
 <link rel="import" href="crostini_browser_proxy.html">
 <link rel="import" href="crostini_export_import.html">
@@ -28,8 +29,10 @@
             on-click="onSubpageTap_">
           <div class="start">
             $i18n{crostiniPageLabel}
-            <div class="secondary" id="secondaryText"
-                inner-h-t-m-l="[[i18nAdvanced('crostiniSubtext')]]">
+            <div class="secondary" id="secondaryText">
+              <settings-localized-link
+                  localized-string="[[i18nAdvanced('crostiniSubtext')]]">
+              </settings-localized-link>
             </div>
           </div>
           <template is="dom-if" if="[[!allowCrostini]]" restamp>
diff --git a/chrome/browser/resources/settings/google_assistant_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/google_assistant_page/BUILD.gn
similarity index 83%
rename from chrome/browser/resources/settings/google_assistant_page/BUILD.gn
rename to chrome/browser/resources/settings/chromeos/google_assistant_page/BUILD.gn
index b75831dd..5eb6954 100644
--- a/chrome/browser/resources/settings/google_assistant_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/BUILD.gn
@@ -21,8 +21,10 @@
 js_library("google_assistant_page") {
   deps = [
     ":google_assistant_browser_proxy",
-    "../prefs:prefs_behavior",
+    "../../prefs:prefs_behavior",
     "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
     "//ui/webui/resources/js:load_time_data",
+    "//ui/webui/resources/js:web_ui_listener_behavior",
   ]
 }
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_browser_proxy.html b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.html
similarity index 100%
rename from chrome/browser/resources/settings/google_assistant_page/google_assistant_browser_proxy.html
rename to chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.html
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_browser_proxy.js b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
similarity index 97%
rename from chrome/browser/resources/settings/google_assistant_page/google_assistant_browser_proxy.js
rename to chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
index c2ef77d..b920b539 100644
--- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.js
@@ -11,7 +11,7 @@
   /** @interface */
   class GoogleAssistantBrowserProxy {
     /** Launches into the Google Assistant app settings. */
-    launchGoogleAssistantSettings() {}
+    showGoogleAssistantSettings() {}
 
     /** Retrain the Assistant voice model. */
     retrainAssistantVoiceModel() {}
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
similarity index 92%
rename from chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
rename to chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
index 721bb79..64f63113 100644
--- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html
@@ -7,13 +7,13 @@
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
 <link rel="import" href="google_assistant_browser_proxy.html">
-<link rel="import" href="../controls/controlled_button.html">
-<link rel="import" href="../controls/settings_toggle_button.html">
-<link rel="import" href="../i18n_setup.html">
-<link rel="import" href="../prefs/prefs.html">
-<link rel="import" href="../prefs/prefs_behavior.html">
-<link rel="import" href="../settings_shared_css.html">
-<link rel="import" href="../prefs/pref_util.html">
+<link rel="import" href="../../controls/controlled_button.html">
+<link rel="import" href="../../controls/settings_toggle_button.html">
+<link rel="import" href="../../i18n_setup.html">
+<link rel="import" href="../../prefs/prefs.html">
+<link rel="import" href="../../prefs/prefs_behavior.html">
+<link rel="import" href="../../settings_shared_css.html">
+<link rel="import" href="../../prefs/pref_util.html">
 
 <dom-module id="settings-google-assistant-page">
   <template>
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
similarity index 96%
rename from chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
rename to chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
index 5237e01..7ed6245 100644
--- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
+++ b/chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.js
@@ -96,10 +96,8 @@
       value: false,
     },
 
-    /** @private */
-    dspHotwordState_: {
-      type: DspHotwordState,
-    }
+    /** @private {DspHotwordState} */
+    dspHotwordState_: Number,
   },
 
   observers: [
@@ -199,8 +197,8 @@
         !loadTimeData.getBoolean('voiceMatchDisabled') &&
         this.getPref('settings.voice_interaction.hotword.enabled.value') &&
         (this.getPref(
-          'settings.voice_interaction.activity_control.consent_status.value') ==
-            ConsentStatus.kActivityControlAccepted);
+             'settings.voice_interaction.activity_control.consent_status.value') ==
+         ConsentStatus.kActivityControlAccepted);
 
     const hotwordEnabled =
         this.getPref('settings.voice_interaction.hotword.enabled');
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
index 2a90471..7926668 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
@@ -17,6 +17,7 @@
     "../../about_page:about_page_browser_proxy",
     "../../settings_page:main_page_behavior",
     "../../settings_page:settings_animated_pages",
+    "../localized_link:localized_link",
     "//ui/webui/resources/js:assert",
     "//ui/webui/resources/js:i18n_behavior",
     "//ui/webui/resources/js:parse_html_subset",
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
index 382b53c..3ce8f387 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -17,6 +17,7 @@
 <link rel="import" href="../../settings_shared_css.html">
 <link rel="import" href="../os_icons.html">
 <link rel="import" href="../os_reset_page/os_powerwash_dialog.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
@@ -116,11 +117,11 @@
                   $i18n{learnMore}
                 </a>
               </div>
-             <div id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]">
-               $i18n{endOfLifeMessage}
-               <a href="$i18n{endOfLifeLearnMoreURL}" target="_blank">
-                 $i18n{learnMore}
-               </a>
+              <div id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]">
+                <settings-localized-link
+                    localized-string="$i18n{endOfLifeMessage}"
+                    link-url="$i18n{endOfLifeLearnMoreURL}">
+                </settings-localized-link>
              </div>
               <div class="secondary">$i18n{aboutBrowserVersion}</div>
             </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
index 664cc90..5c5c450 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
@@ -17,6 +17,7 @@
     "../../android_apps_page:android_apps_subpage",
     "../../prefs:prefs_behavior",
     "../../settings_page:settings_animated_pages",
+    "../localized_link:localized_link",
     "app_management_page",
     "//ui/webui/resources/js:cr",
     "//ui/webui/resources/js:i18n_behavior",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html
index 2ccf521..812ae12 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.html
@@ -14,6 +14,7 @@
 <link rel="import" href="../../settings_page/settings_subpage.html">
 <link rel="import" href="../../settings_shared_css.html">
 <link rel="import" href="../../settings_shared_css.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="app_management_page/app_management_page.html">
 <link rel="import" href="app_management_page/app_detail_view.html">
 <link rel="import" href="app_management_page/uninstall_button.html">
@@ -46,8 +47,10 @@
               on-click="onAndroidAppsSubpageTap_">
             <div class="start settings-box-text">
               $i18n{androidAppsPageLabel}
-              <div class="secondary" id="secondaryText"
-                  inner-h-t-m-l="[[i18nAdvanced('androidAppsSubtext')]]">
+              <div class="secondary" id="secondaryText">
+                <settings-localized-link
+                    localized-string="[[i18nAdvanced('androidAppsSubtext')]]">
+                </settings-localized-link>
               </div>
             </div>
             <cr-policy-pref-indicator pref="[[prefs.arc.enabled]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn
index 38ac772..ffe076d2 100644
--- a/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn
@@ -14,6 +14,7 @@
 js_library("smb_shares_page") {
   deps = [
     "../..:route",
+    "../localized_link:localized_link",
     "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy",
   ]
 }
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.html b/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.html
index 23cce5a..3b7da3e 100644
--- a/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.html
@@ -6,6 +6,7 @@
 <link rel="import" href="chrome://resources/html/action_link.html">
 <link rel="import" href="chrome://resources/cr_elements/action_link_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="../../route.html">
 <link rel="import" href="../../settings_shared_css.html">
 <link rel="import" href="../../settings_vars_css.html">
@@ -15,10 +16,10 @@
     <style include="settings-shared"></style>
     <div class="settings-box first">
       <div class="start">
-        <span>$i18n{smbSharesLearnMoreLabel}</span>
-        <a href="$i18n{smbSharesLearnMoreURL}" target="_blank">
-          $i18n{learnMore}
-        </a>
+         <settings-localized-link
+             localized-string="$i18n{smbSharesLearnMoreLabel}"
+             link-url="$i18n{smbSharesLearnMoreURL}">
+         </settings-localized-link>
       </div>
       <template is="dom-if" if="[[!prefs.network_file_shares.allowed.value]]"
           restamp>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
index 38b28886..c5783ca3 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -38,6 +38,7 @@
     "../..:route",
     "../../languages_page:languages_types",
     "../../settings_page:settings_animated_pages",
+    "../localized_link:localized_link",
     "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
     "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button",
     "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render",
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html
index de3a4ff..489be1e 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html
@@ -18,6 +18,7 @@
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="os_add_languages_dialog.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="../../controls/controlled_radio_button.html">
 <link rel="import" href="../../controls/settings_radio_group.html">
 <link rel="import" href="../../controls/settings_toggle_button.html">
@@ -146,10 +147,10 @@
 
       <span class="settings-box first"
           hidden="[[isHelpTextHidden_(languages.enabled.*)]]">
-        <span>$i18n{orderLanguagesInstructions}</span>
-        <a href="$i18n{languagesLearnMoreURL}" target="_blank">
-          $i18n{learnMore}
-        </a>
+        <settings-localized-link
+            localized-string="$i18n{orderLanguagesInstructions}"
+            link-url="$i18n{languagesLearnMoreURL}">
+        </settings-localized-link>
       </span>
       <div class="list-frame vertical-list" id="languagesList">
         <template is="dom-repeat" items="[[languages.enabled]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
index 11d0c4e3..f7c0a68 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
@@ -36,6 +36,7 @@
     "../../:page_visibility",
     "../../:route",
     "../../settings_page:settings_animated_pages",
+    "../localized_link:localized_link",
     "//chrome/browser/resources/settings/people_page:lock_screen",
     "//chrome/browser/resources/settings/people_page:lock_state_behavior",
     "//chrome/browser/resources/settings/people_page:profile_info_browser_proxy",
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
index 15b38ce..5e4270e1 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
@@ -32,6 +32,7 @@
 <link rel="import" href="../../settings_page/settings_animated_pages.html">
 <link rel="import" href="../../settings_page/settings_subpage.html">
 <link rel="import" href="../../settings_shared_css.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="os_sync_controls.html">
 
 <dom-module id="os-settings-people-page">
@@ -114,10 +115,10 @@
             <div class="settings-box two-line" id="sync-overview"
                 hidden="[[!syncStatus.signinAllowed]]">
               <div class="start settings-box-text">
-                $i18n{syncOverview}
-                <a target="_blank" href="$i18n{syncLearnMoreUrl}">
-                  $i18n{learnMore}
-                </a>
+                <settings-localized-link
+                    localized-string="$i18n{syncOverview}"
+                    link-url="$i18n{syncLearnMoreUrl}">
+                </settings-localized-link>
               </div>
             </div>
         </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn
index 42ff0d0..3a3d3ef5 100644
--- a/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn
@@ -16,6 +16,7 @@
   deps = [
     ":os_reset_browser_proxy",
     "../..:lifetime_browser_proxy",
+    "../localized_link:localized_link",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/chromeos/os_reset_page/os_powerwash_dialog.html b/chrome/browser/resources/settings/chromeos/os_reset_page/os_powerwash_dialog.html
index 51a81006..0634932 100644
--- a/chrome/browser/resources/settings/chromeos/os_reset_page/os_powerwash_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/os_reset_page/os_powerwash_dialog.html
@@ -3,6 +3,7 @@
 <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
 <link rel="import" href="os_reset_browser_proxy.html">
+<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="../../lifetime_browser_proxy.html">
 <link rel="import" href="../../settings_shared_css.html">
 
@@ -13,12 +14,10 @@
         ignore-enter-key>
       <div slot="title">$i18n{powerwashDialogTitle}</div>
       <div slot="body">
-        <span>
-          $i18n{powerwashDialogExplanation}
-          <a href="$i18nRaw{powerwashLearnMoreUrl}" target="_blank">
-            $i18n{learnMore}
-          </a>
-        </span>
+        <settings-localized-link
+            localized-string="$i18n{powerwashDialogExplanation}"
+            link-url="$i18nRaw{powerwashLearnMoreUrl}">
+        </settings-localized-link>
       </div>
       <div slot="button-container">
         <cr-button class="cancel-button" on-click="onCancelTap_"
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html
index ee0c4f1..727f2d91 100644
--- a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html
@@ -9,8 +9,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tooltip/paper-tooltip.html">
 <link rel="import" href="../../controls/extension_controlled_indicator.html">
-<link rel="import" href="../../google_assistant_page/google_assistant_page.html">
-<link rel="import" href="../../google_assistant_page/google_assistant_browser_proxy.html">
+<link rel="import" href="../google_assistant_page/google_assistant_page.html">
 <link rel="import" href="../../icons.html">
 <link rel="import" href="../../i18n_setup.html">
 <link rel="import" href="../../route.html">
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.html b/chrome/browser/resources/settings/controls/controlled_radio_button.html
index de6672a..3251e15 100644
--- a/chrome/browser/resources/settings/controls/controlled_radio_button.html
+++ b/chrome/browser/resources/settings/controls/controlled_radio_button.html
@@ -37,7 +37,7 @@
         class="disc-wrapper"
         id="button"
         role="radio"
-        tabindex="0"
+        tabindex$="[[buttonTabIndex_]]"
         on-keydown="onInputKeydown_">
       <div class="disc-border"></div>
       <div class="disc"></div>
diff --git a/chrome/browser/resources/settings/device_page/pointers.html b/chrome/browser/resources/settings/device_page/pointers.html
index 9304c57..310b2d9d 100644
--- a/chrome/browser/resources/settings/device_page/pointers.html
+++ b/chrome/browser/resources/settings/device_page/pointers.html
@@ -96,9 +96,9 @@
         <div class="settings-box">$i18n{scrollLabel}</div>
         <div class="list-frame">
           <settings-radio-group
-              pref="{{prefs.settings.touchpad.natural_scroll}}">
-            <cr-radio-button name="false">
-              $i18n{traditionalScrollLabel}
+              pref="{{prefs.settings.touchpad.natural_scroll}}"
+              group-aria-label="$i18n{scrollLabel}">
+            <cr-radio-button name="false" label="$i18n{traditionalScrollLabel}">
             </cr-radio-button>
             <cr-radio-button name="true">
               <settings-localized-link
diff --git a/chrome/browser/resources/settings/downloads_page/BUILD.gn b/chrome/browser/resources/settings/downloads_page/BUILD.gn
index 044f3b72..cbed10c 100644
--- a/chrome/browser/resources/settings/downloads_page/BUILD.gn
+++ b/chrome/browser/resources/settings/downloads_page/BUILD.gn
@@ -25,6 +25,7 @@
   js_library("smb_shares_page") {
     deps = [
       "..:route",
+      "../chromeos/localized_link:localized_link",
       "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy",
       "//ui/webui/resources/js:web_ui_listener_behavior",
     ]
diff --git a/chrome/browser/resources/settings/downloads_page/smb_shares_page.html b/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
index a5dfd95..d05663e 100644
--- a/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
+++ b/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
@@ -6,6 +6,7 @@
 <link rel="import" href="chrome://resources/html/action_link.html">
 <link rel="import" href="chrome://resources/cr_elements/action_link_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 <link rel="import" href="../route.html">
 <link rel="import" href="../settings_shared_css.html">
 <link rel="import" href="../settings_vars_css.html">
@@ -15,10 +16,10 @@
     <style include="settings-shared"></style>
     <div class="settings-box first">
       <div class="start">
-        <span>$i18n{smbSharesLearnMoreLabel}</span>
-        <a href="$i18n{smbSharesLearnMoreURL}" target="_blank">
-          $i18n{learnMore}
-        </a>
+        <settings-localized-link
+            localized-string="$i18n{smbSharesLearnMoreLabel}"
+            link-url="$i18n{smbSharesLearnMoreURL}">
+        </settings-localized-link>
       </div>
       <template is="dom-if" if="[[!prefs.network_file_shares.allowed.value]]"
           restamp>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
index b3e7076e..b4fc312b 100644
--- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
+++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
@@ -42,7 +42,8 @@
             </template>
             <div class$=
                 "[[getMultiDeviceItemLabelBlockCssClass_(pageContentData)]]
-                    settings-box-text">
+                    settings-box-text"
+                aria-hidden$="[[getTextAriaHidden_(pageContentData)]]">
               <div id="multidevice-label">
                 [[getLabelText_(pageContentData)]]
               </div>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
index 51e8c67..e2e57f6 100644
--- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
+++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
@@ -159,6 +159,21 @@
   },
 
   /**
+   * @return {string} "true" or "false" indicating whether the text box
+   *                  should be aria-hidden or not.
+   * @private
+   */
+  getTextAriaHidden_: function() {
+    // When host is set and verified, we only show subpage arrow button and
+    // toggle. In this case, we avoid the navigation stops on the text to make
+    // navigating easier. The arrow button is labeled and described by the text,
+    // so the text is still available to assistive tools.
+    return String(
+        this.pageContentData.mode ===
+        settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED);
+  },
+
+  /**
    * @return {boolean}
    * @private
    */
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.html b/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.html
index 7f8c96b..10d79df 100644
--- a/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.html
+++ b/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.html
@@ -34,7 +34,7 @@
         role="presentation"
         class="disc-wrapper"
         id="button"
-        tabindex="0"
+        tabindex$="[[buttonTabIndex_]]"
         on-keydown="onInputKeydown_">
       <div class="disc-border"></div>
       <div class="disc"></div>
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd
index b70faaa..9b5a7f0 100644
--- a/chrome/browser/resources/settings/os_settings_resources.grd
+++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -1070,19 +1070,19 @@
                  preprocess="true"
                  allowexternalscript="true" />
       <structure name="IDR_OS_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_PAGE_JS"
-                 file="google_assistant_page/google_assistant_page.js"
+                 file="chromeos/google_assistant_page/google_assistant_page.js"
                  type="chrome_html"
                  allowexternalscript="true"/>
       <structure name="IDR_OS_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_PAGE_HTML"
-                 file="google_assistant_page/google_assistant_page.html"
+                 file="chromeos/google_assistant_page/google_assistant_page.html"
                  type="chrome_html"
                  allowexternalscript="true" />
       <structure name="IDR_OS_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_BROWSER_PROXY_JS"
-                 file="google_assistant_page/google_assistant_browser_proxy.js"
+                 file="chromeos/google_assistant_page/google_assistant_browser_proxy.js"
                  type="chrome_html"
                  allowexternalscript="true" />
       <structure name="IDR_OS_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_BROWSER_PROXY_HTML"
-                 file="google_assistant_page/google_assistant_browser_proxy.html"
+                 file="chromeos/google_assistant_page/google_assistant_browser_proxy.html"
                  type="chrome_html"
                  allowexternalscript="true" />
       <structure name="IDR_OS_SETTINGS_SEARCH_PAGE_JS"
diff --git a/chrome/browser/resources/settings/people_page/BUILD.gn b/chrome/browser/resources/settings/people_page/BUILD.gn
index 4d65262..1d3f6877 100644
--- a/chrome/browser/resources/settings/people_page/BUILD.gn
+++ b/chrome/browser/resources/settings/people_page/BUILD.gn
@@ -49,6 +49,7 @@
 js_library("account_manager") {
   deps = [
     ":account_manager_browser_proxy",
+    "../chromeos/localized_link:localized_link",
     "//ui/webui/resources/js:cr",
     "//ui/webui/resources/js:i18n_behavior",
     "//ui/webui/resources/js:icon",
diff --git a/chrome/browser/resources/settings/people_page/account_manager.html b/chrome/browser/resources/settings/people_page/account_manager.html
index 6835994..1384780 100644
--- a/chrome/browser/resources/settings/people_page/account_manager.html
+++ b/chrome/browser/resources/settings/people_page/account_manager.html
@@ -10,6 +10,7 @@
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 <link rel="import" href="../i18n_setup.html">
 <link rel="import" href="../route.html">
 <link rel="import" href="../settings_shared_css.html">
@@ -107,12 +108,11 @@
     </style>
 
     <div class="settings-box first">
-      <span class="account-manager-description">
-        $i18n{accountManagerDescription}
-        <a href="$i18nRaw{accountManagerLearnMoreUrl}" target="_blank">
-          $i18n{learnMore}
-        </a>
-      </span>
+      <settings-localized-link
+          class="account-manager-description"
+          localized-string="$i18n{accountManagerDescription}"
+          link-url="$i18nRaw{accountManagerLearnMoreUrl}">
+      </settings-localized-link>
     </div>
 
     <div id="settings-box-user-message" class="settings-box first user-message"
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html
index 7b5dc785..7f6db51b 100644
--- a/chrome/browser/resources/settings/people_page/lock_screen.html
+++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -54,14 +54,6 @@
         display: block;
       }
 
-      #pinPasswordDiv {
-        display: flex;
-      }
-
-      #pinPasswordLabel {
-        flex: 1;
-      }
-
       #pinPasswordLabel,
       #pinPasswordSecondaryActionDiv {
         margin: auto;
@@ -87,7 +79,9 @@
       <template is="dom-if" if="[[quickUnlockEnabled_]]">
         <div id="lockOptionsDiv">
           <div class="settings-box">
-            <h2>[[selectLockScreenOptionsString(hasPinLogin)]]</h2>
+            <h2 id=lockScreenOptionsTitle aria-hidden="true">
+              [[selectLockScreenOptionsString(hasPinLogin)]]
+            </h2>
             <template is="dom-if" if="[[quickUnlockDisabledByPolicy_]]">
               <cr-policy-indicator indicator-type="userPolicy">
               </cr-policy-indicator>
@@ -96,18 +90,13 @@
           <div class="list-frame" >
             <cr-radio-group id="unlockType"
                 disabled$="[[quickUnlockDisabledByPolicy_]]"
-                selected="{{selectedUnlockType}}">
-              <cr-radio-button name="password" class="list-item underbar">
-                <div class="start">
-                  $i18n{lockScreenPasswordOnly}
-                </div>
+                selected="{{selectedUnlockType}}"
+                aria-labelledby="lockScreenOptionsTitle">
+              <cr-radio-button name="password" class="list-item underbar"
+                  label=$i18n{lockScreenPasswordOnly}>
               </cr-radio-button>
-              <cr-radio-button name="pin+password" class="list-item-start">
-                <div id="pinPasswordDiv">
-                  <div id="pinPasswordLabel">
-                    $i18n{lockScreenPinOrPassword}
-                  </div>
-                </div>
+              <cr-radio-button name="pin+password" class="list-item-start"
+                  label=$i18n{lockScreenPinOrPassword}>
               </cr-radio-button>
               <div class="list-item-end"
                   hidden="[[!showConfigurePinButton_(selectedUnlockType)]]">
@@ -134,7 +123,8 @@
         </h2>
         <div class="list-frame">
           <settings-radio-group
-              pref="{{prefs.ash.message_center.lock_screen_mode}}">
+              pref="{{prefs.ash.message_center.lock_screen_mode}}"
+              group-aria-label="$i18n{lockScreenNotificationTitle}">
             <template is="dom-if"
                 if="[[lockScreenHideSensitiveNotificationSupported_]]">
               <cr-radio-button name="hideSensitive" class="list-item underbar"
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.js b/chrome/browser/resources/settings/people_page/sync_account_control.js
index e64173f..58a45655 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.js
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.js
@@ -316,9 +316,7 @@
    * @private
    */
   shouldDisableSyncButton_: function() {
-    if (this.hideButtons ||
-        !loadTimeData.getBoolean('privacySettingsRedesignEnabled')) {
-      // Maintain existing behaviour if hidden or flag disabled
+    if (this.hideButtons || this.prefs === undefined) {
       return this.computeShowSetupButtons_();
     }
     return !!this.syncStatus.firstSetupInProgress ||
diff --git a/chrome/browser/resources/settings/printing_page/BUILD.gn b/chrome/browser/resources/settings/printing_page/BUILD.gn
index 59e2697..15a5279 100644
--- a/chrome/browser/resources/settings/printing_page/BUILD.gn
+++ b/chrome/browser/resources/settings/printing_page/BUILD.gn
@@ -58,6 +58,7 @@
   js_library("cups_add_printer_dialog") {
     deps = [
       ":cups_printers_browser_proxy",
+      "../chromeos/localized_link:localized_link",
       "//ui/webui/resources/js:load_time_data",
       "//ui/webui/resources/js:web_ui_listener_behavior",
     ]
@@ -71,6 +72,7 @@
 
   js_library("cups_edit_printer_dialog") {
     deps = [
+      "../chromeos/localized_link:localized_link",
       "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
       "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior",
       "//ui/webui/resources/cr_components/chromeos/network:onc_mojo",
@@ -109,6 +111,7 @@
       ":cups_printers_entry_manager",
       ":cups_saved_printers",
       "..:route",
+      "../chromeos/localized_link:localized_link",
       "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
       "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior",
       "//ui/webui/resources/cr_components/chromeos/network:onc_mojo",
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
index eba79486..e31bb468 100644
--- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
+++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
@@ -8,6 +8,7 @@
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 <link rel="import" href="../i18n_setup.html">
 <link rel="import" href="cups_add_printer_dialog_elements.html">
 <link rel="import" href="cups_printer_dialog_util.html">
@@ -165,11 +166,11 @@
       </div>
       <div slot="dialog-body">
         <div class="subtext" id="makeModelTextInfo">
-          <span>[[getManufacturerAndModelSubtext_(activePrinter.*)]]
-          </span>
-          <a href="$i18n{printingCUPSPrintLearnMoreUrl}" target="_blank">
-            $i18n{learnMore}
-          </a>
+          <settings-localized-link
+              localized-string=
+                  "[[getManufacturerAndModelSubtext_(activePrinter.*)]]"
+              link-url="$i18n{printingCUPSPrintLearnMoreUrl}">
+          </settings-localized-link>
         </div>
         <div class="settings-box two-line">
           <cr-searchable-drop-down id="manufacturerDropdown"
@@ -188,10 +189,9 @@
           </cr-searchable-drop-down>
         </div>
         <div id="ppdLabel" class="cr-form-field-label">
-          <span>$i18n{selectDriver}</span>
-          <a href="$i18n{printingCUPSPrintPpdLearnMoreUrl}" target="_blank">
-              $i18n{learnMore}
-          </a>
+          <settings-localized-link localized-string="$i18n{selectDriver}"
+              link-url="$i18n{printingCUPSPrintPpdLearnMoreUrl}">
+          </settings-localized-link>
         </div>
         <div class="settings-box two-line">
           <cr-input class="browse-file-input" readonly value="[[newUserPPD_]]"
@@ -203,25 +203,28 @@
             $i18n{selectDriverButtonText}
           </cr-button>
         </div>
-        <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
-          <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
-        </div>
       </div>
       <div slot="dialog-buttons">
-        <cr-button class="cancel-button" on-click="onCancelTap_">
-          $i18n{cancel}
-        </cr-button>
-        <cr-button class="action-button" id="addPrinterButton"
-            disabled="[[!canAddPrinter_(activePrinter.ppdManufacturer,
-                                        activePrinter.ppdModel,
-                                        activePrinter.printerPPDPath,
-                                        addPrinterInProgress_,
-                                        isManufacturerInvalid_,
-                                        isModelInvalid_)]]"
-
-            on-click="addPrinter_">
-          $i18n{addPrinterButtonText}
-        </cr-button>
+        <div> <!-- Left group -->
+          <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
+            <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
+          </div>
+        </div>
+        <div> <!-- Right group -->
+          <cr-button class="cancel-button" on-click="onCancelTap_">
+            $i18n{cancel}
+          </cr-button>
+          <cr-button class="action-button" id="addPrinterButton"
+              disabled="[[!canAddPrinter_(activePrinter.ppdManufacturer,
+                                          activePrinter.ppdModel,
+                                          activePrinter.printerPPDPath,
+                                          addPrinterInProgress_,
+                                          isManufacturerInvalid_,
+                                          isModelInvalid_)]]"
+              on-click="addPrinter_">
+            $i18n{addPrinterButtonText}
+          </cr-button>
+        </div>
       </div>
     </add-printer-dialog>
   </template>
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
index b9eb7fe..a1752d2 100644
--- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
+++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
@@ -8,6 +8,7 @@
 <link rel="import" href="chrome://resources/cr_elements/cr_scrollable_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html">
 <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 <link rel="import" href="../i18n_setup.html">
 <link rel="import" href="cups_add_printer_dialog_elements.html">
 <link rel="import" href="cups_printer_dialog_util.html">
@@ -121,10 +122,9 @@
             </cr-searchable-drop-down>
           </div>
           <div id="ppdLabel" class="cr-form-field-label">
-            <span>$i18n{selectDriver}</span>
-            <a href="$i18n{printingCUPSPrintPpdLearnMoreUrl}" target="_blank">
-                $i18n{learnMore}
-            </a>
+            <settings-localized-link localized-string="$i18n{selectDriver}"
+                link-url="$i18n{printingCUPSPrintPpdLearnMoreUrl}">
+            </settings-localized-link>
           </div>
           <div class="settings-box two-line">
             <cr-input class="browse-file-input" readonly tabindex="-1"
@@ -138,20 +138,25 @@
               $i18n{selectDriverButtonText}
             </cr-button>
           </div>
-          <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
-            <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
-          </div>
         </template>
       </div>
       <div slot="dialog-buttons">
-        <cr-button class="cancel-button" on-click="onCancelTap_">
-          $i18n{cancel}
-        </cr-button>
-        <cr-button class="action-button" on-click="onSaveTap_"
-            disabled="[[!canSavePrinter_(pendingPrinter_.*, printerInfoChanged_,
-               isOnline_, isManufacturerInvalid_, isModelInvalid_)]]">
-          $i18n{editPrinterButtonText}
-        </cr-button>
+        <div>
+          <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
+            <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
+          </div>
+        </div>
+        <div>
+          <cr-button class="cancel-button" on-click="onCancelTap_">
+            $i18n{cancel}
+          </cr-button>
+          <cr-button class="action-button" on-click="onSaveTap_"
+              disabled="[[!canSavePrinter_(pendingPrinter_.*,
+                  printerInfoChanged_,
+                  isOnline_, isManufacturerInvalid_, isModelInvalid_)]]">
+            $i18n{editPrinterButtonText}
+          </cr-button>
+        </div>
       </div>
     </add-printer-dialog>
   </template>
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
index 9132c29..98dc15c 100644
--- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
+++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
@@ -361,10 +361,7 @@
       return;
     }
 
-    settings.CupsPrintersBrowserProxyImpl.getInstance()
-        .getEulaUrl(
-            this.pendingPrinter_.ppdManufacturer, this.pendingPrinter_.ppdModel)
-        .then(this.onGetEulaUrlCompleted_.bind(this));
+    this.attemptPpdEulaFetch_();
   },
 
   /**
@@ -407,6 +404,10 @@
       this.modelList = modelsInfo.models;
       // ModelListChanged_ is the final step of initializing pendingPrinter.
       this.arePrinterFieldsInitialized_ = true;
+
+      // Fetch the EULA URL once we have PpdReferences from fetching the
+      // |modelList|.
+      this.attemptPpdEulaFetch_();
     }
   },
 
@@ -482,4 +483,21 @@
     return this.isOnline_ && this.networkProtocolActive_;
   },
 
+  /**
+   * Attempts fetching for the EULA Url based off of the current printer's
+   * |ppdManufacturer| and |ppdModel|.
+   * @private
+   */
+  attemptPpdEulaFetch_: function() {
+    if (!this.pendingPrinter_.ppdManufacturer ||
+        !this.pendingPrinter_.ppdModel) {
+      return;
+    }
+
+    settings.CupsPrintersBrowserProxyImpl.getInstance()
+        .getEulaUrl(
+            this.pendingPrinter_.ppdManufacturer, this.pendingPrinter_.ppdModel)
+        .then(this.onGetEulaUrlCompleted_.bind(this));
+  },
+
 });
diff --git a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
index fd0d81a..4ebf477 100644
--- a/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
+++ b/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
@@ -58,16 +58,16 @@
         width: 100%;
       }
 
-      [slot='dialog-body'] .eula {
-        padding-inline-start: 20px;
-      }
-
       [slot='dialog-buttons'] {
         display: flex;
         justify-content: space-between;
         width: 100%;
       }
 
+      [slot='dialog-buttons'] .eula {
+        padding-top: 6px;
+      }
+
       .flex-auto {
         flex: 1 1 auto;
       }
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.html b/chrome/browser/resources/settings/printing_page/cups_printers.html
index 5882181..84fec7b 100644
--- a/chrome/browser/resources/settings/printing_page/cups_printers.html
+++ b/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -19,6 +19,7 @@
 <link rel="import" href="cups_printers_entry_manager.html">
 <link rel="import" href="cups_saved_printers.html">
 <link rel="import" href="cups_nearby_printers.html">
+<link rel="import" href="../chromeos/localized_link/localized_link.html">
 <link rel="import" href="../route.html">
 
 <dom-module id="settings-cups-printers">
@@ -86,10 +87,10 @@
     <template is="dom-if" if="[[!enableUpdatedUi_]]">
       <div class="settings-box first">
         <div class="start">
-          <span>$i18n{cupsPrintersLearnMoreLabel}</span>
-          <a href="$i18n{printingCUPSPrintLearnMoreUrl}" target="_blank">
-            $i18n{learnMore}
-          </a>
+          <settings-localized-link
+              localized-string="$i18n{cupsPrintersLearnMoreLabel}"
+              link-url="$i18n{printingCUPSPrintLearnMoreUrl}">
+          </settings-localized-link>
           <div class="secondary" hidden="[[canAddPrinter]]">
             $i18n{requireNetworkMessage}
           </div>
@@ -150,14 +151,10 @@
         <div aria-label$="[[nearbyPrintersAriaLabel_]]">
             $i18n{nearbyPrintersListTitle}
         </div>
-        <span id="nearbyPrintersDescription" class="secondary"
-            aria-hidden="true">
-          $i18n{nearbyPrintersListDescription}
-        </span>
-        <a href="$i18n{printingCUPSPrintLearnMoreUrl}"
-            target="_blank">
-          $i18n{learnMore}
-        </a>
+        <settings-localized-link class="secondary"
+            localized-string="$i18n{nearbyPrintersListDescription}"
+            link-url="$i18n{nearbyPrintersListDescription}">
+        </settings-localized-link>
         <template is="dom-if" if="[[!addPrinterButtonActive_(canAddPrinter,
             prefs.native_printing.user_native_printers_allowed.value)]]">
           <cr-policy-pref-indicator
diff --git a/chrome/browser/resources/settings/privacy_page/passwords_leak_detection_toggle.js b/chrome/browser/resources/settings/privacy_page/passwords_leak_detection_toggle.js
index e2c3c83..ea3f53e 100644
--- a/chrome/browser/resources/settings/privacy_page/passwords_leak_detection_toggle.js
+++ b/chrome/browser/resources/settings/privacy_page/passwords_leak_detection_toggle.js
@@ -76,6 +76,9 @@
    * @private
    */
   computePasswordsLeakDetectionAvailable_: function() {
+    if (this.prefs === undefined) {
+      return false;
+    }
     return !!this.getPref('profile.password_manager_leak_detection').value &&
         !!this.getPref('safebrowsing.enabled').value;
   },
@@ -96,6 +99,9 @@
    * @private
    */
   getDisabledLeakDetection_: function() {
+    if (this.prefs === undefined) {
+      return false;
+    }
     return !this.userSignedIn_ || !this.getPref('safebrowsing.enabled').value;
   },
 
@@ -108,7 +114,7 @@
 
   /** @private */
   setPasswordsLeakDetectionPref_: function() {
-    if (this.prefs == undefined) {
+    if (this.prefs === undefined) {
       return;
     }
     const passwordManagerLeakDetectionPref =
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html
index 4a02d73..07bae3e 100644
--- a/chrome/browser/resources/settings/privacy_page/personalization_options.html
+++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -11,7 +11,6 @@
 <link rel="import" href="../prefs/prefs_behavior.html">
 <link rel="import" href="../route.html">
 <link rel="import" href="../settings_shared_css.html">
-<link rel="import" href="passwords_leak_detection_toggle.html">
 <link rel="import" href="privacy_page_browser_proxy.html">
 
 <if expr="not chromeos">
@@ -38,16 +37,14 @@
       }
     </style>
 <if expr="not chromeos">
-    <template is="dom-if" if="[[privacySettingsRedesignEnabled_]]">
-      <settings-toggle-button id="signinAllowedToggle"
-          disabled="[[syncFirstSetupInProgress_]]"
-          pref="{{prefs.signin.allowed_on_next_startup}}"
-          label="$i18n{signinAllowedTitle}"
-          sub-label="$i18n{signinAllowedDescription}"
-          on-settings-boolean-control-change="onSigninAllowedChange_"
-          no-set-pref>
-      </settings-toggle-button>
-    </template>
+    <settings-toggle-button id="signinAllowedToggle"
+        disabled="[[syncFirstSetupInProgress_]]"
+        pref="{{prefs.signin.allowed_on_next_startup}}"
+        label="$i18n{signinAllowedTitle}"
+        sub-label="$i18n{signinAllowedDescription}"
+        on-settings-boolean-control-change="onSigninAllowedChange_"
+        no-set-pref>
+    </settings-toggle-button>
 </if><!-- not chromeos -->
     <settings-toggle-button hidden="[[!pageVisibility.searchPrediction]]"
         pref="{{prefs.search.suggest_enabled}}"
@@ -58,28 +55,6 @@
         label="$i18n{linkDoctorPref}"
         sub-label="$i18n{linkDoctorPrefDesc}">
     </settings-toggle-button>
-    <template is="dom-if" if="[[!privacySettingsRedesignEnabled_]]">
-      <settings-toggle-button id="safeBrowsingToggle"
-          pref="{{prefs.safebrowsing.enabled}}"
-          label="$i18n{safeBrowsingEnableProtection}"
-          sub-label="$i18n{safeBrowsingEnableProtectionDesc}">
-      </settings-toggle-button>
-      <template is="dom-if" if="[[passwordsLeakDetectionEnabled_]]">
-        <settings-passwords-leak-detection-toggle
-            id="passwordsLeakDetectionToggle"
-            prefs="{{prefs}}"
-            sync-status="[[syncStatus]]">
-        </settings-passwords-leak-detection-toggle>
-      </template>
-      <settings-toggle-button id="safeBrowsingReportingToggle"
-          pref="[[safeBrowsingReportingPref_]]" no-set-pref
-          label="$i18n{safeBrowsingEnableExtendedReporting}"
-          sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"
-          disabled="[[getDisabledExtendedSafeBrowsing_(prefs.*)]]"
-          on-settings-boolean-control-change=
-              "onSafeBrowsingReportingToggleChange_">
-      </settings-toggle-button>
-    </template>
 <if expr="_google_chrome">
 <if expr="chromeos">
     <settings-toggle-button pref="{{prefs.cros.metrics.reportingEnabled}}"
@@ -124,12 +99,10 @@
       </settings-toggle-button>
     </template>
 
-    <template is="dom-if" if="[[privacySettingsRedesignEnabled_]]">
-      <template is="dom-if" if="[[showSignoutDialog_]]" restamp>
-        <settings-signout-dialog sync-status="[[syncStatus]]"
-            on-close="onSignoutDialogClosed_">
-        </settings-signout-dialog>
-      </template>
+    <template is="dom-if" if="[[showSignoutDialog_]]" restamp>
+      <settings-signout-dialog sync-status="[[syncStatus]]"
+          on-close="onSignoutDialogClosed_">
+      </settings-signout-dialog>
     </template>
 
 <if expr="not chromeos">
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chrome/browser/resources/settings/privacy_page/personalization_options.js
index 29021b8c..79241b18 100644
--- a/chrome/browser/resources/settings/privacy_page/personalization_options.js
+++ b/chrome/browser/resources/settings/privacy_page/personalization_options.js
@@ -32,14 +32,6 @@
     /** @type {settings.SyncStatus} */
     syncStatus: Object,
 
-    /** @private */
-    passwordsLeakDetectionEnabled_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('passwordsLeakDetectionEnabled');
-      },
-    },
-
     // <if expr="_google_chrome and not chromeos">
     // TODO(dbeam): make a virtual.* pref namespace and set/get this normally
     // (but handled differently in C++).
@@ -53,14 +45,6 @@
       },
     },
 
-    /** @private {chrome.settingsPrivate.PrefObject} */
-    safeBrowsingReportingPref_: {
-      type: Object,
-      value: function() {
-        return /** @type {chrome.settingsPrivate.PrefObject} */ ({});
-      },
-    },
-
     /** @private */
     showRestart_: Boolean,
 
@@ -72,14 +56,6 @@
     showSignoutDialog_: Boolean,
 
     /** @private */
-    privacySettingsRedesignEnabled_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('privacySettingsRedesignEnabled');
-      },
-    },
-
-    /** @private */
     syncFirstSetupInProgress_: {
       type: Boolean,
       value: false,
@@ -87,10 +63,6 @@
     },
   },
 
-  observers: [
-    'onSafeBrowsingReportingPrefChange_(prefs.safebrowsing.*)',
-  ],
-
   /**
    * @return {boolean}
    * @private
@@ -110,39 +82,6 @@
     // </if>
   },
 
-  /**
-   * @return {boolean}
-   * @private
-   */
-  getDisabledExtendedSafeBrowsing_: function() {
-    return !this.getPref('safebrowsing.enabled').value;
-  },
-
-  /** @private */
-  onSafeBrowsingReportingToggleChange_: function() {
-    this.setPrefValue(
-        'safebrowsing.scout_reporting_enabled',
-        this.$$('#safeBrowsingReportingToggle').checked);
-  },
-
-  /** @private */
-  onSafeBrowsingReportingPrefChange_: function() {
-    if (this.prefs == undefined) {
-      return;
-    }
-    const safeBrowsingScoutPref =
-        this.getPref('safebrowsing.scout_reporting_enabled');
-    const prefValue = !!this.getPref('safebrowsing.enabled').value &&
-        !!safeBrowsingScoutPref.value;
-    this.safeBrowsingReportingPref_ = {
-      key: '',
-      type: chrome.settingsPrivate.PrefType.BOOLEAN,
-      value: prefValue,
-      enforcement: safeBrowsingScoutPref.enforcement,
-      controlledBy: safeBrowsingScoutPref.controlledBy,
-    };
-  },
-
   // <if expr="_google_chrome and not chromeos">
   /** @private */
   onMetricsReportingChange_: function() {
@@ -177,7 +116,6 @@
       this.showRestart_ = true;
     }
   },
-
   // </if>
 
   // <if expr="_google_chrome">
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 2c75fd1..a75d8fc 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -13,9 +13,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
 <link rel="import" href="../clear_browsing_data_dialog/clear_browsing_data_dialog.html">
 <link rel="import" href="../controls/settings_toggle_button.html">
-<link rel="import" href="../lifetime_browser_proxy.html">
 <link rel="import" href="../people_page/sync_browser_proxy.html">
-<link rel="import" href="../people_page/signout_dialog.html">
 <link rel="import" href="../prefs/prefs.html">
 <link rel="import" href="../prefs/prefs_behavior.html">
 <link rel="import" href="../route.html">
@@ -25,9 +23,6 @@
 <link rel="import" href="../site_settings/all_sites.html">
 <link rel="import" href="../site_settings/constants.html">
 
-<if expr="not chromeos">
-<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
-</if>
 <link rel="import" href="privacy_page_browser_proxy.html">
 
 <dom-module id="settings-privacy-page">
@@ -36,18 +31,6 @@
       .iron-collapse-indented {
         margin-inline-start: var(--cr-section-indent-width);
       }
-
-<if expr="not chromeos">
-      #toast {
-        left: 0;
-        z-index: 1;
-      }
-
-      :host-context([dir='rtl']) #toast {
-        left: auto;
-        right: 0;
-      }
-</if>
     </style>
     <template is="dom-if" if="[[showClearBrowsingDataDialog_]]" restamp>
       <settings-clear-browsing-data-dialog prefs="{{prefs}}"
@@ -76,13 +59,6 @@
     <settings-animated-pages id="pages" section="privacy"
         focus-config="[[focusConfig_]]">
       <div route-path="default">
-        <template is="dom-if" if="[[!privacySettingsRedesignEnabled_]]">
-          <cr-link-row id="syncLinkRow"
-              label="$i18n{syncAndNonPersonalizedServices}"
-              sub-label="$i18n{syncAndGoogleServicesPrivacyDescription}"
-              on-click="onSyncAndGoogleServicesClick_">
-          </cr-link-row>
-        </template>
         <cr-link-row id="clearBrowsingData"
             class="hr"
             label="$i18n{clearBrowsingData}"
@@ -96,47 +72,32 @@
         <cr-expand-button id="moreExpansion"
             alt="$i18n{privacyPageMore}"
             class="settings-box"
-            expanded="{{moreOpened_}}"
-            hidden="[[!privacySettingsRedesignEnabled_]]">
+            expanded="{{moreOpened_}}">
             <div>$i18n{privacyPageMore}</div>
         </cr-expand-button>
         <iron-collapse id="moreCollapse" opened="[[moreOpened_]]"
-            class$="[[getIronCollapseCssClass_(
-              privacySettingsRedesignEnabled_)]]">
-          <template is="dom-if" if="[[privacySettingsRedesignEnabled_]]">
-            <settings-toggle-button id="safeBrowsingToggle"
-                class$="[[getTopBarCssClass_(privacySettingsRedesignEnabled_)]]"
-                pref="{{prefs.safebrowsing.enabled}}"
-                label="$i18n{safeBrowsingEnableProtection}"
-                sub-label="$i18n{safeBrowsingEnableProtectionDesc}">
-            </settings-toggle-button>
-            <template is="dom-if" if="[[passwordsLeakDetectionEnabled_]]">
-              <settings-passwords-leak-detection-toggle
-                  id="passwordsLeakDetectionToggle"
-                  prefs="{{prefs}}"
-                  sync-status="[[syncStatus]]">
-              </settings-passwords-leak-detection-toggle>
-            </template>
-            <settings-toggle-button id="safeBrowsingReportingToggle"
-                pref="[[safeBrowsingReportingPref_]]" no-set-pref
-                label="$i18n{safeBrowsingEnableExtendedReporting}"
-                sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"
-                disabled="[[getDisabledExtendedSafeBrowsing_(prefs.*)]]"
-                on-settings-boolean-control-change=
-                    "onSafeBrowsingReportingToggleChange_">
-            </settings-toggle-button>
-          </template>
-<if expr="not chromeos">
-        <template is="dom-if" if="[[!privacySettingsRedesignEnabled_]]">
-          <settings-toggle-button id="signinAllowedToggle"
-              pref="{{prefs.signin.allowed_on_next_startup}}"
-              label="$i18n{signinAllowedTitle}"
-              sub-label="$i18n{signinAllowedDescription}"
-              on-settings-boolean-control-change="onSigninAllowedChange_"
-              no-set-pref>
+            class="iron-collapse-indented">
+          <settings-toggle-button id="safeBrowsingToggle"
+              class="settings-box first"
+              pref="{{prefs.safebrowsing.enabled}}"
+              label="$i18n{safeBrowsingEnableProtection}"
+              sub-label="$i18n{safeBrowsingEnableProtectionDesc}">
           </settings-toggle-button>
-        </template>
-</if><!-- not chromeos -->
+          <template is="dom-if" if="[[passwordsLeakDetectionEnabled_]]">
+            <settings-passwords-leak-detection-toggle
+                id="passwordsLeakDetectionToggle"
+                prefs="{{prefs}}"
+                sync-status="[[syncStatus]]">
+            </settings-passwords-leak-detection-toggle>
+          </template>
+          <settings-toggle-button id="safeBrowsingReportingToggle"
+              pref="[[safeBrowsingReportingPref_]]" no-set-pref
+              label="$i18n{safeBrowsingEnableExtendedReporting}"
+              sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"
+              disabled="[[getDisabledExtendedSafeBrowsing_(prefs.*)]]"
+              on-settings-boolean-control-change=
+                  "onSafeBrowsingReportingToggleChange_">
+          </settings-toggle-button>
           <settings-toggle-button id="doNotTrack"
               pref="{{prefs.enable_do_not_track}}" label="$i18n{doNotTrack}"
               on-settings-boolean-control-change="onDoNotTrackChange_"
@@ -739,23 +700,6 @@
         </template>
       </template>
     </settings-animated-pages>
-
-    <template is="dom-if" if="[[!privacySettingsRedesignEnabled_]]">
-      <template is="dom-if" if="[[showSignoutDialog_]]" restamp>
-        <settings-signout-dialog sync-status="[[syncStatus]]"
-            on-close="onSignoutDialogClosed_">
-        </settings-signout-dialog>
-      </template>
-    </template>
-
-<if expr="not chromeos">
-    <cr-toast id="toast" open="[[showRestart_]]">
-      <div>$i18n{restartToApplyChanges}</div>
-      <cr-button on-click="onRestartTap_">
-        $i18n{restart}
-      </cr-button>
-    </cr-toast>
-</if>
   </template>
   <script src="privacy_page.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js
index f1ed037..bba083a 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.js
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -131,9 +131,7 @@
      */
     moreOpened_: {
       type: Boolean,
-      value: function() {
-        return !loadTimeData.getBoolean('privacySettingsRedesignEnabled');
-      },
+      value: false,
     },
 
     /** @private */
@@ -232,14 +230,6 @@
       },
     },
 
-    // <if expr="not chromeos">
-    /** @private */
-    showRestart_: Boolean,
-    // </if>
-
-    /** @private */
-    showSignoutDialog_: Boolean,
-
     /** @private */
     searchFilter_: String,
   },
@@ -441,15 +431,6 @@
         settings.SettingsPageInteractions.PRIVACY_NETWORK_PREDICTION);
   },
 
-  /** @private */
-  onSyncAndGoogleServicesClick_: function() {
-    // Navigate to sync page, and remove (privacy related) search text to
-    // avoid the sync page from being hidden.
-    settings.navigateTo(settings.routes.SYNC, null, true);
-    this.browserProxy_.recordSettingsPageHistogram(
-        settings.SettingsPageInteractions.PRIVACY_SYNC_AND_GOOGLE_SERVICES);
-  },
-
   /**
    * This is a workaround to connect the remove all button to the subpage.
    * @private
@@ -505,58 +486,5 @@
     return value ? this.i18n('siteSettingsProtectedContentEnableIdentifiers') :
                    this.i18n('siteSettingsBlocked');
   },
-
-  /** @private */
-  onSigninAllowedChange_: function() {
-    const toggle = this.$$('#signinAllowedToggle');
-    if (this.syncStatus.signedIn && !toggle.checked) {
-      // Switch the toggle back on and show the signout dialog.
-      toggle.checked = true;
-      this.showSignoutDialog_ = true;
-    } else {
-      toggle.sendPrefChange();
-      this.showRestart_ = true;
-    }
-    this.browserProxy_.recordSettingsPageHistogram(
-        settings.SettingsPageInteractions.PRIVACY_CHROME_SIGN_IN);
-  },
-
-  /** @private */
-  onSignoutDialogClosed_: function() {
-    if (/** @type {!SettingsSignoutDialogElement} */ (
-            this.$$('settings-signout-dialog'))
-            .wasConfirmed()) {
-      const toggle = this.$$('#signinAllowedToggle');
-      toggle.checked = false;
-      toggle.sendPrefChange();
-      this.showRestart_ = true;
-    }
-    this.showSignoutDialog_ = false;
-  },
-
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onRestartTap_: function(e) {
-    e.stopPropagation();
-    settings.LifetimeBrowserProxyImpl.getInstance().restart();
-  },
-
-  /**
-   * @return {string}
-   * @private
-   */
-  getIronCollapseCssClass_: function() {
-    return this.privacySettingsRedesignEnabled_ ? 'iron-collapse-indented' : '';
-  },
-
-  /**
-   * @return {string}
-   * @private
-   */
-  getTopBarCssClass_: function() {
-    return this.privacySettingsRedesignEnabled_ ? 'settings-box first' : '';
-  },
 });
 })();
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js
index 63409309..869aa09 100644
--- a/chrome/browser/resources/settings/route.js
+++ b/chrome/browser/resources/settings/route.js
@@ -352,14 +352,12 @@
       r.ADDRESSES = r.AUTOFILL.createChild('/addresses');
     }
 
-    if (loadTimeData.getBoolean('privacySettingsRedesignEnabled')) {
-      r.CLEAR_BROWSER_DATA = r.BASIC.createChild('/clearBrowserData');
-      r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
+    r.CLEAR_BROWSER_DATA = r.BASIC.createChild('/clearBrowserData');
+    r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
 
-      if (pageVisibility.privacy !== false) {
-        r.PRIVACY = r.BASIC.createSection('/privacy', 'privacy');
-        addPrivacyChildRoutes(r);
-      }
+    if (pageVisibility.privacy !== false) {
+      r.PRIVACY = r.BASIC.createSection('/privacy', 'privacy');
+      addPrivacyChildRoutes(r);
     }
 
     if (pageVisibility.defaultBrowser !== false) {
@@ -378,16 +376,6 @@
     if (pageVisibility.advancedSettings !== false) {
       r.ADVANCED = new Route('/advanced');
 
-      if (!loadTimeData.getBoolean('privacySettingsRedesignEnabled')) {
-        r.CLEAR_BROWSER_DATA = r.ADVANCED.createChild('/clearBrowserData');
-        r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
-
-        if (pageVisibility.privacy !== false) {
-          r.PRIVACY = r.ADVANCED.createSection('/privacy', 'privacy');
-          addPrivacyChildRoutes(r);
-        }
-      }
-
       r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages');
       // <if expr="not is_macosx">
       r.EDIT_DICTIONARY = r.LANGUAGES.createChild('/editDictionary');
diff --git a/chrome/browser/resources/settings/search_page/BUILD.gn b/chrome/browser/resources/settings/search_page/BUILD.gn
index 48ae8f73..6eeb409 100644
--- a/chrome/browser/resources/settings/search_page/BUILD.gn
+++ b/chrome/browser/resources/settings/search_page/BUILD.gn
@@ -17,6 +17,5 @@
     "../search_engines_page:search_engines_browser_proxy",
     "../settings_page:settings_animated_pages",
     "//ui/webui/resources/js:cr",
-    "//ui/webui/resources/js:i18n_behavior",
   ]
 }
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html
index 2c35591..a0b87a2 100644
--- a/chrome/browser/resources/settings/search_page/search_page.html
+++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -1,14 +1,9 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
 <link rel="import" href="../controls/extension_controlled_indicator.html">
-<link rel="import" href="../controls/settings_toggle_button.html">
-<link rel="import" href="../icons.html">
 <link rel="import" href="../i18n_setup.html">
 <link rel="import" href="../route.html">
 <link rel="import" href="../search_engines_page/search_engines_browser_proxy.html">
@@ -17,11 +12,6 @@
 <link rel="import" href="../settings_shared_css.html">
 <link rel="import" href="../settings_vars_css.html">
 
-<if expr="chromeos">
-  <link rel="import" href="../google_assistant_page/google_assistant_page.html">
-  <link rel="import" href="../google_assistant_page/google_assistant_browser_proxy.html">
-</if>
-
 <dom-module id="settings-search-page">
   <template>
     <style include="settings-shared md-select">
@@ -30,14 +20,6 @@
         display: flex;
         min-height: var(--settings-row-min-height);
       }
-
-      iron-icon {
-        padding-inline-end: 16px;
-      }
-
-      .indented {
-        margin-inline-start: var(--cr-section-indent-width);
-      }
     </style>
     <settings-animated-pages id="pages" section="search"
         focus-config="[[focusConfig_]]">
@@ -82,21 +64,6 @@
             label="$i18n{searchEnginesManage}"
             on-click="onManageSearchEnginesTap_"
             role-description="$i18n{subpageArrowRoleDescription}"></cr-link-row>
-
-<if expr="chromeos">
-        <!-- Google Assistant -->
-        <template is="dom-if" if="[[isAssistantAllowed_]]">
-          <cr-link-row
-              class="hr"
-              id="assistantSubpageTrigger"
-              label="$i18n{searchGoogleAssistant}"
-              sub-label="[[getAssistantEnabledDisabledLabel_(
-                  prefs.settings.voice_interaction.enabled.value)]]"
-              on-click="onGoogleAssistantTap_"
-              role-description="$i18n{subpageArrowRoleDescription}">
-          </cr-link-row>
-        </template>
-</if>
       </div>
       <template is="dom-if" route-path="/searchEngines">
         <settings-subpage
@@ -107,18 +74,6 @@
           <settings-search-engines-page filter="[[searchEnginesFilter_]]">
         </settings-subpage>
       </template>
-<if expr="chromeos">
-      <template is="dom-if" if="[[isAssistantAllowed_]]">
-        <template is="dom-if" route-path="/googleAssistant">
-          <settings-subpage
-              associated-control="[[$$('#assistantSubpageTrigger')]]"
-              page-title="$i18n{googleAssistantPageTitle}">
-            <settings-google-assistant-page prefs="{{prefs}}">
-            </settings-google-assistant-page>
-          </settings-subpage>
-        </template>
-      </template>
-</if>
     </settings-animated-pages>
   </template>
   <script src="search_page.js"></script>
diff --git a/chrome/browser/resources/settings/search_page/search_page.js b/chrome/browser/resources/settings/search_page/search_page.js
index 28e2c0f5..123164b 100644
--- a/chrome/browser/resources/settings/search_page/search_page.js
+++ b/chrome/browser/resources/settings/search_page/search_page.js
@@ -9,8 +9,6 @@
 Polymer({
   is: 'settings-search-page',
 
-  behaviors: [I18nBehavior],
-
   properties: {
     prefs: Object,
 
@@ -30,17 +28,6 @@
 
     /** @type {?Map<string, string>} */
     focusConfig_: Object,
-
-    // <if expr="chromeos">
-    /** @private Can be disallowed due to flag, policy, locale, etc. */
-    isAssistantAllowed_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('isAssistantAllowed') &&
-            loadTimeData.getBoolean('showOSSettings');
-      },
-    },
-    // </if>
   },
 
   /** @private {?settings.SearchEnginesBrowserProxy} */
@@ -65,12 +52,6 @@
       this.focusConfig_.set(
           settings.routes.SEARCH_ENGINES.path, '#enginesSubpageTrigger');
     }
-    // <if expr="chromeos">
-    if (settings.routes.GOOGLE_ASSISTANT) {
-      this.focusConfig_.set(
-          settings.routes.GOOGLE_ASSISTANT.path, '#assistantSubpageTrigger');
-    }
-    // </if>
   },
 
   /** @private */
@@ -90,35 +71,6 @@
     settings.navigateTo(settings.routes.SEARCH_ENGINES);
   },
 
-  // <if expr="chromeos">
-  /** @private */
-  onGoogleAssistantTap_: function() {
-    assert(this.isAssistantAllowed_);
-    settings.navigateTo(settings.routes.GOOGLE_ASSISTANT);
-  },
-  // </if>
-
-  // <if expr="chromeos">
-  /**
-   * @param {boolean} toggleValue
-   * @return {string}
-   * @private
-   */
-  getAssistantEnabledDisabledLabel_: function(toggleValue) {
-    return this.i18n(
-        toggleValue ? 'searchGoogleAssistantEnabled' :
-                      'searchGoogleAssistantDisabled');
-  },
-  // </if>
-
-  /**
-   * @param {!Event} event
-   * @private
-   */
-  doNothing_: function(event) {
-    event.stopPropagation();
-  },
-
   /**
    * @param {!chrome.settingsPrivate.PrefObject} pref
    * @return {boolean}
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html
index b005a75..c5222a19 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -63,11 +63,6 @@
     <template is="dom-if" if="[[showPages_.settings]]">
       <settings-basic-page prefs="{{prefs}}"
           page-visibility="[[pageVisibility]]"
-          show-android-apps="[[showAndroidApps]]"
-          show-crostini="[[showCrostini]]"
-          show-parental-controls="[[showParentalControls]]"
-          show-plugin-vm="[[showPluginVm]]"
-          have-play-store-app="[[havePlayStoreApp]]"
           on-showing-section="onShowingSection_"
           on-subpage-expand="onShowingSubpage_"
           on-showing-main-page="onShowingMainPage_"
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js
index bb8287b..d883acb 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.js
+++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -78,12 +78,6 @@
      * @type {!PageVisibility}
      */
     pageVisibility: Object,
-
-    showAndroidApps: Boolean,
-
-    showParentalControls: Boolean,
-
-    havePlayStoreApp: Boolean,
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html
index 95b16d5..7657dd2 100644
--- a/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -11,11 +11,6 @@
 <link rel="import" href="../route.html">
 <link rel="import" href="../settings_shared_css.html">
 
-<if expr="chromeos">
-<!-- TODO(crbug.com/986596): Remove OS icons when SplitSettings is complete. -->
-<link rel="import" href="../chromeos/os_icons.html">
-</if>
-
 <dom-module id="settings-menu">
   <template>
     <style include="settings-shared cr-icons">
@@ -111,22 +106,6 @@
     <iron-selector id="topMenu" selectable="a:not(#extensionsLink)"
         attr-for-selected="href" on-iron-activate="onSelectorActivate_"
         role="navigation" on-click="onLinkClick_">
-<if expr="chromeos">
-      <a href="/internet" hidden="[[!pageVisibility.internet]]">
-        <iron-icon icon="os-settings:network-wifi"></iron-icon>
-        $i18n{internetPageTitle}
-      </a>
-      <a href="/bluetooth" hidden="[[!pageVisibility.bluetooth]]">
-        <iron-icon icon="cr:bluetooth"></iron-icon>
-        $i18n{bluetoothPageTitle}
-      </a>
-      <a id="multidevice" href="/multidevice"
-          hidden="[[!pageVisibility.multidevice]]">
-        <iron-icon icon="os-settings:multidevice-better-together-suite">
-        </iron-icon>
-        $i18n{multidevicePageTitle}
-      </a>
-</if>
       <a id="people" href="/people" hidden="[[!pageVisibility.people]]">
         <iron-icon icon="cr:person"></iron-icon>
         $i18n{peoplePageTitle}
@@ -136,8 +115,7 @@
         <iron-icon icon="settings:assignment"></iron-icon>
         $i18n{autofillPageTitle}
       </a>
-      <a href="/privacy" hidden="[[shouldHidePrivacy_(
-          privacySettingsRedesignEnabled_, pageVisibility.privacy)]]">
+      <a href="/privacy" hidden="[[!pageVisibility.privacy]]">
         <iron-icon icon="cr:security"></iron-icon>
         $i18n{privacyPageTitle}
       </a>
@@ -146,30 +124,10 @@
         <iron-icon icon="settings:palette"></iron-icon>
         $i18n{appearancePageTitle}
       </a>
-<if expr="chromeos">
-      <a href="/device" hidden="[[!pageVisibility.device]]">
-        <iron-icon icon="os-settings:laptop-chromebook"></iron-icon>
-        $i18n{devicePageTitle}
-      </a>
-</if>
       <a href="/search">
         <iron-icon icon="cr:search"></iron-icon>
         $i18n{searchPageTitle}
       </a>
-<if expr="chromeos">
-      <a href="/androidApps" hidden="[[!showAndroidApps]]">
-        <iron-icon icon="os-settings:play-prism"></iron-icon>
-        $i18n{androidAppsPageTitle}
-      </a>
-      <a href="/crostini" hidden="[[!showCrostini]]">
-        <iron-icon icon="os-settings:crostini-mascot"></iron-icon>
-        $i18n{crostiniPageTitle}
-      </a>
-      <a href="/pluginVm" hidden="[[!showPluginVm]]">
-        <iron-icon icon="os-settings:plugin-vm"></iron-icon>
-        $i18n{pluginVmPageTitle}
-      </a>
-</if>
 <if expr="not chromeos">
       <a id="defaultBrowser" href="/defaultBrowser"
         hidden="[[!pageVisibility.defaultBrowser]]">
@@ -193,16 +151,6 @@
           hidden="[[!pageVisibility.advancedSettings]]">
         <iron-selector id="subMenu" selectable="a" attr-for-selected="href"
             role="navigation" on-click="onLinkClick_">
-<if expr="chromeos">
-          <a href="/dateTime" hidden="[[!pageVisibility.dateTime]]">
-            <iron-icon icon="os-settings:access-time"></iron-icon>
-            $i18n{dateTimePageTitle}
-          </a>
-</if>
-          <a href="/privacy" hidden="[[privacySettingsRedesignEnabled_]]">
-            <iron-icon icon="cr:security"></iron-icon>
-            $i18n{privacyPageTitle}
-          </a>
           <a href="/languages">
             <iron-icon icon="settings:language"></iron-icon>
             $i18n{languagesPageTitle}
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chrome/browser/resources/settings/settings_menu/settings_menu.js
index e045bc812..c604ae4b 100644
--- a/chrome/browser/resources/settings/settings_menu/settings_menu.js
+++ b/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -18,14 +18,6 @@
       notify: true,
     },
 
-    /** @private */
-    privacySettingsRedesignEnabled_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('privacySettingsRedesignEnabled');
-      },
-    },
-
     /**
      * Dictionary defining page visibility.
      * @type {!PageVisibility}
@@ -55,17 +47,6 @@
   },
 
   /**
-   * @return {boolean}
-   * @private
-   */
-  shouldHidePrivacy_: function() {
-    const pageVisibility = settings.pageVisibility || {};
-    return !(
-        this.privacySettingsRedesignEnabled_ &&
-        (pageVisibility.privacy !== false));
-  },
-
-  /**
    * Prevent clicks on sidebar items from navigating. These are only links for
    * accessibility purposes, taps are handled separately by <iron-selector>.
    * @param {!Event} event
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd
index 4335ae9..db8d5c2 100644
--- a/chrome/browser/resources/settings/settings_resources.grd
+++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1192,33 +1192,12 @@
                  type="chrome_html"
                  preprocess="true"
                  allowexternalscript="true" />
-      <if expr="chromeos">
-        <structure name="IDR_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_PAGE_JS"
-                   file="google_assistant_page/google_assistant_page.js"
-                   type="chrome_html"
-                   allowexternalscript="true"/>
-        <structure name="IDR_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_PAGE_HTML"
-                   file="google_assistant_page/google_assistant_page.html"
-                   type="chrome_html"
-                   allowexternalscript="true" />
-        <structure name="IDR_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_BROWSER_PROXY_JS"
-                   file="google_assistant_page/google_assistant_browser_proxy.js"
-                   type="chrome_html"
-                   allowexternalscript="true" />
-        <structure name="IDR_SETTINGS_GOOGLE_ASSISTANT_PAGE_GOOGLE_ASSISTANT_BROWSER_PROXY_HTML"
-                   file="google_assistant_page/google_assistant_browser_proxy.html"
-                   type="chrome_html"
-                   allowexternalscript="true" />
-      </if>
       <structure name="IDR_SETTINGS_SEARCH_PAGE_JS"
                  file="search_page/search_page.js"
-                 type="chrome_html"
-                 preprocess="true" />
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_SEARCH_PAGE_HTML"
                  file="search_page/search_page.html"
-                 type="chrome_html"
-                 preprocess="true"
-                 allowexternalscript="true" />
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_SYNC_CONTROLS_JS"
                  file="people_page/sync_controls.js"
                  type="chrome_html"
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html
index da213634..83589b0 100644
--- a/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -121,11 +121,6 @@
       <div class="drawer-content">
         <template is="dom-if" id="drawerTemplate">
           <settings-menu page-visibility="[[pageVisibility_]]"
-              show-android-apps="[[showAndroidApps_]]"
-              show-crostini="[[showCrostini_]]"
-              show-parental-controls="[[showParentalControls_]]"
-              show-plugin-vm="[[showPluginVm_]]"
-              have-play-store-app="[[havePlayStoreApp_]]"
               on-iron-activate="onIronActivate_"
               advanced-opened="{{advancedOpenedInMenu_}}">
           </settings-menu>
@@ -135,11 +130,6 @@
     <div id="container" class="no-outline">
       <div id="left">
         <settings-menu page-visibility="[[pageVisibility_]]"
-            show-android-apps="[[showAndroidApps_]]"
-            show-crostini="[[showCrostini_]]"
-            show-parental-controls="[[showParentalControls_]]"
-            show-plugin-vm="[[showPluginVm_]]"
-            have-play-store-app="[[havePlayStoreApp_]]"
             on-iron-activate="onIronActivate_"
             advanced-opened="{{advancedOpenedInMenu_}}">
         </settings-menu>
@@ -147,12 +137,6 @@
       <settings-main id="main" prefs="{{prefs}}"
           toolbar-spinner-active="{{toolbarSpinnerActive_}}"
           page-visibility="[[pageVisibility_]]"
-          show-apps="[[showApps_]]"
-          show-android-apps="[[showAndroidApps_]]"
-          show-crostini="[[showCrostini_]]"
-          show-parental-controls="[[showParentalControls_]]"
-          show-plugin-vm="[[showPluginVm_]]"
-          have-play-store-app="[[havePlayStoreApp_]]"
           advanced-toggle-expanded="{{advancedOpenedInMain_}}">
       </settings-main>
       <!-- An additional child of the flex #container to take up space,
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js
index 30785ee2..70a4076 100644
--- a/chrome/browser/resources/settings/settings_ui/settings_ui.js
+++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -66,21 +66,6 @@
     pageVisibility_: {type: Object, value: settings.pageVisibility},
 
     /** @private */
-    showAndroidApps_: Boolean,
-
-    /** @private */
-    showCrostini_: Boolean,
-
-    /** @private */
-    showParentalControls_: Boolean,
-
-    /** @private */
-    showPluginVm_: Boolean,
-
-    /** @private */
-    havePlayStoreApp_: Boolean,
-
-    /** @private */
     lastSearchQuery_: {
       type: String,
       value: '',
@@ -136,25 +121,6 @@
       // </if>
     };
 
-    // The SplitSettings feature hides OS settings in the browser settings page.
-    // https://crbug.com/950007
-    const showOSSettings = loadTimeData.getBoolean('showOSSettings');
-    this.showAndroidApps_ = showOSSettings &&
-        loadTimeData.valueExists('androidAppsVisible') &&
-        loadTimeData.getBoolean('androidAppsVisible');
-    this.showCrostini_ = showOSSettings &&
-        loadTimeData.valueExists('showCrostini') &&
-        loadTimeData.getBoolean('showCrostini');
-    this.showParentalControls_ = showOSSettings &&
-        loadTimeData.valueExists('showParentalControls') &&
-        loadTimeData.getBoolean('showParentalControls');
-    this.showPluginVm_ = showOSSettings &&
-        loadTimeData.valueExists('showPluginVm') &&
-        loadTimeData.getBoolean('showPluginVm');
-    this.havePlayStoreApp_ = showOSSettings &&
-        loadTimeData.valueExists('havePlayStoreApp') &&
-        loadTimeData.getBoolean('havePlayStoreApp');
-
     this.addEventListener('show-container', () => {
       this.$.container.style.visibility = 'visible';
     });
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.html b/chrome/browser/resources/settings/site_settings/protocol_handlers.html
index 2fe0b49..17bda90 100644
--- a/chrome/browser/resources/settings/site_settings/protocol_handlers.html
+++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.html
@@ -12,6 +12,10 @@
 <link rel="import" href="site_settings_behavior.html">
 <link rel="import" href="site_settings_prefs_browser_proxy.html">
 
+<if expr="chromeos">
+<link rel="import" href="../android_apps_page/android_apps_browser_proxy.html">
+</if>
+
 <dom-module id="protocol-handlers">
   <template>
     <style include="settings-shared">
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.js b/chrome/browser/resources/settings/site_settings/protocol_handlers.js
index 5fe1b81..6c8ee14 100644
--- a/chrome/browser/resources/settings/site_settings/protocol_handlers.js
+++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.js
@@ -90,12 +90,9 @@
   // <if expr="chromeos">
   /** @override */
   attached: function() {
-    if (settings.AndroidAppsBrowserProxyImpl) {
-      cr.addWebUIListener(
-          'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this));
-      settings.AndroidAppsBrowserProxyImpl.getInstance()
-          .requestAndroidAppsInfo();
-    }
+    cr.addWebUIListener(
+        'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this));
+    settings.AndroidAppsBrowserProxyImpl.getInstance().requestAndroidAppsInfo();
   },
   // </if>
 
diff --git a/chrome/browser/resources/snippets_internals/snippets_internals.js b/chrome/browser/resources/snippets_internals/snippets_internals.js
index 99270fb..4ce2bfc 100644
--- a/chrome/browser/resources/snippets_internals/snippets_internals.js
+++ b/chrome/browser/resources/snippets_internals/snippets_internals.js
@@ -269,7 +269,8 @@
 
   // Setup backend mojo.
   const pageHandlerFactory =
-      snippetsInternals.mojom.PageHandlerFactory.getRemote();
+      snippetsInternals.mojom.PageHandlerFactory.getRemote(
+          /*useBrowserInterfaceBroker=*/ true);
 
   // Give backend mojo a reference to frontend mojo.
   pageHandlerFactory.createPageHandler(page.bindNewPipeAndPassRemote())
diff --git a/chrome/browser/resources/usb_internals/usb_internals.js b/chrome/browser/resources/usb_internals/usb_internals.js
index 6d9fc98..3b2789d 100644
--- a/chrome/browser/resources/usb_internals/usb_internals.js
+++ b/chrome/browser/resources/usb_internals/usb_internals.js
@@ -14,7 +14,8 @@
       // actions after the page is loaded but before any script is run.
       await window.setupFn();
 
-      const pageHandler = mojom.UsbInternalsPageHandler.getRemote();
+      const pageHandler = mojom.UsbInternalsPageHandler.getRemote(
+          /*useBrowserInterfaceBroker=*/ true);
 
       // Connection to the UsbInternalsPageHandler instance running in the
       // browser process.
diff --git a/chrome/browser/safe_browsing/browser_feature_extractor.cc b/chrome/browser/safe_browsing/browser_feature_extractor.cc
index 0cdd7be..b6c0b17 100644
--- a/chrome/browser/safe_browsing/browser_feature_extractor.cc
+++ b/chrome/browser/safe_browsing/browser_feature_extractor.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/safe_browsing/client_side_detection_host.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_types.h"
-#include "components/safe_browsing/db/database_manager.h"
 #include "components/safe_browsing/proto/csd.pb.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -43,39 +42,6 @@
 
 namespace safe_browsing {
 
-namespace {
-
-const int kMaxMalwareIPPerRequest = 5;
-
-void FilterBenignIpsOnIOThread(
-    scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
-    IPUrlMap* ips) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  for (auto it = ips->begin(); it != ips->end();) {
-    if (!database_manager.get() ||
-        !database_manager->MatchMalwareIP(it->first)) {
-      // it++ here returns a copy of the old iterator and passes it to erase.
-      ips->erase(it++);
-    } else {
-      ++it;
-    }
-  }
-}
-}  // namespace
-
-IPUrlInfo::IPUrlInfo(const std::string& origin_of_final_url,
-                     const std::string& method,
-                     const std::string& referrer,
-                     const ResourceType& resource_type)
-    : origin_of_final_url(origin_of_final_url),
-      method(method),
-      referrer(referrer),
-      resource_type(resource_type) {}
-
-IPUrlInfo::IPUrlInfo(const IPUrlInfo& other) = default;
-
-IPUrlInfo::~IPUrlInfo() {}
-
 BrowseInfo::BrowseInfo() : http_status_code(0) {}
 
 BrowseInfo::~BrowseInfo() {}
@@ -91,23 +57,6 @@
   DVLOG(2) << "Browser feature: " << feature->name() << " " << feature->value();
 }
 
-static void AddMalwareIpUrlInfo(const std::string& ip,
-                                const std::vector<IPUrlInfo>& meta_infos,
-                                ClientMalwareRequest* request) {
-  DCHECK(request);
-  for (auto it = meta_infos.begin(); it != meta_infos.end(); ++it) {
-    ClientMalwareRequest::UrlInfo* urlinfo =
-        request->add_bad_ip_url_info();
-    // We add the information about url on the bad ip.
-    urlinfo->set_ip(ip);
-    urlinfo->set_url(it->origin_of_final_url);
-    urlinfo->set_method(it->method);
-    urlinfo->set_referrer(it->referrer);
-    urlinfo->set_resource_type(static_cast<int>(it->resource_type));
-  }
-  DVLOG(2) << "Added url info for bad ip: " << ip;
-}
-
 static void AddNavigationFeatures(const std::string& feature_prefix,
                                   NavigationController* controller,
                                   int index,
@@ -157,9 +106,7 @@
   }
 }
 
-BrowserFeatureExtractor::BrowserFeatureExtractor(WebContents* tab,
-                                                 ClientSideDetectionHost* host)
-    : tab_(tab), host_(host) {
+BrowserFeatureExtractor::BrowserFeatureExtractor(WebContents* tab) : tab_(tab) {
   DCHECK(tab);
 }
 
@@ -227,30 +174,6 @@
                                 std::move(callback)));
 }
 
-void BrowserFeatureExtractor::ExtractMalwareFeatures(
-    BrowseInfo* info,
-    std::unique_ptr<ClientMalwareRequest> request,
-    MalwareDoneCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(!callback.is_null());
-
-  // Grab the IPs because they might go away before we're done
-  // checking them against the IP blacklist on the IO thread.
-  std::unique_ptr<IPUrlMap> ips(new IPUrlMap);
-  ips->swap(info->ips);
-
-  IPUrlMap* ips_ptr = ips.get();
-
-  // IP blacklist lookups have to happen on the IO thread.
-  base::PostTaskAndReply(
-      FROM_HERE, {BrowserThread::IO},
-      base::BindOnce(&FilterBenignIpsOnIOThread, host_->database_manager(),
-                     ips_ptr),
-      base::BindOnce(&BrowserFeatureExtractor::FinishExtractMalwareFeatures,
-                     weak_factory_.GetWeakPtr(), std::move(ips),
-                     std::move(callback), std::move(request)));
-}
-
 void BrowserFeatureExtractor::ExtractBrowseInfoFeatures(
     const BrowseInfo& info,
     ClientPhishingRequest* request) {
@@ -435,24 +358,4 @@
   return false;
 }
 
-void BrowserFeatureExtractor::FinishExtractMalwareFeatures(
-    std::unique_ptr<IPUrlMap> bad_ips,
-    MalwareDoneCallback callback,
-    std::unique_ptr<ClientMalwareRequest> request) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  int matched_bad_ips = 0;
-  for (IPUrlMap::const_iterator it = bad_ips->begin();
-       it != bad_ips->end(); ++it) {
-    AddMalwareIpUrlInfo(it->first, it->second, request.get());
-    ++matched_bad_ips;
-    // Limit the number of matched bad IPs in one request to control
-    // the request's size
-    if (matched_bad_ips >= kMaxMalwareIPPerRequest) {
-      break;
-    }
-  }
-  std::move(callback).Run(/*feature_extraction_succeeded=*/true,
-                          std::move(request));
-}
-
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/browser_feature_extractor.h b/chrome/browser/safe_browsing/browser_feature_extractor.h
index d3e9f5c4..8118b02 100644
--- a/chrome/browser/safe_browsing/browser_feature_extractor.h
+++ b/chrome/browser/safe_browsing/browser_feature_extractor.h
@@ -21,13 +21,10 @@
 #include "base/macros.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/time/time.h"
-#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/safe_browsing/ui_manager.h"
 #include "components/history/core/browser/history_types.h"
-#include "content/public/common/resource_type.h"
+#include "components/security_interstitials/content/unsafe_resource.h"
 #include "url/gurl.h"
 
-
 namespace content {
 class WebContents;
 }
@@ -39,40 +36,12 @@
 }
 
 namespace safe_browsing {
-class ClientMalwareRequest;
 class ClientPhishingRequest;
-class ClientSideDetectionHost;
-
-struct IPUrlInfo {
-  // The origin of the final URL for the request to the bad IP address (final =
-  // after redirects).
-  //
-  // The full URL is not available, because in some cases the path
-  // and query may be sanitized away - see https://crbug.com/973885.
-  std::string origin_of_final_url;
-
-  std::string method;
-  std::string referrer;
-  content::ResourceType resource_type;
-
-  IPUrlInfo(const std::string& origin_of_final_url,
-            const std::string& method,
-            const std::string& referrer,
-            const content::ResourceType& resource_type);
-  IPUrlInfo(const IPUrlInfo& other);
-  ~IPUrlInfo();
-};
-
-typedef std::map<std::string, std::vector<IPUrlInfo> > IPUrlMap;
 
 struct BrowseInfo {
   // The URL we're currently browsing.
   GURL url;
 
-  // List of IPv4 and IPv6 addresses from which content was requested
-  // together with the hosts on it, while browsing to the |url|.
-  IPUrlMap ips;
-
   // If a SafeBrowsing interstitial was shown for the current URL
   // this will contain the UnsafeResource struct for that URL.
   std::unique_ptr<security_interstitials::UnsafeResource> unsafe_resource;
@@ -103,15 +72,11 @@
   using DoneCallback =
       base::OnceCallback<void(bool feature_extraction_succeeded,
                               std::unique_ptr<ClientPhishingRequest> request)>;
-  using MalwareDoneCallback =
-      base::OnceCallback<void(bool feature_extraction_succeeded,
-                              std::unique_ptr<ClientMalwareRequest> request)>;
 
   // The caller keeps ownership of the tab and host objects and is
   // responsible for ensuring that they stay valid for the entire
   // lifetime of this object.
-  BrowserFeatureExtractor(content::WebContents* tab,
-                          ClientSideDetectionHost* host);
+  explicit BrowserFeatureExtractor(content::WebContents* tab);
 
   // The destructor will cancel any pending requests.
   virtual ~BrowserFeatureExtractor();
@@ -126,16 +91,6 @@
                                std::unique_ptr<ClientPhishingRequest> request,
                                DoneCallback callback);
 
-  // Begins extraction of the malware related features.  We take ownership
-  // of the request object until |callback| is called.  Once feature extraction
-  // is complete, |callback| will run on the UI thread.  |info| is not expected
-  // to stay valid after ExtractMalwareFeatures returns.  All IPs stored in
-  // |info| will be cleared by calling this function.
-  virtual void ExtractMalwareFeatures(
-      BrowseInfo* info,
-      std::unique_ptr<ClientMalwareRequest> request,
-      MalwareDoneCallback callback);
-
  private:
   // Synchronous browser feature extraction.
   void ExtractBrowseInfoFeatures(const BrowseInfo& info,
@@ -176,15 +131,7 @@
   // is set it will return true and false otherwise.
   bool GetHistoryService(history::HistoryService** history);
 
-  // Helper function which is called when we're done filtering out benign IPs
-  // on the IO thread.  This function is called on the UI thread.
-  void FinishExtractMalwareFeatures(
-      std::unique_ptr<IPUrlMap> bad_ips,
-      MalwareDoneCallback callback,
-      std::unique_ptr<ClientMalwareRequest> request);
-
   content::WebContents* tab_;
-  ClientSideDetectionHost* host_;
   base::CancelableTaskTracker cancelable_task_tracker_;
   base::WeakPtrFactory<BrowserFeatureExtractor> weak_factory_{this};
 
diff --git a/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc b/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc
index c5602f0d..d6f6d66b3 100644
--- a/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc
+++ b/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/message_loop/message_loop_current.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
@@ -25,8 +24,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/history/core/browser/history_backend.h"
 #include "components/history/core/browser/history_service.h"
-#include "components/safe_browsing/db/database_manager.h"
-#include "components/safe_browsing/db/test_database_manager.h"
 #include "components/safe_browsing/proto/csd.pb.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
@@ -51,31 +48,12 @@
 
 namespace {
 
-class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager {
- public:
-  MockSafeBrowsingDatabaseManager() {}
-
-  MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address));
-
- protected:
-  ~MockSafeBrowsingDatabaseManager() override {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
-};
-
 class MockClientSideDetectionHost : public ClientSideDetectionHost {
  public:
-  MockClientSideDetectionHost(
-      content::WebContents* tab,
-      SafeBrowsingDatabaseManager* database_manager)
-      : ClientSideDetectionHost(tab) {
-    set_safe_browsing_managers(NULL, database_manager);
-  }
+  explicit MockClientSideDetectionHost(content::WebContents* tab)
+      : ClientSideDetectionHost(tab) {}
 
   ~MockClientSideDetectionHost() override {}
-
-  MOCK_METHOD1(IsBadIpAddress, bool(const std::string&));
 };
 }  // namespace
 
@@ -92,11 +70,8 @@
     ASSERT_TRUE(profile()->CreateHistoryService(
         true /* delete_file */, false /* no_db */));
 
-    db_manager_ = new StrictMock<MockSafeBrowsingDatabaseManager>();
-    host_.reset(new StrictMock<MockClientSideDetectionHost>(
-        web_contents(), db_manager_.get()));
-    extractor_.reset(
-        new BrowserFeatureExtractor(web_contents(), host_.get()));
+    host_.reset(new StrictMock<MockClientSideDetectionHost>(web_contents()));
+    extractor_.reset(new BrowserFeatureExtractor(web_contents()));
     num_pending_ = 0;
     browse_info_.reset(new BrowseInfo);
   }
@@ -104,7 +79,6 @@
   void TearDown() override {
     extractor_.reset();
     host_.reset();
-    db_manager_.reset();
     ChromeRenderViewHostTestHarness::TearDown();
     ASSERT_EQ(0, num_pending_);
   }
@@ -182,55 +156,12 @@
     }
   }
 
-  std::unique_ptr<ClientMalwareRequest> ExtractMalwareFeatures(
-      std::unique_ptr<ClientMalwareRequest> request) {
-    // Feature extraction takes ownership of the request object
-    // and passes it along to the done callback in the end.
-    uintptr_t key = StartExtractMalwareFeatures(std::move(request));
-    EXPECT_TRUE(base::MessageLoopCurrentForUI::IsSet());
-    base::RunLoop().Run();
-    auto iterator = malware_results_.find(key);
-    EXPECT_TRUE(iterator != malware_results_.end());
-    if (iterator == malware_results_.end())
-      return nullptr;
-
-    auto result = std::move(iterator->second);
-    malware_results_.erase(iterator);
-    EXPECT_TRUE(result.success);
-    EXPECT_TRUE(result.request);
-    return std::move(result.request);
-  }
-
-  uintptr_t StartExtractMalwareFeatures(
-      std::unique_ptr<ClientMalwareRequest> request) {
-    uintptr_t key = reinterpret_cast<uintptr_t>(request.get());
-    EXPECT_EQ(0u, malware_results_.count(key));
-    ++num_pending_;
-    extractor_->ExtractMalwareFeatures(
-        browse_info_.get(), std::move(request),
-        base::Bind(&BrowserFeatureExtractorTest::ExtractMalwareFeaturesDone,
-                   base::Unretained(this)));
-    return key;
-  }
-
-  void GetMalwareUrls(
-      const ClientMalwareRequest& request,
-      std::map<std::string, std::set<std::string> >* urls) {
-    for (int i = 0; i < request.bad_ip_url_info_size(); ++i) {
-      const ClientMalwareRequest::UrlInfo& urlinfo =
-          request.bad_ip_url_info(i);
-      (*urls)[urlinfo.ip()].insert(urlinfo.url());
-    }
-  }
-
   int num_pending_;  // Number of pending feature extractions.
   std::unique_ptr<BrowserFeatureExtractor> extractor_;
   std::map<uintptr_t, RequestAndResult<ClientPhishingRequest>>
       phishing_results_;
-  std::map<uintptr_t, RequestAndResult<ClientMalwareRequest>> malware_results_;
   std::unique_ptr<BrowseInfo> browse_info_;
   std::unique_ptr<StrictMock<MockClientSideDetectionHost>> host_;
-  scoped_refptr<StrictMock<MockSafeBrowsingDatabaseManager> > db_manager_;
 
  private:
   void ExtractFeaturesDone(bool success,
@@ -243,18 +174,6 @@
       base::RunLoop::QuitCurrentWhenIdleDeprecated();
     }
   }
-
-  void ExtractMalwareFeaturesDone(
-      bool success,
-      std::unique_ptr<ClientMalwareRequest> request) {
-    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
-    uintptr_t key = reinterpret_cast<uintptr_t>(request.get());
-    ASSERT_EQ(0U, malware_results_.count(key));
-    malware_results_[key] = {std::move(request), success};
-    if (--num_pending_ == 0) {
-      base::RunLoop::QuitCurrentWhenIdleDeprecated();
-    }
-  }
 };
 
 TEST_F(BrowserFeatureExtractorTest, UrlNotInHistory) {
@@ -630,70 +549,4 @@
                    features[kSafeBrowsingThreatType]);
 }
 
-TEST_F(BrowserFeatureExtractorTest, MalwareFeatures) {
-  auto request = std::make_unique<ClientMalwareRequest>();
-  request->set_url("http://www.foo.com/");
-
-  std::vector<IPUrlInfo> bad_urls;
-  bad_urls.push_back(
-      IPUrlInfo("http://bad.com", "GET", "", content::ResourceType::kScript));
-  bad_urls.push_back(
-      IPUrlInfo("http://evil.com", "GET", "", content::ResourceType::kScript));
-  browse_info_->ips.insert(std::make_pair("193.5.163.8", bad_urls));
-  browse_info_->ips.insert(std::make_pair("92.92.92.92", bad_urls));
-  std::vector<IPUrlInfo> good_urls;
-  good_urls.push_back(
-      IPUrlInfo("http://ok.com", "GET", "", content::ResourceType::kScript));
-  browse_info_->ips.insert(std::make_pair("23.94.78.1", good_urls));
-  EXPECT_CALL(*db_manager_, MatchMalwareIP("193.5.163.8"))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*db_manager_, MatchMalwareIP("92.92.92.92"))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*db_manager_, MatchMalwareIP("23.94.78.1"))
-      .WillOnce(Return(false));
-
-  request = ExtractMalwareFeatures(std::move(request));
-  ASSERT_TRUE(request);
-
-  EXPECT_EQ(4, request->bad_ip_url_info_size());
-  std::map<std::string, std::set<std::string> > result_urls;
-  GetMalwareUrls(*request, &result_urls);
-
-  EXPECT_EQ(2U, result_urls.size());
-  EXPECT_TRUE(result_urls.count("193.5.163.8"));
-  std::set<std::string> urls = result_urls["193.5.163.8"];
-  EXPECT_EQ(2U, urls.size());
-  EXPECT_TRUE(urls.find("http://bad.com") != urls.end());
-  EXPECT_TRUE(urls.find("http://evil.com") != urls.end());
-  EXPECT_TRUE(result_urls.count("92.92.92.92"));
-  urls = result_urls["92.92.92.92"];
-  EXPECT_EQ(2U, urls.size());
-  EXPECT_TRUE(urls.find("http://bad.com") != urls.end());
-  EXPECT_TRUE(urls.find("http://evil.com") != urls.end());
-}
-
-TEST_F(BrowserFeatureExtractorTest, MalwareFeatures_ExceedLimit) {
-  auto request = std::make_unique<ClientMalwareRequest>();
-  request->set_url("http://www.foo.com/");
-
-  std::vector<IPUrlInfo> bad_urls;
-  bad_urls.push_back(
-      IPUrlInfo("http://bad.com", "GET", "", content::ResourceType::kScript));
-  std::vector<std::string> ips;
-  for (int i = 0; i < 7; ++i) {  // Add 7 ips
-    std::string ip = base::StringPrintf("%d.%d.%d.%d", i, i, i, i);
-    ips.push_back(ip);
-    browse_info_->ips.insert(std::make_pair(ip, bad_urls));
-
-    // First ip is good but all the others are bad.
-    EXPECT_CALL(*db_manager_, MatchMalwareIP(ip)).WillOnce(Return(i > 0));
-  }
-
-  request = ExtractMalwareFeatures(std::move(request));
-  ASSERT_TRUE(request);
-
-  // The number of IP matched url we store is capped at 5 IPs per request.
-  EXPECT_EQ(5, request->bad_ip_url_info_size());
-}
-
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc
index 151f96e..b20d070f 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -53,13 +53,10 @@
 
 namespace safe_browsing {
 
-const size_t ClientSideDetectionHost::kMaxUrlsPerIP = 20;
-const size_t ClientSideDetectionHost::kMaxIPsPerBrowse = 200;
-
 typedef base::Callback<void(bool)> ShouldClassifyUrlCallback;
 
 // This class is instantiated each time a new toplevel URL loads, and
-// asynchronously checks whether the malware and phishing classifiers should run
+// asynchronously checks whether the phishing classifier should run
 // for this URL.  If so, it notifies the host class by calling the provided
 // callback form the UI thread.  Objects of this class are ref-counted and will
 // be destroyed once nobody uses it anymore.  If |web_contents|, |csd_service|
@@ -72,7 +69,6 @@
   ShouldClassifyUrlRequest(
       content::NavigationHandle* navigation_handle,
       const ShouldClassifyUrlCallback& start_phishing_classification,
-      const ShouldClassifyUrlCallback& start_malware_classification,
       WebContents* web_contents,
       ClientSideDetectionService* csd_service,
       SafeBrowsingDatabaseManager* database_manager,
@@ -81,8 +77,7 @@
         csd_service_(csd_service),
         database_manager_(database_manager),
         host_(host),
-        start_phishing_classification_cb_(start_phishing_classification),
-        start_malware_classification_cb_(start_malware_classification) {
+        start_phishing_classification_cb_(start_phishing_classification) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     DCHECK(web_contents_);
     DCHECK(csd_service_);
@@ -99,39 +94,25 @@
 
     // We start by doing some simple checks that can run on the UI thread.
     UMA_HISTOGRAM_BOOLEAN("SBClientPhishing.ClassificationStart", 1);
-    UMA_HISTOGRAM_BOOLEAN("SBClientMalware.ClassificationStart", 1);
 
     // Only classify [X]HTML documents.
     if (mime_type_ != "text/html" && mime_type_ != "application/xhtml+xml") {
-      DVLOG(1) << "Skipping phishing classification for URL: " << url_
-               << " because it has an unsupported MIME type: "
-               << mime_type_;
       DontClassifyForPhishing(NO_CLASSIFY_UNSUPPORTED_MIME_TYPE);
     }
 
     if (csd_service_->IsPrivateIPAddress(
             remote_endpoint_.ToStringWithoutPort())) {
-      DVLOG(1) << "Skipping phishing classification for URL: " << url_
-               << " because of hosting on private IP: "
-               << remote_endpoint_.ToStringWithoutPort();
       DontClassifyForPhishing(NO_CLASSIFY_PRIVATE_IP);
-      DontClassifyForMalware(NO_CLASSIFY_PRIVATE_IP);
     }
 
     // For phishing we only classify HTTP or HTTPS pages.
     if (!url_.SchemeIsHTTPOrHTTPS()) {
-      DVLOG(1) << "Skipping phishing classification for URL: " << url_
-               << " because it is not HTTP or HTTPS: "
-               << remote_endpoint_.ToStringWithoutPort();
       DontClassifyForPhishing(NO_CLASSIFY_SCHEME_NOT_SUPPORTED);
     }
 
     // Don't run any classifier if the tab is incognito.
     if (web_contents_->GetBrowserContext()->IsOffTheRecord()) {
-      DVLOG(1) << "Skipping phishing and malware classification for URL: "
-               << url_ << " because we're browsing incognito.";
       DontClassifyForPhishing(NO_CLASSIFY_OFF_THE_RECORD);
-      DontClassifyForMalware(NO_CLASSIFY_OFF_THE_RECORD);
     }
 
     // Don't start classification if |url_| is whitelisted by enterprise policy.
@@ -139,7 +120,6 @@
         Profile::FromBrowserContext(web_contents_->GetBrowserContext());
     if (profile && IsURLWhitelistedByPolicy(url_, *profile->GetPrefs())) {
       DontClassifyForPhishing(NO_CLASSIFY_WHITELISTED_BY_POLICY);
-      DontClassifyForMalware(NO_CLASSIFY_WHITELISTED_BY_POLICY);
     }
 
     // We lookup the csd-whitelist before we lookup the cache because
@@ -147,7 +127,7 @@
     // the csd-whitelist we won't start phishing classification.  The
     // csd-whitelist check has to be done on the IO thread because it
     // uses the SafeBrowsing service class.
-    if (ShouldClassifyForPhishing() || ShouldClassifyForMalware()) {
+    if (ShouldClassifyForPhishing()) {
       base::PostTask(
           FROM_HERE, {BrowserThread::IO},
           base::BindOnce(&ShouldClassifyUrlRequest::CheckSafeBrowsingDatabase,
@@ -157,7 +137,6 @@
 
   void Cancel() {
     DontClassifyForPhishing(NO_CLASSIFY_CANCEL);
-    DontClassifyForMalware(NO_CLASSIFY_CANCEL);
     // Just to make sure we don't do anything stupid we reset all these
     // pointers except for the safebrowsing service class which may be
     // accessed by CheckSafeBrowsingDatabase().
@@ -197,46 +176,24 @@
     return !start_phishing_classification_cb_.is_null();
   }
 
-  bool ShouldClassifyForMalware() const {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    return !start_malware_classification_cb_.is_null();
-  }
-
   void DontClassifyForPhishing(PreClassificationCheckFailures reason) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     if (ShouldClassifyForPhishing()) {
       // Track the first reason why we stopped classifying for phishing.
       UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail",
                                 reason, NO_CLASSIFY_MAX);
-      DVLOG(2) << "Failed phishing pre-classification checks.  Reason: "
-               << reason;
       start_phishing_classification_cb_.Run(false);
     }
     start_phishing_classification_cb_.Reset();
   }
 
-  void DontClassifyForMalware(PreClassificationCheckFailures reason) {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    if (ShouldClassifyForMalware()) {
-      // Track the first reason why we stopped classifying for malware.
-      UMA_HISTOGRAM_ENUMERATION("SBClientMalware.PreClassificationCheckFail",
-                                reason, NO_CLASSIFY_MAX);
-      DVLOG(2) << "Failed malware pre-classification checks.  Reason: "
-               << reason;
-      start_malware_classification_cb_.Run(false);
-    }
-    start_malware_classification_cb_.Reset();
-  }
-
   void CheckSafeBrowsingDatabase(const GURL& url) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     PreClassificationCheckFailures phishing_reason = NO_CLASSIFY_MAX;
-    PreClassificationCheckFailures malware_reason = NO_CLASSIFY_MAX;
     if (!database_manager_.get()) {
       // We cannot check the Safe Browsing whitelists so we stop here
       // for safety.
       OnWhitelistCheckDoneOnIO(url, NO_CLASSIFY_NO_DATABASE_MANAGER,
-                               NO_CLASSIFY_NO_DATABASE_MANAGER,
                                /*match_whitelist=*/false);
       return;
     }
@@ -246,44 +203,37 @@
     base::Callback<void(bool)> result_callback =
         base::Bind(&ClientSideDetectionHost::ShouldClassifyUrlRequest::
                        OnWhitelistCheckDoneOnIO,
-                   this, url, phishing_reason, malware_reason);
+                   this, url, phishing_reason);
     AllowlistCheckerClient::StartCheckCsdWhitelist(database_manager_, url,
                                                    result_callback);
   }
 
   void OnWhitelistCheckDoneOnIO(const GURL& url,
                                 PreClassificationCheckFailures phishing_reason,
-                                PreClassificationCheckFailures malware_reason,
                                 bool match_whitelist) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     // We don't want to call the classification callbacks from the IO
     // thread so we simply pass the results of this method to CheckCache()
     // which is called on the UI thread;
     if (match_whitelist) {
-      DVLOG(1) << "Skipping phishing classification for URL: " << url
-               << " because it matches the csd whitelist";
       phishing_reason = NO_CLASSIFY_MATCH_CSD_WHITELIST;
     }
     base::PostTask(FROM_HERE, {BrowserThread::UI},
                    base::BindOnce(&ShouldClassifyUrlRequest::CheckCache, this,
-                                  phishing_reason, malware_reason));
+                                  phishing_reason));
   }
 
-  void CheckCache(PreClassificationCheckFailures phishing_reason,
-                  PreClassificationCheckFailures malware_reason) {
+  void CheckCache(PreClassificationCheckFailures phishing_reason) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     if (phishing_reason != NO_CLASSIFY_MAX)
       DontClassifyForPhishing(phishing_reason);
-    if (malware_reason != NO_CLASSIFY_MAX)
-      DontClassifyForMalware(malware_reason);
-    if (!ShouldClassifyForMalware() && !ShouldClassifyForPhishing()) {
+    if (!ShouldClassifyForPhishing()) {
       return;  // No point in doing anything else.
     }
     // If result is cached, we don't want to run classification again.
     // In that case we're just trying to show the warning.
     bool is_phishing;
     if (csd_service_->GetValidCachedResult(url_, &is_phishing)) {
-      DVLOG(1) << "Satisfying request for " << url_ << " from cache";
       UMA_HISTOGRAM_BOOLEAN("SBClientPhishing.RequestSatisfiedFromCache", 1);
       // Since we are already on the UI thread, this is safe.
       host_->MaybeShowPhishingWarning(url_, is_phishing);
@@ -296,17 +246,10 @@
     // phishing we want to send a request to the server to give ourselves
     // a chance to fix misclassifications.
     if (csd_service_->IsInCache(url_)) {
-      DVLOG(1) << "Reporting limit skipped for " << url_
-               << " as it was in the cache.";
       UMA_HISTOGRAM_BOOLEAN("SBClientPhishing.ReportLimitSkipped", 1);
     } else if (csd_service_->OverPhishingReportLimit()) {
-      DVLOG(1) << "Too many report phishing requests sent recently, "
-               << "not running classification for " << url_;
       DontClassifyForPhishing(NO_CLASSIFY_TOO_MANY_REPORTS);
     }
-    if (csd_service_->OverMalwareReportLimit()) {
-      DontClassifyForMalware(NO_CLASSIFY_TOO_MANY_REPORTS);
-    }
 
     // Everything checks out, so start classification.
     // |web_contents_| is safe to call as we will be destructed
@@ -317,12 +260,6 @@
       // returns false.
       start_phishing_classification_cb_.Reset();
     }
-    if (ShouldClassifyForMalware()) {
-      start_malware_classification_cb_.Run(true);
-      // Reset the callback to make sure ShouldClassifyForMalware()
-      // returns false.
-      start_malware_classification_cb_.Reset();
-    }
   }
 
   GURL url_;
@@ -336,7 +273,6 @@
   ClientSideDetectionHost* host_;
 
   ShouldClassifyUrlCallback start_phishing_classification_cb_;
-  ShouldClassifyUrlCallback start_malware_classification_cb_;
 
   DISALLOW_COPY_AND_ASSIGN(ShouldClassifyUrlRequest);
 };
@@ -351,14 +287,12 @@
     : content::WebContentsObserver(tab),
       csd_service_(nullptr),
       classification_request_(nullptr),
-      should_extract_malware_features_(true),
-      should_classify_for_malware_(false),
       pageload_complete_(false),
       unsafe_unique_page_id_(-1) {
   DCHECK(tab);
   // Note: csd_service_ and sb_service will be NULL here in testing.
   csd_service_ = g_browser_process->safe_browsing_detection_service();
-  feature_extractor_.reset(new BrowserFeatureExtractor(tab, this));
+  feature_extractor_.reset(new BrowserFeatureExtractor(tab));
 
   scoped_refptr<SafeBrowsingService> sb_service =
       g_browser_process->safe_browsing_service();
@@ -376,21 +310,6 @@
 
 void ClientSideDetectionHost::DidFinishNavigation(
     content::NavigationHandle* navigation_handle) {
-  if (browse_info_.get() && should_extract_malware_features_ &&
-      navigation_handle->HasCommitted() && !navigation_handle->IsDownload() &&
-      !navigation_handle->IsSameDocument()) {
-    content::ResourceType resource_type =
-        navigation_handle->IsInMainFrame() ? content::ResourceType::kMainFrame
-                                           : content::ResourceType::kSubFrame;
-    url::Origin origin_of_final_url =
-        url::Origin::Create(navigation_handle->GetURL());
-    UpdateIPUrlMap(
-        navigation_handle->GetSocketAddress().ToStringWithoutPort() /* ip */,
-        origin_of_final_url.Serialize(),
-        navigation_handle->IsPost() ? "POST" : "GET",
-        navigation_handle->GetReferrer().url.spec(), resource_type);
-  }
-
   if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
     return;
 
@@ -433,37 +352,17 @@
         navigation_handle->GetResponseHeaders()->response_code();
   }
 
-  should_extract_malware_features_ = true;
-  should_classify_for_malware_ = false;
   pageload_complete_ = false;
 
-  // Check whether we can cassify the current URL for phishing or malware.
+  // Check whether we can cassify the current URL for phishing.
   classification_request_ = new ShouldClassifyUrlRequest(
       navigation_handle,
       base::Bind(&ClientSideDetectionHost::OnPhishingPreClassificationDone,
                  weak_factory_.GetWeakPtr()),
-      base::Bind(&ClientSideDetectionHost::OnMalwarePreClassificationDone,
-                 weak_factory_.GetWeakPtr()),
       web_contents(), csd_service_, database_manager_.get(), this);
   classification_request_->Start();
 }
 
-void ClientSideDetectionHost::ResourceLoadComplete(
-    content::RenderFrameHost* render_frame_host,
-    const content::GlobalRequestID& request_id,
-    const content::mojom::ResourceLoadInfo& resource_load_info) {
-  if (!content::IsResourceTypeFrame(resource_load_info.resource_type) &&
-      browse_info_.get() && should_extract_malware_features_ &&
-      !resource_load_info.origin_of_final_url.opaque() &&
-      resource_load_info.network_info->remote_endpoint.has_value()) {
-    UpdateIPUrlMap(
-        resource_load_info.network_info->remote_endpoint->ToStringWithoutPort(),
-        resource_load_info.origin_of_final_url.Serialize(),
-        resource_load_info.method, resource_load_info.referrer.spec(),
-        resource_load_info.resource_type);
-  }
-}
-
 void ClientSideDetectionHost::OnSafeBrowsingHit(
     const security_interstitials::UnsafeResource& resource) {
   if (!web_contents())
@@ -509,8 +408,6 @@
     bool should_classify) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (browse_info_.get() && should_classify) {
-    DVLOG(1) << "Instruct renderer to start phishing detection for URL: "
-             << browse_info_->url;
     content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
     phishing_detector_.reset();
     rfh->GetRemoteInterfaces()->GetInterface(
@@ -522,50 +419,6 @@
   }
 }
 
-void ClientSideDetectionHost::OnMalwarePreClassificationDone(
-    bool should_classify) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // If classification checks failed we should stop extracting malware features.
-  DVLOG(2) << "Malware pre-classification checks done. Should classify: "
-           << should_classify;
-  should_extract_malware_features_ = should_classify;
-  should_classify_for_malware_ = should_classify;
-  MaybeStartMalwareFeatureExtraction();
-}
-
-void ClientSideDetectionHost::DidStopLoading() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (!csd_service_ || !browse_info_.get())
-    return;
-  DVLOG(2) << "Page finished loading.";
-  pageload_complete_ = true;
-  MaybeStartMalwareFeatureExtraction();
-}
-
-void ClientSideDetectionHost::MaybeStartMalwareFeatureExtraction() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (csd_service_ && browse_info_.get() &&
-      should_classify_for_malware_ &&
-      pageload_complete_) {
-    std::unique_ptr<ClientMalwareRequest> malware_request(
-        new ClientMalwareRequest);
-    // Start browser-side malware feature extraction.  Once we're done it will
-    // send the malware client verdict request.
-    malware_request->set_url(browse_info_->url.spec());
-    const GURL& referrer = browse_info_->referrer;
-    if (referrer.SchemeIs("http")) {  // Only send http urls.
-      malware_request->set_referrer_url(referrer.spec());
-    }
-    // This function doesn't expect browse_info_ to stay around after this
-    // function returns.
-    feature_extractor_->ExtractMalwareFeatures(
-        browse_info_.get(), std::move(malware_request),
-        base::Bind(&ClientSideDetectionHost::MalwareFeatureExtractionDone,
-                   weak_factory_.GetWeakPtr()));
-    should_classify_for_malware_ = false;
-  }
-}
-
 void ClientSideDetectionHost::PhishingDetectionDone(
     mojom::PhishingDetectorResult result,
     const std::string& verdict_str) {
@@ -589,7 +442,7 @@
       verdict->IsInitialized()) {
     // We only send phishing verdict to the server if the verdict is phishing or
     // if a SafeBrowsing interstitial was already shown for this site.  E.g., a
-    // malware or phishing interstitial was shown but the user clicked
+    // phishing interstitial was shown but the user clicked
     // through.
     if (verdict->is_phishing() || DidShowSBInterstitial()) {
       if (DidShowSBInterstitial()) {
@@ -635,49 +488,10 @@
   }
 }
 
-void ClientSideDetectionHost::MaybeShowMalwareWarning(GURL original_url,
-                                                      GURL malware_url,
-                                                      bool is_malware) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DVLOG(2) << "Received server malawre IP verdict for URL:" << malware_url
-           << " is_malware:" << is_malware;
-  UMA_HISTOGRAM_BOOLEAN(
-      "SBClientMalware.ServerDeterminesMalware",
-      is_malware);
-  if (is_malware && malware_url.is_valid() && original_url.is_valid()) {
-    DCHECK(web_contents());
-    if (ui_manager_.get()) {
-      security_interstitials::UnsafeResource resource;
-      resource.url = malware_url;
-      resource.original_url = original_url;
-      resource.is_subresource = (malware_url.host() != original_url.host());
-      resource.threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE;
-      resource.threat_source =
-          safe_browsing::ThreatSource::CLIENT_SIDE_DETECTION;
-      resource.web_contents_getter = safe_browsing::SafeBrowsingUIManager::
-          UnsafeResource::GetWebContentsGetter(
-              web_contents()->GetMainFrame()->GetProcess()->GetID(),
-              web_contents()->GetMainFrame()->GetRoutingID());
-
-      if (!ui_manager_->IsWhitelisted(resource)) {
-        // We need to stop any pending navigations, otherwise the interstitial
-        // might not get created properly.
-        web_contents()->GetController().DiscardNonCommittedEntries();
-      }
-      ui_manager_->DisplayBlockingPage(resource);
-    }
-    // If there is true malware verdict, invalidate weakptr so that no longer
-    // consider the phishing vedict.
-    weak_factory_.InvalidateWeakPtrs();
-  }
-}
-
 void ClientSideDetectionHost::FeatureExtractionDone(
     bool success,
     std::unique_ptr<ClientPhishingRequest> request) {
   DCHECK(request);
-  DVLOG(2) << "Feature extraction done (success:" << success << ") for URL: "
-           << request->url() << ". Start sending client phishing request.";
   ClientSideDetectionService::ClientReportPhishingRequestCallback callback;
   // If the client-side verdict isn't phishing we don't care about the server
   // response because we aren't going to display a warning.
@@ -693,48 +507,6 @@
       IsExtendedReportingEnabled(*profile->GetPrefs()), callback);
 }
 
-void ClientSideDetectionHost::MalwareFeatureExtractionDone(
-    bool feature_extraction_success,
-    std::unique_ptr<ClientMalwareRequest> request) {
-  DCHECK(request.get());
-  DVLOG(2) << "Malware Feature extraction done for URL: " << request->url()
-           << ", with badip url count:" << request->bad_ip_url_info_size();
-  UMA_HISTOGRAM_BOOLEAN(
-      "SBClientMalware.ResourceUrlMatchedBadIp",
-      request->bad_ip_url_info_size() > 0);
-  // Send ping if there is matching features.
-  if (feature_extraction_success && request->bad_ip_url_info_size() > 0) {
-    DVLOG(1) << "Start sending client malware request.";
-    ClientSideDetectionService::ClientReportMalwareRequestCallback callback;
-    callback = base::Bind(&ClientSideDetectionHost::MaybeShowMalwareWarning,
-                          weak_factory_.GetWeakPtr());
-    csd_service_->SendClientReportMalwareRequest(request.release(), callback);
-  }
-}
-
-void ClientSideDetectionHost::UpdateIPUrlMap(
-    const std::string& ip,
-    const std::string& origin_of_final_url,
-    const std::string& method,
-    const std::string& referrer,
-    const ResourceType resource_type) {
-  if (ip.empty() || origin_of_final_url.empty())
-    return;
-
-  auto it = browse_info_->ips.find(ip);
-  if (it == browse_info_->ips.end()) {
-    if (browse_info_->ips.size() < kMaxIPsPerBrowse) {
-      std::vector<IPUrlInfo> url_infos;
-      url_infos.push_back(
-          IPUrlInfo(origin_of_final_url, method, referrer, resource_type));
-      browse_info_->ips.insert(make_pair(ip, url_infos));
-    }
-  } else if (it->second.size() < kMaxUrlsPerIP) {
-    it->second.push_back(
-        IPUrlInfo(origin_of_final_url, method, referrer, resource_type));
-  }
-}
-
 bool ClientSideDetectionHost::DidShowSBInterstitial() const {
   if (unsafe_unique_page_id_ <= 0 || !web_contents()) {
     return false;
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/chrome/browser/safe_browsing/client_side_detection_host.h
index 8e88e37d..fe007adb 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host.h
+++ b/chrome/browser/safe_browsing/client_side_detection_host.h
@@ -46,10 +46,6 @@
   // we should classify the new URL.
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
-  void ResourceLoadComplete(
-      content::RenderFrameHost* render_frame_host,
-      const content::GlobalRequestID& request_id,
-      const content::mojom::ResourceLoadInfo& resource_load_info) override;
 
   // Called when the SafeBrowsingService found a hit with one of the
   // SafeBrowsing lists.  This method is called on the UI thread.
@@ -71,10 +67,6 @@
       SafeBrowsingUIManager* ui_manager,
       SafeBrowsingDatabaseManager* database_manager);
 
-  // Called when pre-classification checks are done for the malware classifiers.
-  // Overridden in test.
-  virtual void OnMalwarePreClassificationDone(bool should_classify);
-
  private:
   friend class ClientSideDetectionHostTestBase;
   class ShouldClassifyUrlRequest;
@@ -94,39 +86,12 @@
   // Otherwise, we do nothing.  Called in UI thread.
   void MaybeShowPhishingWarning(GURL phishing_url, bool is_phishing);
 
-  // Callback that is called when the malware IP server ping back is
-  // done. Display an interstitial if |is_malware| is true.
-  // Otherwise, we do nothing.  Called in UI thread.
-  void MaybeShowMalwareWarning(GURL original_url, GURL malware_url,
-                               bool is_malware);
-
   // Callback that is called when the browser feature extractor is done.
   // This method is responsible for deleting the request object.  Called on
   // the UI thread.
   void FeatureExtractionDone(bool success,
                              std::unique_ptr<ClientPhishingRequest> request);
 
-  // Start malware classification once the onload handler was called and
-  // malware pre-classification checks are done and passed.
-  void MaybeStartMalwareFeatureExtraction();
-
-  // Function to be called when the browser malware feature extractor is done.
-  // Called on the UI thread.
-  void MalwareFeatureExtractionDone(
-      bool success,
-      std::unique_ptr<ClientMalwareRequest> request);
-
-  // Update the entries in browse_info_->ips map.
-  void UpdateIPUrlMap(const std::string& ip,
-                      const std::string& origin_of_final_url,
-                      const std::string& method,
-                      const std::string& referrer,
-                      const content::ResourceType resource_type);
-
-  // Inherited from WebContentsObserver.  This is called once the page is
-  // done loading.
-  void DidStopLoading() override;
-
   // Returns true if the user has seen a regular SafeBrowsing
   // interstitial for the current page.  This is only true if the user has
   // actually clicked through the warning.  This method is called on the UI
@@ -162,11 +127,6 @@
 
   // Max number of ips we save for each browse
   static const size_t kMaxIPsPerBrowse;
-  // Max number of urls we report for each malware IP.
-  static const size_t kMaxUrlsPerIP;
-
-  bool should_extract_malware_features_;
-  bool should_classify_for_malware_;
   bool pageload_complete_;
 
   // Unique page ID of the most recent unsafe site that was loaded in this tab
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
index 9fbe2b23..bd9f2a4 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -96,21 +96,7 @@
           other.is_phishing() == arg.is_phishing());
 }
 
-MATCHER_P(PartiallyEqualMalwareVerdict, other, "") {
-  if (other.url() != arg.url() ||
-      other.referrer_url() != arg.referrer_url() ||
-      other.bad_ip_url_info_size() != arg.bad_ip_url_info_size())
-    return false;
-
-  for (int i = 0; i < other.bad_ip_url_info_size(); ++i) {
-    if (other.bad_ip_url_info(i).ip() != arg.bad_ip_url_info(i).ip() ||
-        other.bad_ip_url_info(i).url() != arg.bad_ip_url_info(i).url())
-    return false;
-  }
-  return true;
-}
-
-// Test that the callback is NULL when the verdict is not phishing.
+// Test that the callback is nullptr when the verdict is not phishing.
 MATCHER(CallbackIsNull, "") {
   return arg.is_null();
 }
@@ -129,14 +115,10 @@
                void(ClientPhishingRequest*,
                     bool,
                     const ClientReportPhishingRequestCallback&));
-  MOCK_METHOD2(SendClientReportMalwareRequest,
-               void(ClientMalwareRequest*,
-                    const ClientReportMalwareRequestCallback&));
   MOCK_CONST_METHOD1(IsPrivateIPAddress, bool(const std::string&));
   MOCK_METHOD2(GetValidCachedResult, bool(const GURL&, bool*));
   MOCK_METHOD1(IsInCache, bool(const GURL&));
   MOCK_METHOD0(OverPhishingReportLimit, bool());
-  MOCK_METHOD0(OverMalwareReportLimit, bool());
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService);
@@ -173,7 +155,6 @@
 
   MOCK_METHOD2(CheckCsdWhitelistUrl,
                AsyncMatch(const GURL&, SafeBrowsingDatabaseManager::Client*));
-  MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address));
 
  protected:
   ~MockSafeBrowsingDatabaseManager() override {}
@@ -184,21 +165,14 @@
 
 class MockBrowserFeatureExtractor : public BrowserFeatureExtractor {
  public:
-  explicit MockBrowserFeatureExtractor(
-      WebContents* tab,
-      ClientSideDetectionHost* host)
-      : BrowserFeatureExtractor(tab, host) {}
+  explicit MockBrowserFeatureExtractor(WebContents* tab)
+      : BrowserFeatureExtractor(tab) {}
   ~MockBrowserFeatureExtractor() override {}
 
   MOCK_METHOD3(ExtractFeatures,
                void(const BrowseInfo*,
                     std::unique_ptr<ClientPhishingRequest>,
                     BrowserFeatureExtractor::DoneCallback));
-
-  MOCK_METHOD3(ExtractMalwareFeatures,
-               void(BrowseInfo*,
-                    std::unique_ptr<ClientMalwareRequest>,
-                    BrowserFeatureExtractor::MalwareDoneCallback));
 };
 
 }  // namespace
@@ -324,10 +298,6 @@
 
   void DidStopLoading() { csd_host_->DidStopLoading(); }
 
-  void UpdateIPUrlMap(const std::string& ip, const std::string& host) {
-    csd_host_->UpdateIPUrlMap(ip, host, "", "", content::ResourceType::kObject);
-  }
-
   BrowseInfo* GetBrowseInfo() {
     return csd_host_->browse_info_.get();
   }
@@ -337,8 +307,7 @@
                                      const bool* match_csd_whitelist,
                                      const bool* get_valid_cached_result,
                                      const bool* is_in_cache,
-                                     const bool* over_phishing_report_limit,
-                                     const bool* over_malware_report_limit) {
+                                     const bool* over_phishing_report_limit) {
     if (is_private) {
       EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_))
           .WillOnce(Return(*is_private));
@@ -360,10 +329,6 @@
       EXPECT_CALL(*csd_service_, OverPhishingReportLimit())
           .WillOnce(Return(*over_phishing_report_limit));
     }
-    if (over_malware_report_limit) {
-      EXPECT_CALL(*csd_service_, OverMalwareReportLimit())
-          .WillOnce(Return(*over_malware_report_limit));
-    }
   }
 
   void WaitAndCheckPreClassificationChecks() {
@@ -386,10 +351,6 @@
     csd_host_->browse_info_->referrer = referrer;
   }
 
-  void ExpectShouldClassifyForMalwareResult(bool should_classify) {
-    EXPECT_EQ(should_classify, csd_host_->should_classify_for_malware_);
-  }
-
   void TestUnsafeResourceCopied(const UnsafeResource& resource) {
     ASSERT_TRUE(csd_host_->unsafe_resource_.get());
     // Test that the resource from OnSafeBrowsingHit notification was copied
@@ -476,18 +437,6 @@
     ASSERT_FALSE(csd_host_->DidShowSBInterstitial());
   }
 
-  void CheckIPUrlEqual(const std::vector<IPUrlInfo>& expect,
-                       const std::vector<IPUrlInfo>& result) {
-    ASSERT_EQ(expect.size(), result.size());
-
-    for (unsigned int i = 0; i < expect.size(); ++i) {
-      EXPECT_EQ(expect[i].origin_of_final_url, result[i].origin_of_final_url);
-      EXPECT_EQ(expect[i].method, result[i].method);
-      EXPECT_EQ(expect[i].referrer, result[i].referrer);
-      EXPECT_EQ(expect[i].resource_type, result[i].resource_type);
-    }
-  }
-
  protected:
   std::unique_ptr<ClientSideDetectionHost> csd_host_;
   std::unique_ptr<StrictMock<MockClientSideDetectionService>> csd_service_;
@@ -514,9 +463,7 @@
   // Case 0: renderer sends an invalid verdict string that we're unable to
   // parse.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
   EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0);
   PhishingDetectionDone("Invalid Protocol Buffer");
@@ -527,9 +474,7 @@
   // Case 1: client thinks the page is phishing.  The server does not agree.
   // No interstitial is shown.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
@@ -564,9 +509,7 @@
   // Case 2: client thinks the page is phishing and so does the server but
   // showing the interstitial is disabled => no interstitial is shown.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
@@ -601,9 +544,7 @@
   // Case 3: client thinks the page is phishing and so does the server.
   // We show an interstitial.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
@@ -657,9 +598,7 @@
   // server responds for both requests with a phishing verdict.  Only
   // a single interstitial is shown for the second URL.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
@@ -688,11 +627,10 @@
   // Set this back to a normal browser feature extractor since we're using
   // NavigateAndCommit() and it's easier to use the real thing than setting up
   // mock expectations.
-  SetFeatureExtractor(new BrowserFeatureExtractor(web_contents(),
-                                                  csd_host_.get()));
+  SetFeatureExtractor(new BrowserFeatureExtractor(web_contents()));
   GURL other_phishing_url("http://other_phishing_url.com/bla");
   ExpectPreClassificationChecks(other_phishing_url, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse, &kFalse);
+                                &kFalse, &kFalse);
   // We navigate away.  The callback cb should be revoked.
   NavigateAndCommit(other_phishing_url);
   // Wait for the pre-classification checks to finish for other_phishing_url.
@@ -744,9 +682,7 @@
 TEST_F(ClientSideDetectionHostTest, PhishingDetectionDoneVerdictNotPhishing) {
   // Case 6: renderer sends a verdict string that isn't phishing.
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   ClientPhishingRequest verdict;
@@ -771,7 +707,7 @@
 
   // First we have to navigate to the URL to set the unique page ID.
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndCommit(url);
   WaitAndCheckPreClassificationChecks();
   SetUnsafeSubResourceForCurrent(true /* expect_unsafe_resource */);
@@ -797,7 +733,7 @@
   // Do an initial navigation to a safe host.
   GURL start_url("http://safe.example.com/");
   ExpectPreClassificationChecks(start_url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndCommit(start_url);
   WaitAndCheckPreClassificationChecks();
 
@@ -810,7 +746,7 @@
   verdict.set_is_phishing(false);
 
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateWithSBHitAndCommit(url);
   WaitAndCheckPreClassificationChecks();
 
@@ -826,7 +762,7 @@
   EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
 
   ExpectPreClassificationChecks(start_url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateWithoutSBHitAndCommit(start_url);
   WaitAndCheckPreClassificationChecks();
 }
@@ -840,7 +776,7 @@
   // Do an initial navigation to a safe host.
   GURL start_url("http://safe.example.com/");
   ExpectPreClassificationChecks(start_url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndCommit(start_url);
   WaitAndCheckPreClassificationChecks();
 
@@ -852,7 +788,7 @@
   verdict.set_is_phishing(false);
 
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateWithoutSBHitAndCommit(url);
 
   // Simulate a subresource malware hit on committed page.
@@ -896,129 +832,6 @@
   // was no DidNavigateMainFrame, CSD won't do anything with this hit.)
 }
 
-TEST_F(ClientSideDetectionHostTest,
-       DidStopLoadingShowMalwareInterstitial) {
-  // Case 9: client thinks the page match malware IP and so does the server.
-  // We show an sub-resource malware interstitial.
-  MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(
-          web_contents(),
-          csd_host_.get());
-  SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
-
-  GURL malware_landing_url("http://malware.com/");
-  GURL malware_ip_url("http://badip.com");
-  ClientMalwareRequest malware_verdict;
-  malware_verdict.set_url("http://malware.com/");
-  ClientMalwareRequest::UrlInfo* badipurl =
-      malware_verdict.add_bad_ip_url_info();
-  badipurl->set_ip("1.2.3.4");
-  badipurl->set_url("http://badip.com");
-
-  ExpectPreClassificationChecks(GURL(malware_verdict.url()), &kFalse, &kFalse,
-                                &kFalse, &kFalse, &kFalse, &kFalse);
-  NavigateAndKeepLoading(web_contents(), GURL(malware_verdict.url()));
-  WaitAndCheckPreClassificationChecks();
-
-  ClientSideDetectionService::ClientReportMalwareRequestCallback cb;
-  EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
-      .WillOnce(Invoke(
-          [&](BrowseInfo* info, std::unique_ptr<ClientMalwareRequest> request,
-              BrowserFeatureExtractor::MalwareDoneCallback callback) {
-            request->CopyFrom(malware_verdict);
-            std::move(callback).Run(true, std::move(request));
-          }));
-  EXPECT_CALL(*csd_service_,
-              SendClientReportMalwareRequest(
-                  Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _))
-      .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb)));
-  DidStopLoading();
-  EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
-  EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
-  ASSERT_FALSE(cb.is_null());
-
-  UnsafeResource resource;
-  EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_))
-      .WillOnce(SaveArg<0>(&resource));
-  cb.Run(malware_landing_url, malware_ip_url, true);
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get()));
-  EXPECT_EQ(malware_ip_url, resource.url);
-  EXPECT_EQ(malware_landing_url, resource.original_url);
-  EXPECT_TRUE(resource.is_subresource);
-  EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE, resource.threat_type);
-  EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source);
-  EXPECT_EQ(web_contents(), resource.web_contents_getter.Run());
-
-  // Make sure the client object will be deleted.
-  base::PostTask(
-      FROM_HERE, {BrowserThread::IO},
-      base::BindOnce(&MockSafeBrowsingUIManager::InvokeOnBlockingPageComplete,
-                     ui_manager_, resource.callback));
-}
-
-TEST_F(ClientSideDetectionHostTest, UpdateIPUrlMap) {
-  BrowseInfo* browse_info = GetBrowseInfo();
-
-  // Empty IP or host are skipped
-  UpdateIPUrlMap("250.10.10.10", std::string());
-  ASSERT_EQ(0U, browse_info->ips.size());
-  UpdateIPUrlMap(std::string(), "http://google.com/a");
-  ASSERT_EQ(0U, browse_info->ips.size());
-  UpdateIPUrlMap(std::string(), std::string());
-  ASSERT_EQ(0U, browse_info->ips.size());
-
-  std::vector<IPUrlInfo> expected_urls;
-  for (int i = 0; i < 20; i++) {
-    std::string url = base::StringPrintf("http://%d.com/", i);
-    expected_urls.push_back(
-        IPUrlInfo(url, "", "", content::ResourceType::kObject));
-    UpdateIPUrlMap("250.10.10.10", url);
-  }
-  ASSERT_EQ(1U, browse_info->ips.size());
-  ASSERT_EQ(20U, browse_info->ips["250.10.10.10"].size());
-  CheckIPUrlEqual(expected_urls,
-                  browse_info->ips["250.10.10.10"]);
-
-  // Add more urls for this ip, it exceeds max limit and won't be added
-  UpdateIPUrlMap("250.10.10.10", "http://21.com/");
-  ASSERT_EQ(1U, browse_info->ips.size());
-  ASSERT_EQ(20U, browse_info->ips["250.10.10.10"].size());
-  CheckIPUrlEqual(expected_urls,
-                  browse_info->ips["250.10.10.10"]);
-
-  // Add 199 more IPs
-  for (int i = 0; i < 199; i++) {
-    std::string ip = base::StringPrintf("%d.%d.%d.256", i, i, i);
-    expected_urls.clear();
-    expected_urls.push_back(
-        IPUrlInfo("test.com/", "", "", content::ResourceType::kObject));
-    UpdateIPUrlMap(ip, "test.com/");
-    ASSERT_EQ(1U, browse_info->ips[ip].size());
-    CheckIPUrlEqual(expected_urls,
-                    browse_info->ips[ip]);
-  }
-  ASSERT_EQ(200U, browse_info->ips.size());
-
-  // Exceeding max ip limit 200, these won't be added
-  UpdateIPUrlMap("250.250.250.250", "goo.com/");
-  UpdateIPUrlMap("250.250.250.250", "bar.com/");
-  UpdateIPUrlMap("250.250.0.250", "foo.com/");
-  ASSERT_EQ(200U, browse_info->ips.size());
-
-  // Add url to existing IPs succeed
-  UpdateIPUrlMap("100.100.100.256", "more.com/");
-  ASSERT_EQ(2U, browse_info->ips["100.100.100.256"].size());
-  expected_urls.clear();
-  expected_urls.push_back(
-      IPUrlInfo("test.com/", "", "", content::ResourceType::kObject));
-  expected_urls.push_back(
-      IPUrlInfo("more.com/", "", "", content::ResourceType::kObject));
-  CheckIPUrlEqual(expected_urls,
-                  browse_info->ips["100.100.100.256"]);
-}
-
 // This test doesn't work because it makes assumption about how
 // the message loop is run, and those assumptions are wrong when properly
 // simulating a navigation with browser-side navigations.
@@ -1036,10 +849,10 @@
   EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_))
       .WillOnce(Return(false))
       .WillOnce(Return(false));
-  ExpectPreClassificationChecks(first_url, NULL, &kFalse, NULL, NULL, NULL,
-                                NULL);
-  ExpectPreClassificationChecks(second_url, NULL, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+  ExpectPreClassificationChecks(first_url, nullptr, &kFalse, nullptr, nullptr,
+                                nullptr);
+  ExpectPreClassificationChecks(second_url, nullptr, &kFalse, &kFalse, &kFalse,
+                                &kFalse);
 
   NavigateAndCommit(first_url);
   // Don't flush the message loop, as we want to navigate to a different
@@ -1052,35 +865,33 @@
   // Navigate the tab to a page.  We should see a StartPhishingDetection IPC.
   GURL url("http://host.com/");
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(true);
 }
 
 TEST_F(ClientSideDetectionHostTest,
        TestPreClassificationCheckSameDocumentNavigation) {
   GURL url("http://host.com/");
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url);
   fake_phishing_detector_.Reset();
-  ExpectShouldClassifyForMalwareResult(true);
 
   // Now try an same-document navigation.  This should not trigger an IPC.
   EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_)).Times(0);
   GURL inpage("http://host.com/#foo");
-  ExpectPreClassificationChecks(inpage, NULL, NULL, NULL, NULL, NULL, NULL);
+  ExpectPreClassificationChecks(inpage, nullptr, nullptr, nullptr, nullptr,
+                                nullptr);
   NavigateAndKeepLoading(web_contents(), inpage);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(true);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckXHTML) {
@@ -1091,28 +902,26 @@
   navigation->SetContentsMimeType("application/xhtml+xml");
   navigation->SetKeepLoading(true);
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   navigation->Commit();
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(true);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckTwoNavigations) {
   // Navigate to two hosts, which should cause two IPCs.
   GURL url1("http://host1.com/");
   ExpectPreClassificationChecks(url1, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndKeepLoading(web_contents(), url1);
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url1);
-  ExpectShouldClassifyForMalwareResult(true);
 
   GURL url2("http://host2.com/");
   ExpectPreClassificationChecks(url2, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndKeepLoading(web_contents(), url2);
   // Re-override the binder for PhishingDetector because navigation causes
   // a new web InterfaceProvider to be created
@@ -1120,40 +929,18 @@
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url2);
-  ExpectShouldClassifyForMalwareResult(true);
-}
-
-TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckMimeType) {
-  // If the mime type is not one that we support, no IPC should be triggered
-  // but all pre-classification checks should run because we might classify
-  // other mime types for malware.
-  // Note: for this test to work correctly, the new URL must be on the
-  // same domain as the previous URL, otherwise it will create a new
-  // RenderFrameHost that won't have the mime type set.
-  GURL url("http://host2.com/image.jpg");
-  auto navigation =
-      content::NavigationSimulator::CreateBrowserInitiated(url, web_contents());
-  navigation->SetContentsMimeType("image/jpeg");
-  navigation->SetKeepLoading(true);
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
-  navigation->Commit();
-  WaitAndCheckPreClassificationChecks();
-
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(true);
 }
 
 TEST_F(ClientSideDetectionHostTest,
        TestPreClassificationCheckPrivateIpAddress) {
   // If IsPrivateIPAddress returns true, no IPC should be triggered.
   GURL url("http://host3.com/");
-  ExpectPreClassificationChecks(url, &kTrue, NULL, NULL, NULL, NULL, NULL);
+  ExpectPreClassificationChecks(url, &kTrue, nullptr, nullptr, nullptr,
+                                nullptr);
   NavigateAndCommit(url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(false);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostIncognitoTest,
@@ -1161,53 +948,26 @@
   // If the tab is incognito there should be no IPC.  Also, we shouldn't
   // even check the csd-whitelist.
   GURL url("http://host4.com/");
-  ExpectPreClassificationChecks(url, &kFalse, NULL, NULL, NULL, NULL, NULL);
+  ExpectPreClassificationChecks(url, &kFalse, nullptr, nullptr, nullptr,
+                                nullptr);
 
   content::WebContentsTester::For(web_contents())->NavigateAndCommit(url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(false);
-}
-
-TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckCsdWhitelist) {
-  // If the URL is on the csd whitelist no phishing IPC should be sent
-  // but we should classify the URL for malware.
-  GURL url("http://host5.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kTrue, &kFalse, &kFalse, &kFalse,
-                                &kFalse);
-  NavigateAndKeepLoading(web_contents(), url);
-  WaitAndCheckPreClassificationChecks();
-
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(true);
-}
-
-TEST_F(ClientSideDetectionHostTest,
-       TestPreClassificationCheckMalwareKillSwitch) {
-  // The malware killswitch should be ignored.
-  GURL url("http://host5.com/kill-switch");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
-  NavigateAndKeepLoading(web_contents(), url);
-  WaitAndCheckPreClassificationChecks();
-
-  fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(true);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckInvalidCache) {
   // If item is in the cache but it isn't valid, we will classify regardless
   // of whether we are over the reporting limit.
   GURL url("http://host6.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, NULL,
-                                &kFalse);
+  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue,
+                                nullptr);
 
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(true);
 }
 
 TEST_F(ClientSideDetectionHostTest,
@@ -1215,67 +975,51 @@
   // If the url isn't in the cache and we are over the reporting limit, we
   // don't do classification.
   GURL url("http://host7.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, &kTrue,
-                                &kFalse);
-  NavigateAndKeepLoading(web_contents(), url);
-  WaitAndCheckPreClassificationChecks();
-
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(true);
-}
-
-TEST_F(ClientSideDetectionHostTest,
-       TestPreClassificationCheckOverMalwareReportingLimit) {
-  GURL url("http://host.com/");
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kTrue);
+                                &kTrue);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(false);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest,
        TestPreClassificationCheckOverBothReportingLimits) {
   GURL url("http://host.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, &kTrue,
+  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
                                 &kTrue);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(false);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckHttpsUrl) {
   GURL url("https://host.com/");
   ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+                                &kFalse);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
   fake_phishing_detector_.CheckMessage(&url);
-  ExpectShouldClassifyForMalwareResult(true);
 }
 
 TEST_F(ClientSideDetectionHostTest,
        TestPreClassificationCheckNoneHttpOrHttpsUrl) {
   GURL url("file://host.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
-                                &kFalse, &kFalse);
+  ExpectPreClassificationChecks(url, &kFalse, nullptr, nullptr, nullptr,
+                                nullptr);
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(true);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckValidCached) {
   // If result is cached, we will try and display the blocking page directly
   // with no start classification message.
   GURL url("http://host8.com/");
-  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kTrue, &kFalse, &kFalse,
+  ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kTrue, &kFalse,
                                 &kFalse);
 
   UnsafeResource resource;
@@ -1287,10 +1031,7 @@
   EXPECT_EQ(url, resource.url);
   EXPECT_EQ(url, resource.original_url);
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  // Showing a phishing warning will invalidate all the weak pointers which
-  // means we will not extract malware features.
-  ExpectShouldClassifyForMalwareResult(false);
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, TestPreClassificationWhitelistedByPolicy) {
@@ -1300,35 +1041,18 @@
   update->AppendString("example.com");
 
   GURL url("http://example.com/");
-  ExpectPreClassificationChecks(url, &kFalse, NULL, NULL, NULL, NULL, NULL);
+  ExpectPreClassificationChecks(url, &kFalse, nullptr, nullptr, nullptr,
+                                nullptr);
 
   NavigateAndKeepLoading(web_contents(), url);
   WaitAndCheckPreClassificationChecks();
 
-  fake_phishing_detector_.CheckMessage(NULL);
-  ExpectShouldClassifyForMalwareResult(false);
-}
-
-TEST_F(ClientSideDetectionHostTest,
-       SubresourceResponseStartedSkipsMissingIPAddress) {
-  auto resource_load_info = content::mojom::ResourceLoadInfo::New();
-  resource_load_info->original_url = GURL("http://host1.com");
-  resource_load_info->origin_of_final_url =
-      url::Origin::Create(resource_load_info->original_url);
-  resource_load_info->referrer = GURL("http://host2.com");
-  resource_load_info->method = "GET";
-  resource_load_info->resource_type = content::ResourceType::kSubFrame;
-  csd_host_->ResourceLoadComplete(/*render_frame_host=*/nullptr,
-                                  content::GlobalRequestID(),
-                                  *resource_load_info);
-
-  EXPECT_EQ(0u, GetBrowseInfo()->ips.size());
+  fake_phishing_detector_.CheckMessage(nullptr);
 }
 
 TEST_F(ClientSideDetectionHostTest, RecordsPhishingDetectorResults) {
   MockBrowserFeatureExtractor* mock_extractor =
-      new StrictMock<MockBrowserFeatureExtractor>(web_contents(),
-                                                  csd_host_.get());
+      new StrictMock<MockBrowserFeatureExtractor>(web_contents());
   SetFeatureExtractor(mock_extractor);  // The host class takes ownership.
 
   {
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.cc b/chrome/browser/safe_browsing/client_side_detection_service.cc
index 3a25c639..14d5a42f 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_service.cc
@@ -49,26 +49,6 @@
 
 namespace safe_browsing {
 
-namespace {
-
-// malware report type for UMA histogram counting.
-enum MalwareReportTypes {
-  REPORT_SENT,
-  REPORT_HIT_LIMIT,
-  REPORT_FAILED_SERIALIZATION,
-
-  // Always at the end
-  REPORT_RESULT_MAX
-};
-
-void UpdateEnumUMAHistogram(MalwareReportTypes report_type) {
-  DCHECK(report_type >= 0 && report_type < REPORT_RESULT_MAX);
-  UMA_HISTOGRAM_ENUMERATION("SBClientMalware.SentReports", report_type,
-                            REPORT_RESULT_MAX);
-}
-
-}  // namespace
-
 const int ClientSideDetectionService::kInitialClientModelFetchDelayMs = 10000;
 const int ClientSideDetectionService::kReportsIntervalDays = 1;
 const int ClientSideDetectionService::kMaxReportsPerInterval = 3;
@@ -77,8 +57,6 @@
 
 const char ClientSideDetectionService::kClientReportPhishingUrl[] =
     "https://sb-ssl.google.com/safebrowsing/clientreport/phishing";
-const char ClientSideDetectionService::kClientReportMalwareUrl[] =
-    "https://sb-ssl.google.com/safebrowsing/clientreport/malware-check";
 
 struct ClientSideDetectionService::ClientPhishingReportInfo {
   std::unique_ptr<network::SimpleURLLoader> loader;
@@ -86,13 +64,6 @@
   GURL phishing_url;
 };
 
-struct ClientSideDetectionService::ClientMalwareReportInfo {
-  std::unique_ptr<network::SimpleURLLoader> loader;
-  ClientReportMalwareRequestCallback callback;
-  // This is the original landing url, may not be the malware url.
-  GURL original_url;
-};
-
 ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time)
     : is_phishing(phish), timestamp(time) {}
 
@@ -148,13 +119,6 @@
         info->callback.Run(info->phishing_url, false);
     }
     client_phishing_reports_.clear();
-    for (auto it = client_malware_reports_.begin();
-         it != client_malware_reports_.end(); ++it) {
-      ClientMalwareReportInfo* info = it->second.get();
-      if (!info->callback.is_null())
-        info->callback.Run(info->original_url, info->original_url, false);
-    }
-    client_malware_reports_.clear();
     cache_.clear();
   }
 }
@@ -172,17 +136,6 @@
           callback));
 }
 
-void ClientSideDetectionService::SendClientReportMalwareRequest(
-    ClientMalwareRequest* verdict,
-    const ClientReportMalwareRequestCallback& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &ClientSideDetectionService::StartClientReportMalwareRequest,
-          weak_factory_.GetWeakPtr(), verdict, callback));
-}
-
 bool ClientSideDetectionService::IsPrivateIPAddress(
     const std::string& ip_address) const {
   net::IPAddress address;
@@ -204,15 +157,9 @@
   if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers)
     response_code = url_loader->ResponseInfo()->headers->response_code();
 
-  if (base::Contains(client_phishing_reports_, url_loader)) {
-    HandlePhishingVerdict(url_loader, url_loader->GetFinalURL(),
-                          url_loader->NetError(), response_code, data);
-  } else if (base::Contains(client_malware_reports_, url_loader)) {
-    HandleMalwareVerdict(url_loader, url_loader->GetFinalURL(),
-                         url_loader->NetError(), response_code, data);
-  } else {
-    NOTREACHED();
-  }
+  DCHECK(base::Contains(client_phishing_reports_, url_loader));
+  HandlePhishingVerdict(url_loader, url_loader->GetFinalURL(),
+                        url_loader->NetError(), response_code, data);
 }
 
 void ClientSideDetectionService::Observe(
@@ -361,89 +308,6 @@
   phishing_report_times_.push(base::Time::Now());
 }
 
-void ClientSideDetectionService::StartClientReportMalwareRequest(
-    ClientMalwareRequest* verdict,
-    const ClientReportMalwareRequestCallback& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  std::unique_ptr<ClientMalwareRequest> request(verdict);
-
-  if (!enabled_) {
-    if (!callback.is_null())
-      callback.Run(GURL(request->url()), GURL(request->url()), false);
-    return;
-  }
-
-  std::string request_data;
-  if (!request->SerializeToString(&request_data)) {
-    UpdateEnumUMAHistogram(REPORT_FAILED_SERIALIZATION);
-    DVLOG(1) << "Unable to serialize the CSD request. Proto file changed?";
-    if (!callback.is_null())
-      callback.Run(GURL(request->url()), GURL(request->url()), false);
-    return;
-  }
-
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation(
-          "safe_browsing_client_side_malware_detector", R"(
-          semantics {
-            sender: "Safe Browsing Client-Side Malware Detector"
-            description:
-              "If the client-side malware detector determines that a requested "
-              "page's IP is in the blacklisted malware IPs, it will send a "
-              "request to Safe Browsing to ask for a final verdict. If Safe "
-              "Browsing agrees the page is dangerous, Chrome will show a "
-              "full-page interstitial warning."
-            trigger:
-              "Whenever the IP of the page is in malware blacklist."
-            data:
-              "Top-level page URL without CGI parameters, its non-https "
-              "referrer, URLs of resources that match IP blacklist."
-            destination: GOOGLE_OWNED_SERVICE
-          }
-          policy {
-            cookies_allowed: YES
-            cookies_store: "Safe browsing cookie store"
-            setting:
-              "Users can enable or disable this feature by toggling 'Protect "
-              "you and your device from dangerous sites' in Chrome settings "
-              "under Privacy. This feature is enabled by default."
-            chrome_policy {
-              SafeBrowsingEnabled {
-                policy_options {mode: MANDATORY}
-                SafeBrowsingEnabled: false
-              }
-            }
-          })");
-  auto resource_request = std::make_unique<network::ResourceRequest>();
-  resource_request->url = GetClientReportUrl(kClientReportMalwareUrl);
-  resource_request->method = "POST";
-  resource_request->load_flags = net::LOAD_DISABLE_CACHE;
-  auto loader = network::SimpleURLLoader::Create(std::move(resource_request),
-                                                 traffic_annotation);
-  loader->AttachStringForUpload(request_data, "application/octet-stream");
-  loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      url_loader_factory_.get(),
-      base::BindOnce(&ClientSideDetectionService::OnURLLoaderComplete,
-                     base::Unretained(this), loader.get()));
-
-  // Remember which callback and URL correspond to the current fetcher object.
-  std::unique_ptr<ClientMalwareReportInfo> info(new ClientMalwareReportInfo);
-  auto* loader_ptr = loader.get();
-  info->loader = std::move(loader);
-  info->callback = callback;
-  info->original_url = GURL(request->url());
-  client_malware_reports_[loader_ptr] = std::move(info);
-
-  UMA_HISTOGRAM_ENUMERATION("SBClientMalware.SentReports", REPORT_SENT,
-                            REPORT_RESULT_MAX);
-
-  UMA_HISTOGRAM_COUNTS_1M("SBClientMalware.IPBlacklistRequestPayloadSize",
-                          request_data.size());
-
-  // Record that we made a malware request
-  malware_report_times_.push(base::Time::Now());
-}
-
 void ClientSideDetectionService::HandlePhishingVerdict(
     network::SimpleURLLoader* source,
     const GURL& url,
@@ -471,44 +335,6 @@
     info->callback.Run(info->phishing_url, is_phishing);
 }
 
-void ClientSideDetectionService::HandleMalwareVerdict(
-    network::SimpleURLLoader* source,
-    const GURL& url,
-    int net_error,
-    int response_code,
-    const std::string& data) {
-  if (net_error == net::OK) {
-    base::UmaHistogramSparse("SBClientMalware.IPBlacklistRequestResponseCode",
-                             response_code);
-  }
-  // status error is negative, so we put - in front of it.
-  base::UmaHistogramSparse("SBClientMalware.IPBlacklistRequestNetError",
-                           -net_error);
-
-  ClientMalwareResponse response;
-  std::unique_ptr<ClientMalwareReportInfo> info =
-      std::move(client_malware_reports_[source]);
-  client_malware_reports_.erase(source);
-
-  bool should_blacklist = false;
-  if (net_error == net::OK && net::HTTP_OK == response_code &&
-      response.ParseFromString(data)) {
-    should_blacklist = response.blacklist();
-  } else {
-    DLOG(ERROR) << "Unable to get the server verdict for URL: "
-                << info->original_url << " net_error: " << net_error << " "
-                << "response_code:" << response_code;
-  }
-
-  if (!info->callback.is_null()) {
-    if (response.has_bad_url())
-      info->callback.Run(info->original_url, GURL(response.bad_url()),
-                         should_blacklist);
-    else
-      info->callback.Run(info->original_url, info->original_url, false);
-  }
-}
-
 bool ClientSideDetectionService::IsInCache(const GURL& url) {
   UpdateCache();
 
@@ -566,18 +392,10 @@
   }
 }
 
-bool ClientSideDetectionService::OverMalwareReportLimit() {
-  return GetMalwareNumReports() > kMaxReportsPerInterval;
-}
-
 bool ClientSideDetectionService::OverPhishingReportLimit() {
   return GetPhishingNumReports() > kMaxReportsPerInterval;
 }
 
-int ClientSideDetectionService::GetMalwareNumReports() {
-  return GetNumReports(&malware_report_times_);
-}
-
 int ClientSideDetectionService::GetPhishingNumReports() {
   return GetNumReports(&phishing_report_times_);
 }
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.h b/chrome/browser/safe_browsing/client_side_detection_service.h
index 9f33e222..bae1b19 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service.h
+++ b/chrome/browser/safe_browsing/client_side_detection_service.h
@@ -43,7 +43,6 @@
 }  // namespace network
 
 namespace safe_browsing {
-class ClientMalwareRequest;
 class ClientPhishingRequest;
 
 // Main service which pushes models to the renderers, responds to classification
@@ -52,9 +51,6 @@
  public:
   // void(GURL phishing_url, bool is_phishing).
   typedef base::Callback<void(GURL, bool)> ClientReportPhishingRequestCallback;
-  // void(GURL original_url, GURL malware_url, bool is_malware).
-  typedef base::Callback<void(GURL, GURL, bool)>
-      ClientReportMalwareRequestCallback;
 
   ~ClientSideDetectionService() override;
 
@@ -101,11 +97,6 @@
       bool is_extended_reporting,
       const ClientReportPhishingRequestCallback& callback);
 
-  // Similar to above one, instead send ClientMalwareRequest
-  virtual void SendClientReportMalwareRequest(
-      ClientMalwareRequest* verdict,
-      const ClientReportMalwareRequestCallback& callback);
-
   // Returns true if the given IP address string falls within a private
   // (unroutable) network block.  Pages which are hosted on these IP addresses
   // are exempt from client-side phishing detection.  This is called by the
@@ -126,10 +117,6 @@
   // reports in the last kReportsInterval.
   virtual bool OverPhishingReportLimit();
 
-  // Returns true if we have sent more than kMaxReportsPerInterval malware
-  // reports in the last kReportsInterval.
-  virtual bool OverMalwareReportLimit();
-
   // Sends a model to each renderer.
   virtual void SendModelToRenderers();
 
@@ -154,7 +141,6 @@
     CacheState(bool phish, base::Time time);
   };
 
-  static const char kClientReportMalwareUrl[];
   static const char kClientReportPhishingUrl[];
   static const int kMaxReportsPerInterval;
   static const int kInitialClientModelFetchDelayMs;
@@ -169,10 +155,6 @@
       bool is_extended_reporting,
       const ClientReportPhishingRequestCallback& callback);
 
-  void StartClientReportMalwareRequest(
-      ClientMalwareRequest* verdict,
-      const ClientReportMalwareRequestCallback& callback);
-
   // Called by OnURLFetchComplete to handle the server response from
   // sending the client-side phishing request.
   void HandlePhishingVerdict(network::SimpleURLLoader* source,
@@ -181,20 +163,9 @@
                              int response_code,
                              const std::string& data);
 
-  // Called by OnURLFetchComplete to handle the server response from
-  // sending the client-side malware request.
-  void HandleMalwareVerdict(network::SimpleURLLoader* source,
-                            const GURL& url,
-                            int net_error,
-                            int response_code,
-                            const std::string& data);
-
   // Invalidate cache results which are no longer useful.
   void UpdateCache();
 
-  // Get the number of malware reports that we have sent over kReportsInterval.
-  int GetMalwareNumReports();
-
   // Get the number of phishing reports that we have sent over kReportsInterval.
   int GetPhishingNumReports();
 
@@ -223,12 +194,6 @@
   std::map<const network::SimpleURLLoader*,
            std::unique_ptr<ClientPhishingReportInfo>>
       client_phishing_reports_;
-  // Map of client malware ip request to the corresponding callback that
-  // has to be invoked when the request is done.
-  struct ClientMalwareReportInfo;
-  std::map<const network::SimpleURLLoader*,
-           std::unique_ptr<ClientMalwareReportInfo>>
-      client_malware_reports_;
 
   // Cache of completed requests. Used to satisfy requests for the same urls
   // as long as the next request falls within our caching window (which is
@@ -243,10 +208,6 @@
   // TODO(gcasto): Serialize this so that it doesn't reset on browser restart.
   base::queue<base::Time> phishing_report_times_;
 
-  // Timestamp of when we sent a malware request. Used to limit the number
-  // of malware requests that we send in a day.
-  base::queue<base::Time> malware_report_times_;
-
   // The URLLoaderFactory we use to issue network requests.
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
 
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc
index 2b583b75..82bf6e0 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc
@@ -97,19 +97,6 @@
     return is_phishing_;
   }
 
-  bool SendClientReportMalwareRequest(const GURL& url) {
-    std::unique_ptr<ClientMalwareRequest> request(new ClientMalwareRequest());
-    request->set_url(url.spec());
-    base::RunLoop run_loop;
-    csd_service_->SendClientReportMalwareRequest(
-        request.release(),
-        base::Bind(&ClientSideDetectionServiceTest::SendMalwareRequestDone,
-                   base::Unretained(this), run_loop.QuitWhenIdleClosure()));
-    phishing_url_ = url;
-    run_loop.Run();  // Waits until callback is called.
-    return is_malware_;
-  }
-
   void SetModelFetchResponses() {
     // Set reponses for both models.
     test_url_loader_factory_.AddResponse(
@@ -141,13 +128,6 @@
                 response_data, net_error);
   }
 
-  void SetClientReportMalwareResponse(const std::string& response_data,
-                                      int net_error) {
-    SetResponse(ClientSideDetectionService::GetClientReportUrl(
-                    ClientSideDetectionService::kClientReportMalwareUrl),
-                response_data, net_error);
-  }
-
   int GetNumReports(base::queue<base::Time>* report_times) {
     return csd_service_->GetNumReports(report_times);
   }
@@ -156,10 +136,6 @@
     return csd_service_->phishing_report_times_;
   }
 
-  base::queue<base::Time>& GetMalwareReportTimes() {
-    return csd_service_->malware_report_times_;
-  }
-
   void SetCache(const GURL& gurl, bool is_phishing, base::Time time) {
     csd_service_->cache_[gurl] =
         std::make_unique<ClientSideDetectionService::CacheState>(is_phishing,
@@ -233,10 +209,6 @@
     feature->set_value(value);
   }
 
-  void CheckConfirmedMalwareUrl(GURL url) {
-    ASSERT_EQ(confirmed_malware_url_, url);
-  }
-
  protected:
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<ClientSideDetectionService> csd_service_;
@@ -257,22 +229,10 @@
     std::move(continuation_callback).Run();
   }
 
-  void SendMalwareRequestDone(base::OnceClosure continuation_callback,
-                              GURL original_url,
-                              GURL malware_url,
-                              bool is_malware) {
-    ASSERT_EQ(phishing_url_, original_url);
-    confirmed_malware_url_ = malware_url;
-    is_malware_ = is_malware;
-    std::move(continuation_callback).Run();
-  }
-
   std::unique_ptr<base::FieldTrialList> field_trials_;
 
   GURL phishing_url_;
-  GURL confirmed_malware_url_;
   bool is_phishing_;
-  bool is_malware_;
 };
 
 
@@ -338,59 +298,6 @@
   EXPECT_FALSE(csd_service_->IsInCache(second_url));
 }
 
-TEST_F(ClientSideDetectionServiceTest, SendClientReportMalwareRequest) {
-  SetModelFetchResponses();
-  csd_service_ =
-      ClientSideDetectionService::Create(test_shared_loader_factory_);
-  csd_service_->SetEnabledAndRefreshState(true);
-  GURL url("http://a.com/");
-
-  base::Time before = base::Time::Now();
-  // Invalid response body from the server.
-  SetClientReportMalwareResponse("invalid proto response", net::OK);
-  EXPECT_FALSE(SendClientReportMalwareRequest(url));
-
-  // Missing bad_url.
-  ClientMalwareResponse response;
-  response.set_blacklist(true);
-  SetClientReportMalwareResponse(response.SerializeAsString(), net::OK);
-  EXPECT_FALSE(SendClientReportMalwareRequest(url));
-
-  // Normal behavior.
-  response.set_blacklist(true);
-  response.set_bad_url("http://response-bad.com/");
-  SetClientReportMalwareResponse(response.SerializeAsString(), net::OK);
-  EXPECT_TRUE(SendClientReportMalwareRequest(url));
-  CheckConfirmedMalwareUrl(GURL("http://response-bad.com/"));
-
-  // This request will fail
-  response.set_blacklist(false);
-  SetClientReportMalwareResponse(response.SerializeAsString(), net::ERR_FAILED);
-  EXPECT_FALSE(SendClientReportMalwareRequest(url));
-
-  // Server blacklist decision is false, and response is successful
-  response.set_blacklist(false);
-  SetClientReportMalwareResponse(response.SerializeAsString(), net::OK);
-  EXPECT_FALSE(SendClientReportMalwareRequest(url));
-
-  // Check that we have recorded all 5 requests within the correct time range.
-  base::Time after = base::Time::Now();
-  base::queue<base::Time>& report_times = GetMalwareReportTimes();
-  EXPECT_EQ(5U, report_times.size());
-
-  // Check that the malware report limit was reached.
-  EXPECT_TRUE(csd_service_->OverMalwareReportLimit());
-
-  report_times = GetMalwareReportTimes();
-  EXPECT_EQ(5U, report_times.size());
-  while (!report_times.empty()) {
-    base::Time time = report_times.back();
-    report_times.pop();
-    EXPECT_LE(before, time);
-    EXPECT_GE(after, time);
-  }
-}
-
 TEST_F(ClientSideDetectionServiceTest, GetNumReportTest) {
   SetModelFetchResponses();
   csd_service_ =
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 6ab0cf28..938fedf2 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -293,6 +293,8 @@
               IDS_NEW_TAB_VOICE_OTHER_ERROR);
     AddString(translated_strings.get(), "voiceCloseTooltip",
               IDS_NEW_TAB_VOICE_CLOSE_TOOLTIP);
+    AddString(translated_strings.get(), "voiceSearchClosed",
+              IDS_NEW_TAB_VOICE_SEARCH_CLOSED);
 
     // Realbox
     AddString(translated_strings.get(), "realboxSeparator",
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc
index 87886d9..09abf88 100644
--- a/chrome/browser/sessions/tab_restore_browsertest.cc
+++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -679,8 +679,10 @@
 }
 
 // https://crbug.com/825305: Timeout flakiness on Win7 Tests (dbg)(1) bot and
-// PASS/FAIL flakiness on Linux Chromium OS ASan LSan Tests (1) bot.
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(OS_WIN)
+// Mac10.13 Tests (dbg) and PASS/FAIL flakiness on Linux Chromium OS ASan LSan
+// Tests (1) bot.
+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
+    defined(OS_WIN) || (defined(OS_MAC) && !defined(NDEBUG))
 #define MAYBE_RestoreTabWithSpecialURL DISABLED_RestoreTabWithSpecialURL
 #else
 #define MAYBE_RestoreTabWithSpecialURL RestoreTabWithSpecialURL
@@ -711,9 +713,10 @@
 }
 
 // https://crbug.com/667932: Flakiness on linux_chromium_asan_rel_ng bot.
-// https://crbug.com/825305: Timeout flakiness on Win7 Tests (dbg)(1) bot.
+// https://crbug.com/825305: Timeout flakiness on Win7 Tests (dbg)(1) and
+// Mac10.13 Tests (dbg) bots.
 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    (defined(OS_WIN) && !defined(NDEBUG))
+    ((defined(OS_WIN) || defined(OS_MAC)) && !defined(NDEBUG))
 #define MAYBE_RestoreTabWithSpecialURLOnBack DISABLED_RestoreTabWithSpecialURLOnBack
 #else
 #define MAYBE_RestoreTabWithSpecialURLOnBack RestoreTabWithSpecialURLOnBack
diff --git a/chrome/browser/sharing/ack_message_handler.cc b/chrome/browser/sharing/ack_message_handler.cc
index 288b79b..5224123 100644
--- a/chrome/browser/sharing/ack_message_handler.cc
+++ b/chrome/browser/sharing/ack_message_handler.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/sharing/ack_message_handler.h"
 
 #include "base/memory/ptr_util.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_message_sender.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 
 AckMessageHandler::AckMessageHandler(
     SharingMessageSender* sharing_message_sender)
diff --git a/chrome/browser/sharing/ack_message_handler_unittest.cc b/chrome/browser/sharing/ack_message_handler_unittest.cc
index 11ba484..eb955b41 100644
--- a/chrome/browser/sharing/ack_message_handler_unittest.cc
+++ b/chrome/browser/sharing/ack_message_handler_unittest.cc
@@ -7,9 +7,9 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/test/mock_callback.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_fcm_sender.h"
 #include "chrome/browser/sharing/sharing_message_sender.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_message_handler_android.cc b/chrome/browser/sharing/click_to_call/click_to_call_message_handler_android.cc
index ac979d8..9a94784 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_message_handler_android.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_message_handler_android.cc
@@ -7,8 +7,8 @@
 #include "base/android/jni_string.h"
 #include "base/logging.h"
 #include "chrome/android/chrome_jni_headers/ClickToCallMessageHandler_jni.h"
-#include "components/sync/protocol/sharing_click_to_call_message.pb.h"
-#include "components/sync/protocol/sharing_message.pb.h"
+#include "chrome/browser/sharing/proto/click_to_call_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 
 ClickToCallMessageHandler::ClickToCallMessageHandler() = default;
 
diff --git a/chrome/browser/sharing/ping_message_handler.cc b/chrome/browser/sharing/ping_message_handler.cc
index 047a6a5..a5b2eb1 100644
--- a/chrome/browser/sharing/ping_message_handler.cc
+++ b/chrome/browser/sharing/ping_message_handler.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/sharing/ping_message_handler.h"
 
-#include "components/sync/protocol/sharing_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 
 PingMessageHandler::PingMessageHandler() = default;
 
diff --git a/chrome/browser/sharing/proto/BUILD.gn b/chrome/browser/sharing/proto/BUILD.gn
new file mode 100644
index 0000000..67a6d2dc
--- /dev/null
+++ b/chrome/browser/sharing/proto/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import("//third_party/protobuf/proto_library.gni")
+group("proto_lite") {
+  public_deps = [
+    ":proto",
+    "//third_party/protobuf:protobuf_lite",
+  ]
+}
+proto_library("proto") {
+  sources = [
+    "click_to_call_message.proto",
+    "peer_connection_messages.proto",
+    "remote_copy_message.proto",
+    "shared_clipboard_message.proto",
+    "sharing_message.proto",
+    "sms_fetch_message.proto",
+  ]
+}
diff --git a/components/sync/protocol/sharing_click_to_call_message.proto b/chrome/browser/sharing/proto/click_to_call_message.proto
similarity index 86%
rename from components/sync/protocol/sharing_click_to_call_message.proto
rename to chrome/browser/sharing/proto/click_to_call_message.proto
index 3ba74d02c..eeb92d5 100644
--- a/components/sync/protocol/sharing_click_to_call_message.proto
+++ b/chrome/browser/sharing/proto/click_to_call_message.proto
@@ -5,7 +5,7 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 package chrome_browser_sharing;
 
diff --git a/components/sync/protocol/sharing_peer_connection_messages.proto b/chrome/browser/sharing/proto/peer_connection_messages.proto
similarity index 91%
rename from components/sync/protocol/sharing_peer_connection_messages.proto
rename to chrome/browser/sharing/proto/peer_connection_messages.proto
index f87f2de..fd5ba17d 100644
--- a/components/sync/protocol/sharing_peer_connection_messages.proto
+++ b/chrome/browser/sharing/proto/peer_connection_messages.proto
@@ -5,7 +5,7 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 package chrome_browser_sharing;
 
diff --git a/components/sync/protocol/sharing_remote_copy_message.proto b/chrome/browser/sharing/proto/remote_copy_message.proto
similarity index 89%
rename from components/sync/protocol/sharing_remote_copy_message.proto
rename to chrome/browser/sharing/proto/remote_copy_message.proto
index 4a518c2c..428dc5c 100644
--- a/components/sync/protocol/sharing_remote_copy_message.proto
+++ b/chrome/browser/sharing/proto/remote_copy_message.proto
@@ -5,7 +5,7 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 package chrome_browser_sharing;
 
diff --git a/components/sync/protocol/sharing_shared_clipboard_message.proto b/chrome/browser/sharing/proto/shared_clipboard_message.proto
similarity index 86%
rename from components/sync/protocol/sharing_shared_clipboard_message.proto
rename to chrome/browser/sharing/proto/shared_clipboard_message.proto
index 91a72c6..1dbf67d5 100644
--- a/components/sync/protocol/sharing_shared_clipboard_message.proto
+++ b/chrome/browser/sharing/proto/shared_clipboard_message.proto
@@ -5,7 +5,7 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 package chrome_browser_sharing;
 
diff --git a/components/sync/protocol/sharing_message.proto b/chrome/browser/sharing/proto/sharing_message.proto
similarity index 89%
rename from components/sync/protocol/sharing_message.proto
rename to chrome/browser/sharing/proto/sharing_message.proto
index bd6af3f7..d1c57271 100644
--- a/components/sync/protocol/sharing_message.proto
+++ b/chrome/browser/sharing/proto/sharing_message.proto
@@ -5,13 +5,13 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
-import "sharing_click_to_call_message.proto";
-import "sharing_peer_connection_messages.proto";
-import "sharing_remote_copy_message.proto";
-import "sharing_shared_clipboard_message.proto";
-import "sharing_sms_fetch_message.proto";
+import "click_to_call_message.proto";
+import "peer_connection_messages.proto";
+import "remote_copy_message.proto";
+import "shared_clipboard_message.proto";
+import "sms_fetch_message.proto";
 
 package chrome_browser_sharing;
 
diff --git a/components/sync/protocol/sharing_sms_fetch_message.proto b/chrome/browser/sharing/proto/sms_fetch_message.proto
similarity index 91%
rename from components/sync/protocol/sharing_sms_fetch_message.proto
rename to chrome/browser/sharing/proto/sms_fetch_message.proto
index cc25d9f1..3e5805a 100644
--- a/components/sync/protocol/sharing_sms_fetch_message.proto
+++ b/chrome/browser/sharing/proto/sms_fetch_message.proto
@@ -5,7 +5,7 @@
 syntax = "proto3";
 
 option java_multiple_files = true;
-option java_package = "org.chromium.components.sync.protocol";
+option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 package chrome_browser_sharing;
 
diff --git a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc
index 632da8ec..6036e32f 100644
--- a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc
+++ b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc
@@ -18,11 +18,11 @@
 #include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/browser/notifications/notification_display_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sharing/proto/remote_copy_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/shared_clipboard/feature_flags.h"
 #include "chrome/browser/sharing/sharing_metrics.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/sync/protocol/sharing_message.pb.h"
-#include "components/sync/protocol/sharing_remote_copy_message.pb.h"
 #include "net/base/load_flags.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
diff --git a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc
index e050526..593a924 100644
--- a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc
+++ b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc
@@ -9,13 +9,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/sharing/proto/remote_copy_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/shared_clipboard/feature_flags.h"
 #include "chrome/browser/sharing/shared_clipboard/remote_copy_handle_message_result.h"
 #include "chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile.h"
-#include "components/sync/protocol/sharing_message.pb.h"
-#include "components/sync/protocol/sharing_remote_copy_message.pb.h"
 #include "components/sync/protocol/sync_enums.pb.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/message_center/public/cpp/notification.h"
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler.cc
index 3b1b3b4..8ba36ba 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler.cc
@@ -8,9 +8,9 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/sharing/proto/shared_clipboard_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_device_source.h"
-#include "components/sync/protocol/sharing_message.pb.h"
-#include "components/sync/protocol/sharing_shared_clipboard_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "ui/base/clipboard/clipboard_buffer.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler_desktop_unittest.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler_desktop_unittest.cc
index f9235527..390fbc4 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler_desktop_unittest.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_message_handler_desktop_unittest.cc
@@ -8,11 +8,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/mock_callback.h"
 #include "chrome/browser/sharing/mock_sharing_service.h"
+#include "chrome/browser/sharing/proto/shared_clipboard_message.pb.h"
 #include "chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.h"
 #include "chrome/browser/sharing/sharing_device_source.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile.h"
-#include "components/sync/protocol/sharing_shared_clipboard_message.pb.h"
 #include "components/sync/protocol/sync_enums.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.cc
index 3829870b..a550da9a 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_test_base.cc
@@ -7,7 +7,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/browser/sharing/mock_sharing_service.h"
-#include "components/sync/protocol/sharing_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/clipboard/clipboard.h"
diff --git a/chrome/browser/sharing/sharing_fcm_handler.h b/chrome/browser/sharing/sharing_fcm_handler.h
index 34e593c..e4d359f 100644
--- a/chrome/browser/sharing/sharing_fcm_handler.h
+++ b/chrome/browser/sharing/sharing_fcm_handler.h
@@ -12,9 +12,9 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_send_message_result.h"
 #include "components/gcm_driver/gcm_app_handler.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 
 namespace gcm {
diff --git a/chrome/browser/sharing/sharing_fcm_sender.h b/chrome/browser/sharing/sharing_fcm_sender.h
index 968de8a..b9729d0b 100644
--- a/chrome/browser/sharing/sharing_fcm_sender.h
+++ b/chrome/browser/sharing/sharing_fcm_sender.h
@@ -14,9 +14,9 @@
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_send_message_result.h"
 #include "components/gcm_driver/web_push_common.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 
 namespace gcm {
diff --git a/chrome/browser/sharing/sharing_handler_registry.h b/chrome/browser/sharing/sharing_handler_registry.h
index 0ee7467..033139b 100644
--- a/chrome/browser/sharing/sharing_handler_registry.h
+++ b/chrome/browser/sharing/sharing_handler_registry.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_SHARING_SHARING_HANDLER_REGISTRY_H_
 #define CHROME_BROWSER_SHARING_SHARING_HANDLER_REGISTRY_H_
 
-#include "components/sync/protocol/sharing_message.pb.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 
 class SharingMessageHandler;
 
diff --git a/chrome/browser/sharing/sharing_metrics.h b/chrome/browser/sharing/sharing_metrics.h
index dffaa908..97a98b349 100644
--- a/chrome/browser/sharing/sharing_metrics.h
+++ b/chrome/browser/sharing/sharing_metrics.h
@@ -6,10 +6,10 @@
 #define CHROME_BROWSER_SHARING_SHARING_METRICS_H_
 
 #include "base/time/time.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/shared_clipboard/remote_copy_handle_message_result.h"
 #include "chrome/browser/sharing/sharing_constants.h"
 #include "chrome/browser/sharing/sharing_send_message_result.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 
 enum class SharingDeviceRegistrationResult;
 
diff --git a/chrome/browser/sharing/sharing_service.h b/chrome/browser/sharing/sharing_service.h
index 72a9828..7c5faf5 100644
--- a/chrome/browser/sharing/sharing_service.h
+++ b/chrome/browser/sharing/sharing_service.h
@@ -13,6 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_device_registration.h"
 #include "chrome/browser/sharing/sharing_message_sender.h"
 #include "chrome/browser/sharing/sharing_send_message_result.h"
@@ -20,7 +21,6 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/sync/driver/sync_service_observer.h"
 #include "components/sync/protocol/device_info_specifics.pb.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "net/base/backoff_entry.h"
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/sharing/sharing_service_unittest.cc b/chrome/browser/sharing/sharing_service_unittest.cc
index a85f529..8895750 100644
--- a/chrome/browser/sharing/sharing_service_unittest.cc
+++ b/chrome/browser/sharing/sharing_service_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/test/task_environment.h"
 #include "chrome/browser/sharing/fake_device_info.h"
 #include "chrome/browser/sharing/features.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_constants.h"
 #include "chrome/browser/sharing/sharing_device_registration.h"
 #include "chrome/browser/sharing/sharing_device_registration_result.h"
@@ -26,7 +27,6 @@
 #include "components/gcm_driver/crypto/gcm_encryption_provider.h"
 #include "components/gcm_driver/instance_id/instance_id_driver.h"
 #include "components/sync/driver/test_sync_service.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "components/sync_device_info/fake_device_info_sync_service.h"
 #include "components/sync_device_info/local_device_info_provider.h"
diff --git a/chrome/browser/sharing/sharing_ui_controller.h b/chrome/browser/sharing/sharing_ui_controller.h
index 38635c5..7f03554 100644
--- a/chrome/browser/sharing/sharing_ui_controller.h
+++ b/chrome/browser/sharing/sharing_ui_controller.h
@@ -14,6 +14,7 @@
 #include "base/optional.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_app.h"
 #include "chrome/browser/sharing/sharing_constants.h"
 #include "chrome/browser/sharing/sharing_dialog_data.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/sharing/sharing_service.h"
 #include "chrome/browser/ui/page_action/page_action_icon_type.h"
 #include "components/sync/protocol/device_info_specifics.pb.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/controls/styled_label_listener.h"
diff --git a/chrome/browser/sharing/sms/sms_fetch_request_handler.cc b/chrome/browser/sharing/sms/sms_fetch_request_handler.cc
index 43f3ecf..b0f3d0c 100644
--- a/chrome/browser/sharing/sms/sms_fetch_request_handler.cc
+++ b/chrome/browser/sharing/sms/sms_fetch_request_handler.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/sharing/sms/sms_fetch_request_handler.h"
 
 #include "base/logging.h"
-#include "components/sync/protocol/sharing_sms_fetch_message.pb.h"
+#include "chrome/browser/sharing/proto/sms_fetch_message.pb.h"
 #include "content/public/browser/sms_fetcher.h"
 #include "url/gurl.h"
 #include "url/origin.h"
diff --git a/chrome/browser/sharing/sms/sms_fetch_request_handler.h b/chrome/browser/sharing/sms/sms_fetch_request_handler.h
index 170c555..99658ad 100644
--- a/chrome/browser/sharing/sms/sms_fetch_request_handler.h
+++ b/chrome/browser/sharing/sms/sms_fetch_request_handler.h
@@ -9,8 +9,8 @@
 #include "base/containers/flat_set.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/macros.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_message_handler.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "content/public/browser/sms_fetcher.h"
 #include "url/origin.h"
 
diff --git a/chrome/browser/sharing/sms/sms_fetch_request_handler_unittest.cc b/chrome/browser/sharing/sms/sms_fetch_request_handler_unittest.cc
index 1193be2..5d39beb0 100644
--- a/chrome/browser/sharing/sms/sms_fetch_request_handler_unittest.cc
+++ b/chrome/browser/sharing/sms/sms_fetch_request_handler_unittest.cc
@@ -6,8 +6,8 @@
 
 #include "base/run_loop.h"
 #include "base/test/bind_test_util.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_message_handler.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "content/public/browser/sms_fetcher.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/sharing/sms/sms_remote_fetcher_unittest.cc b/chrome/browser/sharing/sms/sms_remote_fetcher_unittest.cc
index 35630341..18c1ff2c 100644
--- a/chrome/browser/sharing/sms/sms_remote_fetcher_unittest.cc
+++ b/chrome/browser/sharing/sms/sms_remote_fetcher_unittest.cc
@@ -8,11 +8,11 @@
 #include "base/test/bind_test_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/sharing/mock_sharing_service.h"
+#include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_service.h"
 #include "chrome/browser/sharing/sharing_service_factory.h"
 #include "chrome/browser/sharing/sms/sms_flags.h"
 #include "chrome/test/base/testing_profile.h"
-#include "components/sync/protocol/sharing_message.pb.h"
 #include "components/sync_device_info/device_info.h"
 #include "content/public/browser/sms_fetcher.h"
 #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/signin/signin_promo.cc b/chrome/browser/signin/signin_promo.cc
index 17af026c..4fc33a0b 100644
--- a/chrome/browser/signin/signin_promo.cc
+++ b/chrome/browser/signin/signin_promo.cc
@@ -17,6 +17,8 @@
 #include "components/google/core/common/google_util.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_context.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/base/url_util.h"
 #include "url/gurl.h"
@@ -89,8 +91,13 @@
   return url;
 }
 
-GURL GetSigninPartitionURL() {
-  return GURL("chrome-guest://chrome-signin/?");
+content::StoragePartition* GetSigninPartition(
+    content::BrowserContext* browser_context) {
+  const GURL signin_site_url =
+      extensions::WebViewGuest::GetSiteForGuestPartitionConfig(
+          "chrome-signin", /* partition_name= */ "", /* in_memory= */ true);
+  return content::BrowserContext::GetStoragePartitionForSite(browser_context,
+                                                             signin_site_url);
 }
 
 signin_metrics::AccessPoint GetAccessPointForEmbeddedPromoURL(const GURL& url) {
diff --git a/chrome/browser/signin/signin_promo.h b/chrome/browser/signin/signin_promo.h
index d8e7a46..d054e965 100644
--- a/chrome/browser/signin/signin_promo.h
+++ b/chrome/browser/signin/signin_promo.h
@@ -12,6 +12,11 @@
 
 class GURL;
 
+namespace content {
+class BrowserContext;
+class StoragePartition;
+}  // namespace content
+
 namespace user_prefs {
 class PrefRegistrySyncable;
 }
@@ -58,8 +63,9 @@
 GURL GetAddAccountURLForDice(const std::string& email,
                              const std::string& continue_url);
 
-// Gets the partition URL for the embedded sign in frame/webview.
-GURL GetSigninPartitionURL();
+// Gets the partition for the embedded sign in frame/webview.
+content::StoragePartition* GetSigninPartition(
+    content::BrowserContext* browser_context);
 
 // Gets the access point from the query portion of the sign in promo URL.
 signin_metrics::AccessPoint GetAccessPointForEmbeddedPromoURL(const GURL& url);
diff --git a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
index 2c9bf9fe..c7c016c8 100644
--- a/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
+++ b/chrome/browser/subresource_filter/ad_tagging_browsertest.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
 #include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h"
 #include "components/subresource_filter/core/common/test_ruleset_utils.h"
@@ -403,7 +403,7 @@
     // here to unblock that, so as to be able to test that the UseCounter not
     // being recorded was due to the filtering in our recording function, rather
     // than the default popup blocking.
-    command_line->AppendSwitch(::switches::kDisablePopupBlocking);
+    command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
   }
 };
 
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 55477d7..62df7846 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -409,10 +409,11 @@
       !chromeos::switches::IsTabletFormFactor()) {
     if (chromeos::features::IsSplitSettingsSyncEnabled()) {
       // Runs in sync transport-mode and full-sync mode.
-      controllers.push_back(OsSyncableServiceModelTypeController::Create(
-          syncer::APP_LIST, model_type_store_factory,
-          GetSyncableServiceForType(syncer::APP_LIST), dump_stack,
-          profile_->GetPrefs(), sync_service));
+      controllers.push_back(
+          std::make_unique<OsSyncableServiceModelTypeController>(
+              syncer::APP_LIST, model_type_store_factory,
+              GetSyncableServiceForType(syncer::APP_LIST), dump_stack,
+              profile_->GetPrefs(), sync_service));
     } else {
       // Only runs in full-sync mode.
       controllers.push_back(
@@ -436,23 +437,25 @@
 #if defined(OS_CHROMEOS)
   if (arc::IsArcAllowedForProfile(profile_) &&
       !arc::IsArcAppSyncFlowDisabled()) {
-    controllers.push_back(ArcPackageSyncModelTypeController::Create(
+    controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>(
         model_type_store_factory,
         GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack,
         sync_service, profile_));
   }
   if (chromeos::features::IsSplitSettingsSyncEnabled()) {
     if (!disabled_types.Has(syncer::OS_PREFERENCES)) {
-      controllers.push_back(OsSyncableServiceModelTypeController::Create(
-          syncer::OS_PREFERENCES, model_type_store_factory,
-          GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack,
-          profile_->GetPrefs(), sync_service));
+      controllers.push_back(
+          std::make_unique<OsSyncableServiceModelTypeController>(
+              syncer::OS_PREFERENCES, model_type_store_factory,
+              GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack,
+              profile_->GetPrefs(), sync_service));
     }
     if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) {
-      controllers.push_back(OsSyncableServiceModelTypeController::Create(
-          syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory,
-          GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES),
-          dump_stack, profile_->GetPrefs(), sync_service));
+      controllers.push_back(
+          std::make_unique<OsSyncableServiceModelTypeController>(
+              syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory,
+              GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES),
+              dump_stack, profile_->GetPrefs(), sync_service));
     }
     if (!disabled_types.Has(syncer::PRINTERS)) {
       // Use the same delegate in full-sync and transport-only modes.
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index 360ed3a..32fae958 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -310,6 +310,23 @@
 }
 
 // static
+bool ProfileSyncServiceFactory::IsSyncAllowed(Profile* profile) {
+  DCHECK(profile);
+  if (HasSyncService(profile)) {
+    syncer::SyncService* sync_service = GetForProfile(profile);
+    return !sync_service->HasDisableReason(
+               syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE) &&
+           !sync_service->HasDisableReason(
+               syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
+  }
+
+  // No ProfileSyncService created yet - we don't want to create one, so just
+  // infer the accessible state by looking at prefs/command line flags.
+  syncer::SyncPrefs prefs(profile->GetPrefs());
+  return switches::IsSyncAllowedByFlag() && !prefs.IsManaged();
+}
+
+// static
 std::vector<const syncer::SyncService*>
 ProfileSyncServiceFactory::GetAllSyncServices() {
   std::vector<Profile*> profiles =
diff --git a/chrome/browser/sync/profile_sync_service_factory.h b/chrome/browser/sync/profile_sync_service_factory.h
index 16ec4aa..0f2fa7bd 100644
--- a/chrome/browser/sync/profile_sync_service_factory.h
+++ b/chrome/browser/sync/profile_sync_service_factory.h
@@ -44,6 +44,11 @@
   // Note that GetForProfile will create the service if it doesn't exist yet.
   static bool HasSyncService(Profile* profile);
 
+  // Checks whether sync is configurable by the user. Returns false if sync is
+  // disallowed by the command line or controlled by configuration management.
+  // |profile| must not be nullptr.
+  static bool IsSyncAllowed(Profile* profile);
+
   static ProfileSyncServiceFactory* GetInstance();
 
   // Overrides how the SyncClient is created for testing purposes.
diff --git a/chrome/browser/sync/sync_error_notifier_ash.cc b/chrome/browser/sync/sync_error_notifier_ash.cc
index 3ad4e6a..344ffe6 100644
--- a/chrome/browser/sync/sync_error_notifier_ash.cc
+++ b/chrome/browser/sync/sync_error_notifier_ash.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/common/url_constants.h"
@@ -26,6 +27,7 @@
 #include "chrome/grit/theme_resources.h"
 #include "components/account_id/account_id.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
 #include "components/user_manager/user_manager.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -36,6 +38,11 @@
 
 const char kProfileSyncNotificationId[] = "chrome://settings/sync/";
 
+struct BubbleViewParameters {
+  int message_id;
+  base::RepeatingClosure click_action;
+};
+
 void ShowSyncSetup(Profile* profile) {
   LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile);
   if (login_ui->current_login_ui()) {
@@ -48,6 +55,38 @@
   chrome::ShowSettingsSubPageForProfile(profile, chrome::kSyncSetupSubPage);
 }
 
+void TriggerSyncKeyRetrieval(Profile* profile) {
+  chrome::ScopedTabbedBrowserDisplayer displayer(profile);
+  sync_ui_util::OpenTabForSyncKeyRetrieval(displayer.browser());
+}
+
+BubbleViewParameters GetBubbleViewParameters(
+    Profile* profile,
+    syncer::SyncService* sync_service) {
+  if (sync_ui_util::ShouldShowPassphraseError(sync_service)) {
+    BubbleViewParameters params;
+    params.message_id = IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE;
+    // |profile| is guaranteed to outlive the callback because the ownership of
+    // the notification gets transferred to NotificationDisplayService, which is
+    // a keyed service that cannot outlive the profile.
+    params.click_action =
+        base::BindRepeating(&ShowSyncSetup, base::Unretained(profile));
+    return params;
+  }
+
+  DCHECK(sync_ui_util::ShouldShowSyncKeysMissingError(sync_service));
+
+  BubbleViewParameters params;
+  params.message_id =
+      sync_service->GetUserSettings()->IsEncryptEverythingEnabled()
+          ? IDS_SYNC_NEEDS_KEYS_FOR_EVERYTHING_ERROR_BUBBLE_VIEW_MESSAGE
+          : IDS_SYNC_NEEDS_KEYS_FOR_PASSWORDS_ERROR_BUBBLE_VIEW_MESSAGE;
+
+  params.click_action =
+      base::BindRepeating(&TriggerSyncKeyRetrieval, base::Unretained(profile));
+  return params;
+}
+
 }  // namespace
 
 SyncErrorNotifier::SyncErrorNotifier(syncer::SyncService* sync_service,
@@ -77,14 +116,16 @@
 
   // TODO(crbug.com/1019687): A sync error should also be prompted for
   // sync_ui_util::ShouldShowSyncKeysMissingError().
+  const bool should_display_notification =
+      sync_ui_util::ShouldShowPassphraseError(sync_service_) ||
+      sync_ui_util::ShouldShowSyncKeysMissingError(sync_service_);
 
-  if (sync_ui_util::ShouldShowPassphraseError(sync_service_) ==
-      notification_displayed_) {
+  if (should_display_notification == notification_displayed_) {
     return;
   }
 
   auto* display_service = NotificationDisplayService::GetForProfile(profile_);
-  if (!sync_ui_util::ShouldShowPassphraseError(sync_service_)) {
+  if (!should_display_notification) {
     notification_displayed_ = false;
     display_service->Close(NotificationHandler::Type::TRANSIENT,
                            notification_id_);
@@ -104,8 +145,7 @@
 
   // Error state just got triggered. There shouldn't be previous notification.
   // Let's display one.
-  DCHECK(!notification_displayed_ &&
-         sync_ui_util::ShouldShowPassphraseError(sync_service_));
+  DCHECK(!notification_displayed_ && should_display_notification);
 
   message_center::NotifierId notifier_id(
       message_center::NotifierType::SYSTEM_COMPONENT,
@@ -115,18 +155,20 @@
   notifier_id.profile_id =
       multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail();
 
+  BubbleViewParameters parameters =
+      GetBubbleViewParameters(profile_, sync_service_);
+
   // Add a new notification.
   std::unique_ptr<message_center::Notification> notification =
       ash::CreateSystemNotification(
           message_center::NOTIFICATION_TYPE_SIMPLE, notification_id_,
           l10n_util::GetStringUTF16(IDS_SYNC_ERROR_BUBBLE_VIEW_TITLE),
-          l10n_util::GetStringUTF16(
-              IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE),
+          l10n_util::GetStringUTF16(parameters.message_id),
           l10n_util::GetStringUTF16(IDS_SIGNIN_ERROR_DISPLAY_SOURCE),
           GURL(notification_id_), notifier_id,
           message_center::RichNotificationData(),
           base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
-              base::BindRepeating(&ShowSyncSetup, profile_)),
+              parameters.click_action),
           ash::kNotificationWarningIcon,
           message_center::SystemNotificationWarningLevel::WARNING);
 
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc
index e7206bb..836737e 100644
--- a/chrome/browser/sync/sync_startup_tracker_unittest.cc
+++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -24,7 +24,7 @@
   SyncStartupTrackerTest() {}
 
   void SetupNonInitializedPSS() {
-    sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+    sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet());
     sync_service_.SetTransportState(
         syncer::SyncService::TransportState::INITIALIZING);
   }
@@ -34,7 +34,7 @@
 };
 
 TEST_F(SyncStartupTrackerTest, SyncAlreadyInitialized) {
-  sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet());
   sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
   EXPECT_CALL(observer_, SyncStartupCompleted());
   SyncStartupTracker tracker(&sync_service_, &observer_);
@@ -54,7 +54,7 @@
 TEST_F(SyncStartupTrackerTest, SyncAuthError) {
   // Make sure that we get a SyncStartupFailed() callback if sync gets an auth
   // error.
-  sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet());
   sync_service_.SetTransportState(
       syncer::SyncService::TransportState::INITIALIZING);
   sync_service_.SetAuthError(
@@ -86,7 +86,7 @@
   Mock::VerifyAndClearExpectations(&sync_service_);
 
   // Now, mark the PSS as having an auth error.
-  sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  sync_service_.SetDisableReasons(syncer::SyncService::DisableReasonSet());
   sync_service_.SetTransportState(
       syncer::SyncService::TransportState::INITIALIZING);
   sync_service_.SetAuthError(
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index fad1028e..888eb80 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -116,7 +116,7 @@
       test_environment->UpdatePersistentErrorOfRefreshTokenForAccount(
           account_id,
           GoogleServiceAuthError(GoogleServiceAuthError::State::SERVICE_ERROR));
-      service->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+      service->SetDisableReasons(syncer::SyncService::DisableReasonSet());
       return {SYNC_ERROR, IDS_SYNC_RELOGIN_ERROR, IDS_SYNC_RELOGIN_LINK_LABEL,
               REAUTHENTICATE};
     }
@@ -129,7 +129,7 @@
       syncer::SyncStatus status;
       status.sync_protocol_error = protocol_error;
       service->SetDetailedSyncStatus(false, status);
-      service->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+      service->SetDisableReasons(syncer::SyncService::DisableReasonSet());
       return {SYNC_ERROR, IDS_SYNC_UPGRADE_CLIENT,
               IDS_SYNC_UPGRADE_CLIENT_LINK_LABEL, UPGRADE_CLIENT};
     }
@@ -145,7 +145,7 @@
       service->SetFirstSetupComplete(true);
       service->SetTransportState(syncer::SyncService::TransportState::ACTIVE);
       service->SetDetailedSyncStatus(false, syncer::SyncStatus());
-      service->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+      service->SetDisableReasons(syncer::SyncService::DisableReasonSet());
       service->SetPassphraseRequired(true);
       service->SetPassphraseRequiredForPreferredDataTypes(true);
       return {SYNC_ERROR, IDS_SYNC_STATUS_NEEDS_PASSWORD,
@@ -155,7 +155,7 @@
       service->SetFirstSetupComplete(true);
       service->SetTransportState(syncer::SyncService::TransportState::ACTIVE);
       service->SetDetailedSyncStatus(false, syncer::SyncStatus());
-      service->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+      service->SetDisableReasons(syncer::SyncService::DisableReasonSet());
       service->SetPassphraseRequired(false);
       service->SetTrustedVaultKeyRequiredForPreferredDataTypes(true);
       return {PASSWORDS_ONLY_SYNC_ERROR, IDS_SETTINGS_EMPTY_STRING,
@@ -165,7 +165,7 @@
       service->SetFirstSetupComplete(true);
       service->SetTransportState(syncer::SyncService::TransportState::ACTIVE);
       service->SetDetailedSyncStatus(false, syncer::SyncStatus());
-      service->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+      service->SetDisableReasons(syncer::SyncService::DisableReasonSet());
       service->SetPassphraseRequired(false);
       return {SYNCED, IDS_SYNC_ACCOUNT_SYNCING, IDS_SETTINGS_EMPTY_STRING,
               NO_ACTION};
diff --git a/chrome/browser/task_manager/providers/web_contents/background_contents_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/background_contents_tag_browsertest.cc
index 4c144415..8e28b0b 100644
--- a/chrome/browser/task_manager/providers/web_contents/background_contents_tag_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/background_contents_tag_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_manager.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/common/content_switches.h"
 #include "extensions/common/switches.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -47,7 +48,7 @@
     extensions::ExtensionBrowserTest::SetUpCommandLine(command_line);
     test_data_dir_ = test_data_dir_.AppendASCII("api_test");
     command_line->AppendSwitch(switches::kDisableRendererBackgrounding);
-    command_line->AppendSwitch(switches::kDisablePopupBlocking);
+    command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
     command_line->AppendSwitch(extensions::switches::kAllowHTTPBackgroundPage);
   }
 
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
index 792a7d0..3733abb 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
@@ -80,14 +80,19 @@
     /**
      * If set to true, requests to show the bottom sheet. Otherwise, requests to hide the sheet.
      * @param isVisible A boolean describing whether to show or hide the sheet.
+     * @return True if the request was successful, false otherwise.
      */
-    void setVisible(boolean isVisible) {
+    boolean setVisible(boolean isVisible) {
         if (isVisible) {
             mBottomSheetController.addObserver(mBottomSheetObserver);
-            mBottomSheetController.requestShowContent(this, true);
+            if (!mBottomSheetController.requestShowContent(this, true)) {
+                mBottomSheetController.removeObserver(mBottomSheetObserver);
+                return false;
+            }
         } else {
             mBottomSheetController.hideContent(this, true);
         }
+        return true;
     }
 
     void setSheetItemListAdapter(RecyclerView.Adapter adapter) {
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
index ed6a8028..39bfe4b 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
@@ -29,6 +29,7 @@
 import org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties;
 import org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ItemType;
 import org.chromium.chrome.browser.touch_to_fill.data.Credential;
+import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.ui.modelutil.MVCListAdapter;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -51,7 +52,11 @@
         if (propertyKey == DISMISS_HANDLER) {
             view.setDismissHandler(model.get(DISMISS_HANDLER));
         } else if (propertyKey == VISIBLE) {
-            view.setVisible(model.get(VISIBLE));
+            boolean visibilityChangeSuccessful = view.setVisible(model.get(VISIBLE));
+            if (!visibilityChangeSuccessful && model.get(VISIBLE)) {
+                assert (model.get(DISMISS_HANDLER) != null);
+                model.get(DISMISS_HANDLER).onResult(BottomSheetController.StateChangeReason.NONE);
+            }
         } else if (propertyKey == ON_CLICK_MANAGE) {
             view.setOnManagePasswordClick(model.get(ON_CLICK_MANAGE));
         } else if (propertyKey == SHEET_ITEMS) {
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
index 24cbff6..6ed44382 100644
--- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
+++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
@@ -4,6 +4,10 @@
 
 package org.chromium.chrome.browser.touch_to_fill;
 
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
@@ -12,9 +16,14 @@
 import static org.chromium.content_public.browser.test.util.CriteriaHelper.pollUiThread;
 import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
 
+import android.annotation.SuppressLint;
 import android.support.test.espresso.Espresso;
 import android.support.test.filters.MediumTest;
 import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -29,6 +38,7 @@
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.touch_to_fill.data.Credential;
+import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetContent;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController.SheetState;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -105,6 +115,85 @@
         verify(mMockBridge, never()).onCredentialSelected(any());
     }
 
+    @Test
+    @MediumTest
+    @SuppressLint("SetTextI18n")
+    public void testDismissedIfUnableToShow() throws Exception {
+        BottomSheetController bottomSheetController =
+                mActivityTestRule.getActivity().getBottomSheetController();
+        BottomSheetContent otherBottomSheetContent = runOnUiThreadBlocking(() -> {
+            TextView highPriorityBottomSheetContentView =
+                    new TextView(mActivityTestRule.getActivity());
+            highPriorityBottomSheetContentView.setText("Another bottom sheet content");
+            BottomSheetContent content = new BottomSheetContent() {
+                @Override
+                public View getContentView() {
+                    return highPriorityBottomSheetContentView;
+                }
+
+                @Nullable
+                @Override
+                public View getToolbarView() {
+                    return null;
+                }
+
+                @Override
+                public int getVerticalScrollOffset() {
+                    return 0;
+                }
+
+                @Override
+                public void destroy() {}
+
+                @Override
+                public int getPriority() {
+                    return ContentPriority.HIGH;
+                }
+
+                @Override
+                public boolean swipeToDismissEnabled() {
+                    return false;
+                }
+
+                @Override
+                public int getSheetContentDescriptionStringId() {
+                    return 0;
+                }
+
+                @Override
+                public int getSheetHalfHeightAccessibilityStringId() {
+                    return 0;
+                }
+
+                @Override
+                public int getSheetFullHeightAccessibilityStringId() {
+                    return 0;
+                }
+
+                @Override
+                public int getSheetClosedAccessibilityStringId() {
+                    return 0;
+                }
+            };
+            bottomSheetController.requestShowContent(content, /* animate = */ false);
+            return content;
+        });
+        pollUiThread(() -> getBottomSheetState() == SheetState.PEEK);
+        Espresso.onView(withText("Another bottom sheet content")).check(matches(isDisplayed()));
+
+        runOnUiThreadBlocking(() -> {
+            mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
+        });
+        waitForEvent(mMockBridge).onDismissed();
+        verify(mMockBridge, never()).onCredentialSelected(any());
+        Espresso.onView(withText("Another bottom sheet content")).check(matches(isDisplayed()));
+
+        runOnUiThreadBlocking(() -> {
+            bottomSheetController.hideContent(otherBottomSheetContent, /* animate = */ false);
+        });
+        pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HIDDEN);
+    }
+
     private RecyclerView getCredentials() {
         return mActivityTestRule.getActivity().findViewById(R.id.sheet_item_list);
     }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 7f1b7da..3adc96f 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -431,6 +431,7 @@
     "//components/domain_reliability",
     "//components/download/content/factory",
     "//components/download/content/public",
+    "//components/embedder_support:switches",
     "//components/encrypted_messages:encrypted_message_proto",
     "//components/favicon/content",
     "//components/favicon/core",
@@ -2045,6 +2046,7 @@
         "webui/chromeos/emulator/device_emulator_ui.cc",
         "webui/chromeos/emulator/device_emulator_ui.h",
       ]
+      deps += [ "//chromeos/components/sample_system_web_app_ui" ]
     }
 
     if (use_cras) {
@@ -2054,6 +2056,10 @@
 
   if (is_win || is_mac || is_desktop_linux || is_chromeos) {
     sources += [
+      "autofill/payments/virtual_card_selection_dialog_controller.h",
+      "autofill/payments/virtual_card_selection_dialog_controller_impl.cc",
+      "autofill/payments/virtual_card_selection_dialog_controller_impl.h",
+      "autofill/payments/virtual_card_selection_dialog_view.h",
       "autofill/payments/webauthn_dialog_controller.h",
       "autofill/payments/webauthn_dialog_controller_impl.cc",
       "autofill/payments/webauthn_dialog_controller_impl.h",
@@ -2069,6 +2075,8 @@
       "signin_view_controller_delegate.h",
       "tab_contents/chrome_web_contents_view_handle_drop.cc",
       "tab_contents/chrome_web_contents_view_handle_drop.h",
+      "views/autofill/payments/virtual_card_selection_dialog_view_impl.cc",
+      "views/autofill/payments/virtual_card_selection_dialog_view_impl.h",
       "views/autofill/payments/webauthn_dialog_view_impl.cc",
       "views/autofill/payments/webauthn_dialog_view_impl.h",
       "views/close_bubble_on_tab_activation_helper.cc",
@@ -3733,6 +3741,8 @@
       "app_list/search/zero_state_file_provider.h",
       "app_list/search/zero_state_file_result.cc",
       "app_list/search/zero_state_file_result.h",
+      "app_list/web_app_context_menu.cc",
+      "app_list/web_app_context_menu.h",
       "ash/assistant/assistant_client.cc",
       "ash/assistant/assistant_client.h",
       "ash/assistant/assistant_context_util.cc",
@@ -3767,6 +3777,7 @@
       "ash/launcher/arc_app_shelf_id.h",
       "ash/launcher/arc_app_window.cc",
       "ash/launcher/arc_app_window.h",
+      "ash/launcher/arc_app_window_delegate.h",
       "ash/launcher/arc_app_window_launcher_controller.cc",
       "ash/launcher/arc_app_window_launcher_controller.h",
       "ash/launcher/arc_app_window_launcher_item_controller.cc",
@@ -3805,8 +3816,6 @@
       "views/crostini/crostini_app_uninstaller_view.h",
       "views/crostini/crostini_force_close_view.cc",
       "views/crostini/crostini_force_close_view.h",
-      "views/crostini/crostini_installer_view.cc",
-      "views/crostini/crostini_installer_view.h",
       "views/crostini/crostini_package_install_failure_view.cc",
       "views/crostini/crostini_package_install_failure_view.h",
       "views/crostini/crostini_uninstaller_view.cc",
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapterRenderTest.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapterRenderTest.java
index 0bbe728c..8aa7f73 100644
--- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapterRenderTest.java
+++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapterRenderTest.java
@@ -32,7 +32,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ui.appmenu.test.R;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.RenderTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
 
@@ -65,8 +65,7 @@
     }
 
     @Rule
-    public RenderTestRule mRenderTestRule =
-            new RenderTestRule("chrome/test/data/android/render_tests");
+    public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
 
     @Override
     public void setUpTest() throws Exception {
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 86a05df6..95ce39c 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4079,6 +4079,19 @@
         Download
       </message>
 
+      <!-- Sharing Hub -->
+      <message name="IDS_SHARING_MORE_ICON_LABEL" desc="Icon label for the More button in the sharing hub.">
+        More
+      </message>
+
+      <message name="IDS_SHARING_COPY_URL" desc="Label for the Copy URL button in the sharing hub.">
+        Copy link
+      </message>
+
+      <message name="IDS_LINK_COPIED" desc="Text shown in the toast notification when Copy Link is selected in the sharing hub.">
+        Link Copied
+      </message>
+
       <!-- Chime DFM module strings -->
       <message name="IDS_CHIME_MODULE_TITLE" desc="Text shown when the chime module is referenced in install start, success, failure UI (e.g. in IDS_MODULE_INSTALL_START_TEXT, which will expand to 'Installing Google Notifications Platform for Chrome…').">
         Google Notifications Platform
@@ -4088,6 +4101,17 @@
       <message name="IDS_IMAGE_EDITOR_MODULE_TITLE" desc="Text shown when the image editor module is referenced in install start, success, failure UI (e.g. in IDS_MODULE_INSTALL_START_TEXT, which will expand to 'Installing Image Editor for Chrome…').">
         Image Editor
       </message>
+
+      <!-- NFC prompt -->
+      <message name="IDS_NFC_DISABLED_ON_DEVICE_MESSAGE" desc="Text shown in a prompt to turn on NFC after user granted NFC permission to a website.">
+        To continue, turn on NFC on your phone
+      </message>
+      <message name="IDS_NFC_PROMPT_TURN_ON" desc="Text on the positive button of the nfc prompt">
+        Turn on
+      </message>
+      <message name="IDS_ANDROID_NFC_OFF_GLOBALLY" desc="The message to show when NFC has been turned off globally in Android. Contains a link to the settings menu to enable NFC.">
+        NFC is off for this device. Turn it on NFC in <ph name="BEGIN_LINK">&lt;link&gt;</ph>Android Settings<ph name="END_LINK">&lt;/link&gt;</ph>.
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_NFC_OFF_GLOBALLY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_NFC_OFF_GLOBALLY.png.sha1
new file mode 100644
index 0000000..6b4d8df
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_NFC_OFF_GLOBALLY.png.sha1
@@ -0,0 +1 @@
+56681f3701c16d54f915744074bddd043a2ecc33
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_COPIED.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_COPIED.png.sha1
new file mode 100644
index 0000000..b91ee7b4
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_COPIED.png.sha1
@@ -0,0 +1 @@
+a1a67b055fa3286aa7b5823a4897e6c4e96e7b91
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_DISABLED_ON_DEVICE_MESSAGE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_DISABLED_ON_DEVICE_MESSAGE.png.sha1
new file mode 100644
index 0000000..36723f0
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_DISABLED_ON_DEVICE_MESSAGE.png.sha1
@@ -0,0 +1 @@
+b61af89a20cbeaf1474ceb0bb4c3caa7494c517b
\ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_NFC_PERMISSION_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_PERMISSION_TITLE.png.sha1
similarity index 100%
rename from chrome/android/java/strings/android_chrome_strings_grd/IDS_NFC_PERMISSION_TITLE.png.sha1
rename to chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_PERMISSION_TITLE.png.sha1
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_PROMPT_TURN_ON.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_PROMPT_TURN_ON.png.sha1
new file mode 100644
index 0000000..36723f0
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_NFC_PROMPT_TURN_ON.png.sha1
@@ -0,0 +1 @@
+b61af89a20cbeaf1474ceb0bb4c3caa7494c517b
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_COPY_URL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_COPY_URL.png.sha1
new file mode 100644
index 0000000..3eadfa3
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_COPY_URL.png.sha1
@@ -0,0 +1 @@
+78f987076df36886fd258a9b1c4d79db957e823f
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_MORE_ICON_LABEL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_MORE_ICON_LABEL.png.sha1
new file mode 100644
index 0000000..c97936b
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SHARING_MORE_ICON_LABEL.png.sha1
@@ -0,0 +1 @@
+a5ac72e0a16a252df681466eabc9fc0ee06442fd
\ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_ASK.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_ASK.png.sha1
similarity index 100%
rename from chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_ASK.png.sha1
rename to chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_ASK.png.sha1
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_BLOCKED.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_BLOCKED.png.sha1
similarity index 100%
rename from chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_BLOCKED.png.sha1
rename to chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_NFC_BLOCKED.png.sha1
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
index ab14922..ac5606a7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Ouer as 30 dae</translation>
 <translation id="5858741533101922242">Chrome kan nie Bluetooth-aansluitprop aanskakel nie</translation>
 <translation id="5860033963881614850">Af</translation>
+<translation id="5860491529813859533">Skakel aan</translation>
 <translation id="5862731021271217234">Skakel sinkronisering aan om jou oortjies van jou ander toestelle af te kry</translation>
 <translation id="5864174910718532887">Besonderhede: Gerangskik volgens werfnaam</translation>
 <translation id="5864419784173784555">Wag tans vir nog 'n aflaai …</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
index a7c5dc7..4e874513 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">ከ30 ቀናት በላይ የቆየ</translation>
 <translation id="5858741533101922242">Chrome የብሉቱዝ አስማሚውን ማብራት አልቻለም</translation>
 <translation id="5860033963881614850">አጥፋ</translation>
+<translation id="5860491529813859533">አብራ</translation>
 <translation id="5862731021271217234">ትሮችዎን ከሌሎች መሣሪያዎችዎ ስምረትን ማብራት ለማግኘት</translation>
 <translation id="5864174910718532887">ዝርዝሮች፦ በጣቢያ ስም የተለየ</translation>
 <translation id="5864419784173784555">ሌላ ውርድን በመጠበቅ ላይ…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
index ce3242a..dd3477a6 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">مرّ عليها أكثر من 30 يومًا</translation>
 <translation id="5858741533101922242">‏يتعذر على Chrome تشغيل محوّل البلوتوث</translation>
 <translation id="5860033963881614850">غير مفعّل</translation>
+<translation id="5860491529813859533">تفعيل</translation>
 <translation id="5862731021271217234">للحصول على علامات التبويب من أجهزتك الأخرى، يُرجى تفعيل المزامنة.</translation>
 <translation id="5864174910718532887">التفاصيل: تم الترتيب بحسب اسم موقع الويب</translation>
 <translation id="5864419784173784555">في انتظار تنزيل آخر…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
index 8fb0ad76..26d50e0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
@@ -658,6 +658,7 @@
 <translation id="5854790677617711513">৩০ দিনতকৈ পুৰণি</translation>
 <translation id="5858741533101922242">Chromeএ ব্লুটুথ এডাপ্টৰটো অন কৰিবলৈ সক্ষম নহ’ল</translation>
 <translation id="5860033963881614850">অফ আছে</translation>
+<translation id="5860491529813859533">অন কৰক</translation>
 <translation id="5862731021271217234">আপোনাৰ অন্য ডিভাইচৰ টেবসমূহ পাবলৈ ছিংক অন কৰক</translation>
 <translation id="5864174910718532887">সবিশেষ: ছাইটৰ নাম অনুযায়ী সজোৱা হৈছে</translation>
 <translation id="5864419784173784555">অন্য এটা ডাউনল’ডৰ বাবে অপেক্ষা কৰি থকা হৈছে…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
index e5903170..982fe660 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 gündən çox</translation>
 <translation id="5858741533101922242">Chrome Bluetooth adapterini aktivləşdirə bilmir</translation>
 <translation id="5860033963881614850">Deaktiv</translation>
+<translation id="5860491529813859533">Aktiv edin</translation>
 <translation id="5862731021271217234">Tabları digər cihazlarınızdan əldə etmək üçün sinxronizasiyanı aktiv edin</translation>
 <translation id="5864174910718532887">Məlumat: Sayt adına görə çeşidləndi</translation>
 <translation id="5864419784173784555">Başqa endirmə gözlənilir…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
index d875fa6..a15b506 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Даныя, старэйшыя за 30 дзён</translation>
 <translation id="5858741533101922242">Браўзеру Chrome не ўдалося ўключыць Bluetooth-адаптар</translation>
 <translation id="5860033963881614850">Выключана</translation>
+<translation id="5860491529813859533">Уключыць</translation>
 <translation id="5862731021271217234">Каб глядзець укладкі са сваіх іншых прылад, уключыце сінхранізацыю</translation>
 <translation id="5864174910718532887">Падрабязнасці: адсартавана па назве сайта</translation>
 <translation id="5864419784173784555">Чаканне іншай спампоўкі…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
index 4b88dda9..4accb84a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">По-стари от 30 дни</translation>
 <translation id="5858741533101922242">Chrome не може да включи адаптера за Bluetooth</translation>
 <translation id="5860033963881614850">Изключено</translation>
+<translation id="5860491529813859533">Включване</translation>
 <translation id="5862731021271217234">Включете синхронизирането, за да получите разделите си от другите си устройства</translation>
 <translation id="5864174910718532887">Подробности: сортирани по име на сайта</translation>
 <translation id="5864419784173784555">Изчаква се друго изтегляне…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
index 88c3dc3..98c1b1d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
@@ -661,6 +661,7 @@
 <translation id="5854790677617711513">৩০ দিনের বেশি পুরনো</translation>
 <translation id="5858741533101922242">Chrome ব্লুটুথ অ্যাডাপ্টার চালু করতে পারছে না</translation>
 <translation id="5860033963881614850">বন্ধ করুন</translation>
+<translation id="5860491529813859533">চালু করুন</translation>
 <translation id="5862731021271217234">আপনার অন্যান্য ডিভাইস থেকে ট্যাবগুলি পেতে সিঙ্ক বিকল্প চালু করুন</translation>
 <translation id="5864174910718532887">বিবরণ: সাইটের নাম অনুযায়ী সাজানো হয়েছে</translation>
 <translation id="5864419784173784555">অন্য ডাউনলোডের জন্য অপেক্ষা করা হচ্ছে…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
index 249c1be..e93e685 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Starije od 30 dana</translation>
 <translation id="5858741533101922242">Chrome ne može uključiti Bluetooth adapter</translation>
 <translation id="5860033963881614850">Isklj.</translation>
+<translation id="5860491529813859533">Uključi</translation>
 <translation id="5862731021271217234">Da dobijete svoje kartice s drugih uređaja, uključite sinhronizaciju</translation>
 <translation id="5864174910718532887">Detalji: Sortirano po nazivu web lokacija</translation>
 <translation id="5864419784173784555">Čekanje drugog preuzimanja…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
index dc5e432e..9ccafd9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Anterior a 30 dies</translation>
 <translation id="5858741533101922242">Chrome no pot activar l'adaptador Bluetooth</translation>
 <translation id="5860033963881614850">Desactivat</translation>
+<translation id="5860491529813859533">Activa</translation>
 <translation id="5862731021271217234">Activa la sincronització per accedir a les pestanyes dels altres dispositius que tinguis</translation>
 <translation id="5864174910718532887">Detalls: files ordenades per nom del lloc web</translation>
 <translation id="5864419784173784555">S'està esperant que finalitzi una altra baixada…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
index 451f55d..6c7d42f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Starší než 30 dnů</translation>
 <translation id="5858741533101922242">Chrome nemůže zapnout adaptér Bluetooth</translation>
 <translation id="5860033963881614850">Vypnuto</translation>
+<translation id="5860491529813859533">Zapnout</translation>
 <translation id="5862731021271217234">Chcete-li získat přístup ke kartám ze svých ostatních zařízení, zapněte synchronizaci</translation>
 <translation id="5864174910718532887">Podrobnosti: Seřazeno podle názvu webu</translation>
 <translation id="5864419784173784555">Čekání na další stahování…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
index e2ee922..f1378270 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Ældre end 30 dage</translation>
 <translation id="5858741533101922242">Chrome kan ikke slå Bluetooth-adapteren til</translation>
 <translation id="5860033963881614850">Fra</translation>
+<translation id="5860491529813859533">Aktivér</translation>
 <translation id="5862731021271217234">Aktivér synkronisering for at få adgang til dine faner på dine andre enheder</translation>
 <translation id="5864174910718532887">Info: Sorteret efter navn på website</translation>
 <translation id="5864419784173784555">Venter på en anden download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
index 453f893..ca431c0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Älter als 30 Tage</translation>
 <translation id="5858741533101922242">Chrome kann den Bluetooth-Adapter nicht aktivieren</translation>
 <translation id="5860033963881614850">Aus</translation>
+<translation id="5860491529813859533">Aktivieren</translation>
 <translation id="5862731021271217234">Aktivieren Sie die Synchronisierung, um Ihre Tabs von Ihren anderen Geräten abzurufen</translation>
 <translation id="5864174910718532887">Details: Nach Websitename sortiert</translation>
 <translation id="5864419784173784555">Warten auf weiteren Download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
index d04fecc..85217e6f5 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Παλαιότερο από 30 ημέρες</translation>
 <translation id="5858741533101922242">Το Chrome δεν είναι δυνατό να ενεργοποιήσει τον προσαρμογέα Bluetooth</translation>
 <translation id="5860033963881614850">Απενεργοποιημένη</translation>
+<translation id="5860491529813859533">Ενεργοποίηση</translation>
 <translation id="5862731021271217234">Για να εμφανίζονται οι καρτέλες σας από τις άλλες συσκευές σας, ενεργοποιήστε τον συγχρονισμό</translation>
 <translation id="5864174910718532887">Λεπτομέρειες: Ταξινομήθηκαν κατά όνομα ιστοτόπου</translation>
 <translation id="5864419784173784555">Αναμονή για άλλη λήψη…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
index 8eed9886..2affabb5 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Older than 30 days</translation>
 <translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation>
 <translation id="5860033963881614850">Off</translation>
+<translation id="5860491529813859533">Turn on</translation>
 <translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation>
 <translation id="5864174910718532887">Details: Sorted by site name</translation>
 <translation id="5864419784173784555">Waiting for another download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
index 94ef927..67e3c1f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Hace más de 30 días</translation>
 <translation id="5858741533101922242">Chrome no puede activar el adaptador Bluetooth</translation>
 <translation id="5860033963881614850">No</translation>
+<translation id="5860491529813859533">Activar</translation>
 <translation id="5862731021271217234">Para obtener las pestañas de tus otros dispositivos, activa la sincronización</translation>
 <translation id="5864174910718532887">Detalles: Ordenados por nombre de sitio</translation>
 <translation id="5864419784173784555">Esperando que finalice otra descarga…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
index 9c3de15..163ca63 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Más de 30 días</translation>
 <translation id="5858741533101922242">Chrome no ha podido activar el adaptador Bluetooth</translation>
 <translation id="5860033963881614850">Desactivado</translation>
+<translation id="5860491529813859533">Activar</translation>
 <translation id="5862731021271217234">Activa la sincronización para ver las pestañas de tus otros dispositivos</translation>
 <translation id="5864174910718532887">Detalles: ordenados por nombre del sitio web</translation>
 <translation id="5864419784173784555">Esperando otra descarga…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
index 83ef9ca..6dd54159 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Vanemad kui 30 päeva</translation>
 <translation id="5858741533101922242">Chrome ei saa Bluetoothi adapterit sisse lülitada</translation>
 <translation id="5860033963881614850">Väljas</translation>
+<translation id="5860491529813859533">Lülita sisse</translation>
 <translation id="5862731021271217234">Vahelehtede hankimiseks oma teistest seadmetest lülitage sünkroonimine sisse</translation>
 <translation id="5864174910718532887">Üksikasjad: sorditud saidi nime alusel</translation>
 <translation id="5864419784173784555">Teise allalaadimise ootamine …</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
index 02a361b..02897bd 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Duela 30 egunetik gorakoak</translation>
 <translation id="5858741533101922242">Chrome-k ezin du aktibatu Bluetooth egokigailua</translation>
 <translation id="5860033963881614850">Desaktibatuta</translation>
+<translation id="5860491529813859533">Aktibatu</translation>
 <translation id="5862731021271217234">Beste gailuetako fitxak eskura izateko, aktibatu sinkronizazioa</translation>
 <translation id="5864174910718532887">Xehetasunak: webgunearen izenaren arabera ordenatuta</translation>
 <translation id="5864419784173784555">Beste deskarga bat amaitzeko zain…</translation>
@@ -752,6 +753,7 @@
 <translation id="6545017243486555795">Garbitu datu guztiak</translation>
 <translation id="6545864417968258051">Bluetooth bidezko gailuak bilatzea</translation>
 <translation id="6560414384669816528">Erabili Sogou bilatzaile gisa</translation>
+<translation id="656065428026159829">Ikusi gehiago</translation>
 <translation id="6566259936974865419"><ph name="GIGABYTES" /> GB aurreztu dituzu Chrome-ri esker</translation>
 <translation id="6573096386450695060">Eman baimena beti</translation>
 <translation id="6573431926118603307">Beste gailuetan Chrome-n ireki dituzun fitxak hemen agertuko dira.</translation>
@@ -848,6 +850,7 @@
 <translation id="7293171162284876153">Sinkronizatzen hasteko, aktibatu "Sinkronizatu Chrome-ko datuak".</translation>
 <translation id="729975465115245577">Gailuak ez du pasahitzen fitxategia gordetzeko aplikaziorik.</translation>
 <translation id="7302081693174882195">Xehetasunak: gordetako datu kopuruaren arabera ordenatuta</translation>
+<translation id="7302486331832100261">Jakinarazpenak blokeatu ohi dituzu. Baimena emateko, sakatu "Xehetasunak".</translation>
 <translation id="7328017930301109123">Oinarrizko moduari esker, Chrome-k bizkorrago kargatzen ditu orriak, datuen ehuneko 60raino aurreztuta.</translation>
 <translation id="7333031090786104871">Oraindik gehitzen ari da aurreko webgunea</translation>
 <translation id="7352939065658542140">BIDEOA</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
index ead76f9..13f512c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">قدیمی‌تر از ۳۰ روز</translation>
 <translation id="5858741533101922242">‏Chrome قادر به روشن کردن آداپتور بلوتوث نیست</translation>
 <translation id="5860033963881614850">خاموش</translation>
+<translation id="5860491529813859533">روشن کردن</translation>
 <translation id="5862731021271217234">برای اینکه به برگه‌های بازشده در سایر دستگاه‌ها دسترسی داشته باشید، همگام‌سازی را روشن کنید</translation>
 <translation id="5864174910718532887">جزئیات: مرتب‌شده براساس نام سایت</translation>
 <translation id="5864419784173784555">در انتظار بارگیری موردی دیگر…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
index 3ee8de0..2565854 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Yli 30 päivää vanhat</translation>
 <translation id="5858741533101922242">Chrome ei voi ottaa käyttöön Bluetooth-sovitinta.</translation>
 <translation id="5860033963881614850">Pois käytöstä</translation>
+<translation id="5860491529813859533">Ota käyttöön</translation>
 <translation id="5862731021271217234">Ota synkronointi käyttöön, niin voit käyttää välilehtiä muilta laitteiltasi</translation>
 <translation id="5864174910718532887">Lisätiedot: Lajiteltu sivuston nimen mukaan</translation>
 <translation id="5864419784173784555">Odottaa toista latausta…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
index d030549d..f187b20fd 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Mas matagal sa 30 araw</translation>
 <translation id="5858741533101922242">Hindi ma-on ng Chrome ang Bluetooth adapter</translation>
 <translation id="5860033963881614850">Naka-off</translation>
+<translation id="5860491529813859533">I-on</translation>
 <translation id="5862731021271217234">Para makuha ang iyong mga tab mula sa iba mo pang device, i-on ang pag-sync</translation>
 <translation id="5864174910718532887">Mga detalye: Pinagbukud-bukod ayon sa pangalan ng site</translation>
 <translation id="5864419784173784555">Naghihintay ng isa pang download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
index 5fec1fa..4315909d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Datant de plus de 30 jours</translation>
 <translation id="5858741533101922242">Chrome n'est pas en mesure d'activer l'adaptateur Bluetooth</translation>
 <translation id="5860033963881614850">Désactivé</translation>
+<translation id="5860491529813859533">Activer</translation>
 <translation id="5862731021271217234">Pour synchroniser vos onglets sur vos autres appareils, activez la synchronisation</translation>
 <translation id="5864174910718532887">Détails : triés par nom de site</translation>
 <translation id="5864419784173784555">En attente d'un autre téléchargement…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
index ee1970b..e589ea72 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Datant de plus de 30 jours</translation>
 <translation id="5858741533101922242">Impossible d'activer l'adaptateur Bluetooth dans Chrome</translation>
 <translation id="5860033963881614850">Désactivé</translation>
+<translation id="5860491529813859533">Activer</translation>
 <translation id="5862731021271217234">Activez la synchronisation pour accéder à vos onglets sur vos autres appareils</translation>
 <translation id="5864174910718532887">Détails : tri effectué par nom de site</translation>
 <translation id="5864419784173784555">En attente d'un autre téléchargement…</translation>
@@ -849,7 +850,7 @@
 <translation id="7293171162284876153">Pour lancer la synchronisation, activez l'option "Synchroniser vos données Chrome".</translation>
 <translation id="729975465115245577">Aucune application n'est installée sur votre appareil pour stocker le fichier de mots de passe.</translation>
 <translation id="7302081693174882195">Détails : tri effectué par volume de données enregistrées</translation>
-<translation id="7302486331832100261">Les notifications sont bloquées par défaut. Pour les autoriser, appuyez sur "Détails".</translation>
+<translation id="7302486331832100261">Vous avez l'habitude de bloquer les notifications. Pour les autoriser, appuyez sur "Détails".</translation>
 <translation id="7328017930301109123">En mode simplifié, Chrome charge les pages plus rapidement et consomme jusqu'à 60 pour cent de données en moins.</translation>
 <translation id="7333031090786104871">L'ajout du site précédent est toujours en cours</translation>
 <translation id="7352939065658542140">VIDÉO</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
index 6ab74ec..5f8aa08 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Con máis de 30 días</translation>
 <translation id="5858741533101922242">Chrome non é capaz de activar o adaptador de Bluetooth</translation>
 <translation id="5860033963881614850">Non</translation>
+<translation id="5860491529813859533">Activar</translation>
 <translation id="5862731021271217234">Activa a sincronización para sincronizar as pestanas dos demais dispositivos</translation>
 <translation id="5864174910718532887">Detalles: filas ordenadas por nome de sitio</translation>
 <translation id="5864419784173784555">Agardando por outra descarga…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
index af10a3c7..93a50a2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 દિવસ કરતા જૂનો</translation>
 <translation id="5858741533101922242">Chrome, Bluetooth એડેપ્ટરને ચાલુ કરવામાં અસમર્થ છે</translation>
 <translation id="5860033963881614850">બંધ</translation>
+<translation id="5860491529813859533">ચાલુ કરો</translation>
 <translation id="5862731021271217234">તમારા અન્ય ઉપકરણો પરથી તમારા ટૅબ મેળવવા માટે, સિંક કરવાનું ચાલુ કરો</translation>
 <translation id="5864174910718532887">વિગતો: સાઇટના નામ દ્વારા સૉર્ટ કરાયેલ</translation>
 <translation id="5864419784173784555">બીજા ડાઉનલોડ માટે રાહ જોઈ રહ્યાં છે…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
index 660f796..864f600 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 दिनों से ज़्यादा पुराना</translation>
 <translation id="5858741533101922242">Chrome, ब्लूटूथ एडाप्टर को चालू नहीं कर सका</translation>
 <translation id="5860033963881614850">बंद</translation>
+<translation id="5860491529813859533">चालू करें</translation>
 <translation id="5862731021271217234">अपने दूसरे डिवाइस से अपने टैब पाने के लिए, 'सिंक करें' को चालू करें</translation>
 <translation id="5864174910718532887">जानकारी: 'साइट नाम' के अनुसार क्रम से लगाया गया</translation>
 <translation id="5864419784173784555">दूसरे डाउनलोड का इंतज़ार किया जा रहा है…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
index 6621325e..b2072f3 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Starije od 30 dana</translation>
 <translation id="5858741533101922242">Chrome ne može uključiti Bluetooth adapter</translation>
 <translation id="5860033963881614850">Isključeno</translation>
+<translation id="5860491529813859533">Uključi</translation>
 <translation id="5862731021271217234">Da bi se prikazale kartice s vaših ostalih uređaja, uključite sinkronizaciju</translation>
 <translation id="5864174910718532887">Pojedinosti: poredano po nazivu web-lokacije</translation>
 <translation id="5864419784173784555">Čekanje na još jedno preuzimanje…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
index 63da835d..d58abec 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 napnál régebbi</translation>
 <translation id="5858741533101922242">A Chrome nem tudja bekapcsolni a Bluetooth-adaptert</translation>
 <translation id="5860033963881614850">Kikapcsolva</translation>
+<translation id="5860491529813859533">Bekapcsolás</translation>
 <translation id="5862731021271217234">Ha a többi eszközén lévő lapjait is szeretné elérni, kapcsolja be a szinkronizálást</translation>
 <translation id="5864174910718532887">Részletek: Webhelynév szerinti rendezés</translation>
 <translation id="5864419784173784555">Várakozás a másik letöltésre…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
index 3822f15..4d54e13 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 օր և ավելի</translation>
 <translation id="5858741533101922242">Չհաջողվեց միացնել Bluetooth ադապտերը</translation>
 <translation id="5860033963881614850">Անջատ.</translation>
+<translation id="5860491529813859533">Միացնել</translation>
 <translation id="5862731021271217234">Ձեր մյուս սարքերում եղած ներդիրներն օգտագործելու համար միացրեք համաժամացումը</translation>
 <translation id="5864174910718532887">Տեղեկություններ․ տեսակավորված է ըստ կայքի անվան</translation>
 <translation id="5864419784173784555">Նախորդ ներբեռնումն ավարտվում է…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
index 2ba993a..55e59b85 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Lebih dari 30 hari</translation>
 <translation id="5858741533101922242">Chrome tidak dapat mengaktifkan adaptor Bluetooth</translation>
 <translation id="5860033963881614850">Nonaktif</translation>
+<translation id="5860491529813859533">Aktifkan</translation>
 <translation id="5862731021271217234">Untuk membuka tab dari perangkat Anda yang lain, aktifkan sinkronisasi</translation>
 <translation id="5864174910718532887">Detail: Diurutkan menurut nama situs</translation>
 <translation id="5864419784173784555">Menunggu proses download lain…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
index 19ad3d7..014e30d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Eldra en 30 dagar</translation>
 <translation id="5858741533101922242">Chrome getur ekki kveikt á Bluetooth-millistykki</translation>
 <translation id="5860033963881614850">Slökkt</translation>
+<translation id="5860491529813859533">Kveikja</translation>
 <translation id="5862731021271217234">Kveiktu á samstillingu til að fá aðgang að flipunum þínum í öðrum tækjum</translation>
 <translation id="5864174910718532887">Upplýsingar: Raðað eftir heiti vefsvæðis</translation>
 <translation id="5864419784173784555">Bíður eftir öðru niðurhali…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
index 4e858d05..4f9ed85 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
@@ -453,7 +453,7 @@
 <translation id="445467742685312942">Consenti ai siti di riprodurre contenuti protetti</translation>
 <translation id="4468959413250150279">Disattiva l'audio per un sito specifico.</translation>
 <translation id="4472118726404937099">Accedi e attiva la sincronizzazione per sincronizzare e personalizzare tutti i dispositivi</translation>
-<translation id="447252321002412580">Contribuisci a migliorare le funzioni e le prestazioni di Chrome</translation>
+<translation id="447252321002412580">Contribuisci a migliorare le funzionalità e le prestazioni di Chrome</translation>
 <translation id="4479647676395637221">Chiedi conferma prima di consentire ai siti di utilizzare la videocamera (opzione consigliata)</translation>
 <translation id="4479972344484327217">Installazione di <ph name="MODULE" /> per Chrome…</translation>
 <translation id="4487967297491345095">Tutti i dati delle app di Chrome saranno eliminati definitivamente. Sono inclusi tutti i file, le impostazioni, gli account, i database e così via.</translation>
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Oltre 30 giorni fa</translation>
 <translation id="5858741533101922242">Chrome non riesce ad attivare l'adattatore Bluetooth</translation>
 <translation id="5860033963881614850">OFF</translation>
+<translation id="5860491529813859533">Attiva</translation>
 <translation id="5862731021271217234">Attiva la sincronizzazione per trovare le tue schede degli altri dispositivi</translation>
 <translation id="5864174910718532887">Dettagli: ordinati per nome del sito</translation>
 <translation id="5864419784173784555">In attesa di un altro download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
index d81988d..1e6c166 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">לפני יותר מ-30 ימים</translation>
 <translation id="5858741533101922242">‏לא ניתן להפעיל ב-Chrome את מתאם Bluetooth</translation>
 <translation id="5860033963881614850">כבוי</translation>
+<translation id="5860491529813859533">הפעל</translation>
 <translation id="5862731021271217234">כדי לקבל את הכרטיסיות מהמכשירים האחרים שלך, יש להפעיל את הסנכרון</translation>
 <translation id="5864174910718532887">פרטים: ממוינות לפי שם האתר</translation>
 <translation id="5864419784173784555">ממתין להורדה נוספת…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
index 6bfee61..2b2a5eb4 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 日以上経過</translation>
 <translation id="5858741533101922242">Chrome から Bluetooth アダプタをオンにできません</translation>
 <translation id="5860033963881614850">オフ</translation>
+<translation id="5860491529813859533">オンにする</translation>
 <translation id="5862731021271217234">他のデバイスと同じタブを使用するには、同期を有効にします</translation>
 <translation id="5864174910718532887">詳細: サイト名の順</translation>
 <translation id="5864419784173784555">別のダウンロードの完了待ちです…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
index 30648f2..212eeb1 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 დღეზე ძველი</translation>
 <translation id="5858741533101922242">Chrome-ის მიერ Bluetooth ადაპტერი ვერ ჩაირთო</translation>
 <translation id="5860033963881614850">გამორთვა</translation>
+<translation id="5860491529813859533">ჩართვა</translation>
 <translation id="5862731021271217234">თქვენს სხვა მოწყობილობებზე არსებულ ჩანართებზე წვდომისთვის ჩართეთ სინქრონიზაცია</translation>
 <translation id="5864174910718532887">დეტალები: დალაგებულია საიტის სახელის მიხედვით</translation>
 <translation id="5864419784173784555">სხვა ჩამოტვირთვის მოლოდინში…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
index e847948..1043f9db 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 күннен асқан</translation>
 <translation id="5858741533101922242">Chrome қолданбасы Bluetooth адаптерін қоса алмайды</translation>
 <translation id="5860033963881614850">Өшірулі</translation>
+<translation id="5860491529813859533">Қосу</translation>
 <translation id="5862731021271217234">Барлық құрылғылардан қойындыларды пайдалану үшін синхрондау функциясын қосыңыз</translation>
 <translation id="5864174910718532887">Мәліметтер: сайт атауы бойынша сұрыпталды</translation>
 <translation id="5864419784173784555">Басқа мазмұн жүктеп алынуда...</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
index 2129096..d87502c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">ចាស់ជាង 30 ថ្ងៃ</translation>
 <translation id="5858741533101922242">Chrome មិនអាចបើក​អាដាប់ទ័រ​ប៊្លូធូស​បានទេ</translation>
 <translation id="5860033963881614850">បិទ</translation>
+<translation id="5860491529813859533">បើក</translation>
 <translation id="5862731021271217234">ដើម្បីទទួលបានផ្ទាំងរបស់អ្នកពីឧបករណ៍ផ្សេងទៀតរបស់អ្នក សូមបើកសមកាលកម្ម</translation>
 <translation id="5864174910718532887">ព័ត៌មាន​លម្អិត៖ ​តម្រៀបតាមឈ្មោះ​គេហទំព័រ</translation>
 <translation id="5864419784173784555">កំពុង​រង់ចាំ​ការទាញយក​ផ្សេង​ទៀត…</translation>
@@ -752,6 +753,7 @@
 <translation id="6545017243486555795">ជម្រះទិន្នន័យទាំងអស់</translation>
 <translation id="6545864417968258051">ការស្កេនប៊្លូធូស</translation>
 <translation id="6560414384669816528">ស្វែងរកដោយប្រើ Sogou</translation>
+<translation id="656065428026159829">មើលច្រើនទៀត</translation>
 <translation id="6566259936974865419">Chrome សន្សំឲ្យអ្នកបាន <ph name="GIGABYTES" /> GB</translation>
 <translation id="6573096386450695060">អនុញ្ញាត​ជា​និច្ច</translation>
 <translation id="6573431926118603307">ផ្ទាំងដែលអ្នកបានបើកនៅក្នុង Chrome នៅលើឧបករណ៍ផ្សេងទៀតរបស់អ្នកនឹងបង្ហាញនៅទីនេះ</translation>
@@ -848,6 +850,7 @@
 <translation id="7293171162284876153">ដើម្បី​ចាប់ផ្ដើមសមកាលកម្ម សូមបើក​ "ធ្វើសមកាលកម្មទិន្នន័យ​ Chrome របស់អ្នក"។</translation>
 <translation id="729975465115245577">ឧបករណ៍​របស់អ្នក​មិន​មាន​កម្មវិធី ដើម្បី​ផ្ទុក​ឯកសារ​ពាក្យសម្ងាត់​ទេ។</translation>
 <translation id="7302081693174882195">ព័ត៌មាន​លម្អិត៖ ​តម្រៀប​តាមទំហំ​ទិន្នន័យ​ដែលបានរក្សាទុក</translation>
+<translation id="7302486331832100261">ជាធម្មតា អ្នកទប់ស្កាត់​ការជូនដំណឹង។ ដើម្បី​អនុញ្ញាត សូម​ចុច "ព័ត៌មាន​លម្អិត"​។</translation>
 <translation id="7328017930301109123">នៅក្នុង​មុខងារស្រាល Chrome ផ្ទុកទំព័រ​រហ័សជាងមុន និងប្រើទិន្នន័យ​តិចជាងមុន​រហូតដល់ 60 ភាគរយ។</translation>
 <translation id="7333031090786104871">កំពុង​បញ្ចូល​ទំព័រ​ពីមុន​នៅឡើយ</translation>
 <translation id="7352939065658542140">វីដេអូ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
index 6706a76..db3ae39 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 ದಿನಗಳಿಗಿಂತ ಹಳೆಯದು</translation>
 <translation id="5858741533101922242">ಬ್ಲೂಟೂತ್ ಅಡಾಪ್ಟರ್ ಆನ್ ಮಾಡಲು Chrome ಗೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</translation>
 <translation id="5860033963881614850">ಆಫ್</translation>
+<translation id="5860491529813859533">ಆನ್ ಮಾಡಿ</translation>
 <translation id="5862731021271217234">ನಿಮ್ಮ ಇತರ ಸಾಧನಗಳಿಂದ ನಿಮ್ಮ ಟ್ಯಾಬ್‌ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಲು, ಸಿಂಕ್‌ ಆನ್‌ ಮಾಡಿ</translation>
 <translation id="5864174910718532887">ವಿವರಗಳು: ಸೈಟ್ ಹೆಸರಿನ ಪ್ರಕಾರ ವಿಂಗಡಿಸಲಾಗಿದೆ</translation>
 <translation id="5864419784173784555">ಇನ್ನೊಂದು ಡೌನ್‌ಲೋಡ್‌ಗಾಗಿ ಕಾಯಲಾಗುತ್ತಿದೆ…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
index ee920ec6..e476de7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
@@ -212,7 +212,7 @@
 <translation id="2532336938189706096">웹 보기</translation>
 <translation id="2534155362429831547"><ph name="NUMBER_OF_ITEMS" />개 항목 삭제함</translation>
 <translation id="2536728043171574184">이 페이지의 오프라인 사본 보는 중</translation>
-<translation id="2537178555904266562">비밀번호 동기화 중 오류</translation>
+<translation id="2537178555904266562">비밀번호 동기화 중 오류 발생</translation>
 <translation id="2537296579376733324">모든 쿠키, 이 사이트에서만</translation>
 <translation id="2546283357679194313">쿠키 및 사이트 데이터</translation>
 <translation id="2567385386134582609">이미지</translation>
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30일 이상 전</translation>
 <translation id="5858741533101922242">Chrome에서 블루투스 어댑터를 사용 설정할 수 없습니다.</translation>
 <translation id="5860033963881614850">사용 안함</translation>
+<translation id="5860491529813859533">사용</translation>
 <translation id="5862731021271217234">다른 기기에서 탭을 가져오려면 동기화를 사용 설정하세요.</translation>
 <translation id="5864174910718532887">세부정보: 사이트 이름별로 정렬</translation>
 <translation id="5864419784173784555">다른 다운로드 대기 중…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
index a5af08e..05c817a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 күндөн мурунку</translation>
 <translation id="5858741533101922242">Chrome Bluetooth адаптерин күйгүзө албай жатат</translation>
 <translation id="5860033963881614850">Өчүк</translation>
+<translation id="5860491529813859533">Күйгүзүү</translation>
 <translation id="5862731021271217234">Өтмөктөрүңүздү башка түзмөктөрүңүздөн алуу үчүн шайкештирүүнү күйгүзүңүз</translation>
 <translation id="5864174910718532887">Кошумча маалымат: Сайттын аталышы боюнча иргелди</translation>
 <translation id="5864419784173784555">Башка жүктөп алуу күтүлүүдө…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
index 9203456..6c584331c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">ເກົ່າກວ່າ 30 ມື້</translation>
 <translation id="5858741533101922242">Chrome ບໍ່ສາມາດເປີດອະແດັບເຕີ Bluetooth ໄດ້</translation>
 <translation id="5860033963881614850">ປິດ</translation>
+<translation id="5860491529813859533">ເປີດ</translation>
 <translation id="5862731021271217234">ເພື່ອໂຫຼດແຖບຂອງທ່ານຈາກອຸປະກອນອື່ນ, ກະລຸນາເປີດການຊິ້ງຂໍ້ມູນກ່ອນ</translation>
 <translation id="5864174910718532887">ລາຍລະອຽດ: ຮຽງລຳດັບຕາມຊື່ເວັບໄຊ</translation>
 <translation id="5864419784173784555">ກຳລັງລໍຖ້າການດາວໂຫຼດອື່ນຢູ່...</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
index 94c8529..e8ac84a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Senesni nei 30 dienų</translation>
 <translation id="5858741533101922242">„Chrome“ nepavyksta įjungti „Bluetooth“ adapterio</translation>
 <translation id="5860033963881614850">Išjungta</translation>
+<translation id="5860491529813859533">Įjungti</translation>
 <translation id="5862731021271217234">Jei norite pasiekti skirtukus iš kitų įrenginių, įjunkite sinchronizavimą</translation>
 <translation id="5864174910718532887">Išsami informacija: surūšiuota pagal svetainės pavadinimą</translation>
 <translation id="5864419784173784555">Laukiama kito atsisiuntimo…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
index ebd7d52..e3799b8 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Vecāki par 30 dienām</translation>
 <translation id="5858741533101922242">Chrome nevar ieslēgt Bluetooth adapteri.</translation>
 <translation id="5860033963881614850">Izsl.</translation>
+<translation id="5860491529813859533">Ieslēgt</translation>
 <translation id="5862731021271217234">Lai varētu piekļūt cilnēm no citām ierīcēm, ieslēdziet sinhronizāciju.</translation>
 <translation id="5864174910718532887">Detalizēta informācija: kārtota pēc vietnes nosaukuma</translation>
 <translation id="5864419784173784555">Tiek gaidīta cita lejupielāde…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
index 428b098..436c151e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Постари од 30 дена</translation>
 <translation id="5858741533101922242">Chrome не може да го вклучи Bluetooth адаптерот</translation>
 <translation id="5860033963881614850">Исклучено</translation>
+<translation id="5860491529813859533">Вклучи</translation>
 <translation id="5862731021271217234">За да ги добиете вашите картички од другите уреди, вклучете ја синхронизацијата</translation>
 <translation id="5864174910718532887">Детали: подредени по име на сајт</translation>
 <translation id="5864419784173784555">Се чека друго преземање…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
index 0705af5..5e1912a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 ദിവസത്തിൽ കൂടുതൽ പഴക്കമുള്ളത്</translation>
 <translation id="5858741533101922242">Chrome-ന് Bluetooth അഡാപ്‌റ്റർ ഓണാക്കാനാവുന്നില്ല</translation>
 <translation id="5860033963881614850">ഓഫാക്കുക</translation>
+<translation id="5860491529813859533">ഓൺ ചെയ്യുക</translation>
 <translation id="5862731021271217234">നിങ്ങളുടെ മറ്റ് ഉപകരണങ്ങളിൽ നിന്നുള്ള ടാബുകൾ ലഭിക്കാൻ, സമന്വയിപ്പിക്കൽ ഓണാക്കുക</translation>
 <translation id="5864174910718532887">വിശദാംശങ്ങൾ: സൈറ്റിൻ്റെ പേരനുസരിച്ച് അടുക്കിയത്</translation>
 <translation id="5864419784173784555">മറ്റൊരു ഡൗൺലോഡിനായി കാത്തിരിക്കുന്നു…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
index 2e614e1..41c683c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
@@ -658,6 +658,7 @@
 <translation id="5854790677617711513">30 өдрөөс илүү</translation>
 <translation id="5858741533101922242">Chrome Bluetooth тохируулагчийг асаах боломжгүй байна</translation>
 <translation id="5860033963881614850">Идэвхгүй байна</translation>
+<translation id="5860491529813859533">Асаах</translation>
 <translation id="5862731021271217234">Бусад төхөөрөмжөөс чихтэй хуудсаа авахын тулд синкийг асаана уу</translation>
 <translation id="5864174910718532887">Дэлгэрэнгүй: Сайтын нэрээр эрэмбэлсэн</translation>
 <translation id="5864419784173784555">Өөр таталтыг хүлээж байна…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
index 42ef6d7..ff44f41 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 दिवसांपेक्षा जुना</translation>
 <translation id="5858741533101922242">ब्लूटूथ अडॅप्टर सुरू करण्यात Chrome अक्षम आहे</translation>
 <translation id="5860033963881614850">बंद</translation>
+<translation id="5860491529813859533">चालू करा</translation>
 <translation id="5862731021271217234">तुमच्या इतर डिव्हाइसवरून तुमचे टॅब मिळवण्यासाठी, सिंक सुरू करा</translation>
 <translation id="5864174910718532887">तपशील: साइटच्या नावानुसार क्रमाने लावलेले</translation>
 <translation id="5864419784173784555">दुसर्‍या डाउनलोडची वाट पाहत आहे…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
index 711cc3e..5666d42 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Lebih lama daripada 30 hari</translation>
 <translation id="5858741533101922242">Chrome tidak dapat menghidupkan penyesuai Bluetooth</translation>
 <translation id="5860033963881614850">Dimatikan</translation>
+<translation id="5860491529813859533">Hidupkan</translation>
 <translation id="5862731021271217234">Hidupkan penyegerakan untuk mendapatkan tab daripada peranti anda yang lain</translation>
 <translation id="5864174910718532887">Butiran: Diisih mengikut nama tapak</translation>
 <translation id="5864419784173784555">Menunggu muat turun lain…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
index e94ce9a..896132b 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">ရက် ၃၀ ထက် ပိုဟောင်းသော</translation>
 <translation id="5858741533101922242">Chrome က ဘလူးတုသ် ကြားခံကိရိယာကို ဖွင့်မပေးနိုင်ပါ</translation>
 <translation id="5860033963881614850">ပိတ်ထား</translation>
+<translation id="5860491529813859533">ဖွင့်ရန်</translation>
 <translation id="5862731021271217234">သင်၏ အခြားစက်ပစ္စည်းများမှ တဘ်များကိုအသုံးပြုရန် စင့်ခ်ကို ဖွင့်ပါ</translation>
 <translation id="5864174910718532887">အသေးစိတ်များ− ဝဘ်ဆိုက်အမည်အလိုက် စီထားသည်</translation>
 <translation id="5864419784173784555">အခြားဒေါင်းလုဒ်လုပ်ခြင်းကို စောင့်နေသည်…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
index b605641..93f31f5a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
@@ -658,6 +658,7 @@
 <translation id="5854790677617711513">३० दिनभन्दा पुरानो</translation>
 <translation id="5858741533101922242">Chrome ले ब्लुटुथ एडाप्टरलाई सक्रिय गर्न सकेन</translation>
 <translation id="5860033963881614850">बन्द</translation>
+<translation id="5860491529813859533">सक्रिय गर्नुहोस्</translation>
 <translation id="5862731021271217234">आफ्ना अन्य यन्त्रहरूबाट आफ्ना ट्याबहरू प्राप्त गर्न सिंक गर्ने सुविधा सक्रिय गर्नुहोस्</translation>
 <translation id="5864174910718532887">विवरणहरू: साइटको नामअनुसार क्रमबद्ध गरिएको</translation>
 <translation id="5864419784173784555">अर्को डाउनलोडको प्रतीक्षा गर्दै…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
index 776b713..8997c208 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Ouder dan 30 dagen</translation>
 <translation id="5858741533101922242">Chrome kan de Bluetooth-adapter niet inschakelen</translation>
 <translation id="5860033963881614850">Uit</translation>
+<translation id="5860491529813859533">Inschakelen</translation>
 <translation id="5862731021271217234">Schakel synchronisatie in om de tabbladen van je andere apparaten te bekijken</translation>
 <translation id="5864174910718532887">Details: gesorteerd op sitenaam</translation>
 <translation id="5864419784173784555">Wachten op andere download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
index 29aec53..74fcfde 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Eldre enn 30 dager</translation>
 <translation id="5858741533101922242">Chrome kan ikke slå på Bluetooth-adapteren</translation>
 <translation id="5860033963881614850">Av</translation>
+<translation id="5860491529813859533">Slå på</translation>
 <translation id="5862731021271217234">For å få fanene dine fra de andre enhetene du bruker, slå på synkronisering</translation>
 <translation id="5864174910718532887">Informasjon: Sortert etter nettstedsnavn</translation>
 <translation id="5864419784173784555">Venter på en annen nedlasting …</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
index a0dfc24..a74305a4 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 ଦିନରୁ ଅଧିକ ପୁରୁଣା</translation>
 <translation id="5858741533101922242">ବ୍ଲୁଟୁଥ୍‍ ଆଡପ୍ଟର୍ ଚାଲୁ କରିବାରେ Chrome ଅକ୍ଷମ ଅଟେ</translation>
 <translation id="5860033963881614850">ବନ୍ଦ ଅଛି</translation>
+<translation id="5860491529813859533">ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="5862731021271217234">ଆପଣଙ୍କର ଅନ୍ୟ ଡିଭାଇସ୍‌ରୁ ନିଜର ଟାବ୍ଗୁଡ଼ିକୁ ପ୍ରାପ୍ତ କରିବାକୁ, ସିଙ୍କ୍‌କୁ ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="5864174910718532887">ବିବରଣୀ: ସାଇଟ୍‌ ନାମ ଅନୁଯାୟୀ କରାଯାଇଛି</translation>
 <translation id="5864419784173784555">ଆଉ ଏକ ଡାଉନ୍‍‍‍ଲୋଡ୍ ପାଇଁ ଅପେକ୍ଷାରତ…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
index df5e623..a5209047 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 ਦਿਨਾਂ ਤੋਂ ਜ਼ਿਆਦਾ ਪੁਰਾਣਾ</translation>
 <translation id="5858741533101922242">Chrome ਬਲੂਟੁੱਥ ਅਡਾਪਟਰ ਨੂੰ ਚਾਲੂ ਕਰਨ ਵਿੱਚ ਅਸਮਰੱਥ ਹੈ।</translation>
 <translation id="5860033963881614850">ਬੰਦ ਕਰੋ</translation>
+<translation id="5860491529813859533">ਚਾਲੂ ਕਰੋ</translation>
 <translation id="5862731021271217234">ਆਪਣੇ ਹੋਰ ਡੀਵਾਈਸਾਂ ਤੋਂ ਆਪਣੀਆਂ ਟੈਬਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ, ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="5864174910718532887">ਵੇਰਵੇ: ਸਾਈਟ ਨਾਮ ਮੁਤਾਬਕ ਕ੍ਰਮ-ਬੱਧ ਕੀਤਾ ਗਿਆ</translation>
 <translation id="5864419784173784555">ਕਿਸੇ ਹੋਰ ਡਾਊਨਲੋਡ ਵੱਲੋਂ ਨੈੱਟਵਰਕ ਦੀ ਉਡੀਕ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
index 1f0df26..36cdac1 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Sprzed ponad 30 dni</translation>
 <translation id="5858741533101922242">Chrome nie może włączyć adaptera Bluetooth</translation>
 <translation id="5860033963881614850">Wyłączone</translation>
+<translation id="5860491529813859533">Włącz</translation>
 <translation id="5862731021271217234">Aby korzystać z kart ze swoich innych urządzeń, włącz synchronizację</translation>
 <translation id="5864174910718532887">Szczegóły: posortowane według nazwy witryny</translation>
 <translation id="5864419784173784555">Czekam na inny plik do pobrania…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
index 9b2cd13..db63e9e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
@@ -660,6 +660,7 @@
 <translation id="5854790677617711513">Com mais de 30 dias</translation>
 <translation id="5858741533101922242">O Chrome não pôde ativar o adaptador Bluetooth</translation>
 <translation id="5860033963881614850">Desativado</translation>
+<translation id="5860491529813859533">Ativar</translation>
 <translation id="5862731021271217234">Para ver as guias dos seus outros dispositivos, ative a sincronização</translation>
 <translation id="5864174910718532887">Detalhes: classificados por nome do site</translation>
 <translation id="5864419784173784555">Aguardando outro download…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
index 4ab75a8..afed5cb 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Com mais de 30 dias</translation>
 <translation id="5858741533101922242">O Chrome não consegue ativar o adaptador Bluetooth</translation>
 <translation id="5860033963881614850">Desativado</translation>
+<translation id="5860491529813859533">Ativar</translation>
 <translation id="5862731021271217234">Para obter os separadores dos seus outros dispositivos, ative a sincronização.</translation>
 <translation id="5864174910718532887">Detalhes: ordenado por nome do site</translation>
 <translation id="5864419784173784555">A aguardar por outra transferência…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
index 7ce166f..6e0a781d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Mai vechi de 30 de zile</translation>
 <translation id="5858741533101922242">Chrome nu poate activa adaptorul Bluetooth</translation>
 <translation id="5860033963881614850">Dezactivat</translation>
+<translation id="5860491529813859533">Activează</translation>
 <translation id="5862731021271217234">Pentru a accesa filele de pe alte dispozitive, activează sincronizarea</translation>
 <translation id="5864174910718532887">Detalii: sortate după numele site-ului</translation>
 <translation id="5864419784173784555">Se așteaptă altă descărcare…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
index 2a2ad11..12d5e38 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Сохраненные более 30 дней назад</translation>
 <translation id="5858741533101922242">Не удалось включить адаптер Bluetooth</translation>
 <translation id="5860033963881614850">ВЫКЛ</translation>
+<translation id="5860491529813859533">Включить</translation>
 <translation id="5862731021271217234">Чтобы получить доступ к вкладкам на всех устройствах, включите синхронизацию.</translation>
 <translation id="5864174910718532887">Сортировка по названию сайта</translation>
 <translation id="5864419784173784555">Завершение предыдущего скачивания…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
index e68c9067b..f4e432ac 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">දින 30කට වඩා පැරණි</translation>
 <translation id="5858741533101922242">Chrome හට බ්ලූටූත් ඇඩප්ටරය ක්‍රියාත්මක කිරීමට නොහැකිය</translation>
 <translation id="5860033963881614850">අක්‍රීය</translation>
+<translation id="5860491529813859533">ක්‍රියාත්මක කරන්න</translation>
 <translation id="5862731021271217234">ඔබගේ වෙනත් උපාංගවලින් ඔබගේ පටිති ලබා ගැනීමට, සමමුහුර්තය ක්‍රියාත්මක කරන්න</translation>
 <translation id="5864174910718532887">විස්තර: අඩවි නාමය අනුව අනුපිළිවෙළට සකසා ඇත</translation>
 <translation id="5864419784173784555">වෙනත් බාගැනීමක් සඳහා රැඳෙමින්…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
index 45f55c7..bb25a05 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Staršie ako 30 dní</translation>
 <translation id="5858741533101922242">Chrome nedokáže zapnúť adaptér Bluetooth</translation>
 <translation id="5860033963881614850">Vypnuté</translation>
+<translation id="5860491529813859533">Zapnúť</translation>
 <translation id="5862731021271217234">Ak chcete získať karty zo svojich ostatných zariadení, zapnite synchronizáciu</translation>
 <translation id="5864174910718532887">Podrobnosti: zoradené podľa názvu webu</translation>
 <translation id="5864419784173784555">Čaká sa na ďalší sťahovaný súbor…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
index fac9f8b..8e7fe5d9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Starejše od 30 dni</translation>
 <translation id="5858741533101922242">Chrome ne more vklopiti vmesnika za Bluetooth</translation>
 <translation id="5860033963881614850">Izklopljeno</translation>
+<translation id="5860491529813859533">Vklopi</translation>
 <translation id="5862731021271217234">Če želite dostopati do zavihkov iz drugih naprav, vklopite sinhronizacijo</translation>
 <translation id="5864174910718532887">Podrobnosti: razvrščeno po imenu spletnega mesta</translation>
 <translation id="5864419784173784555">Čakanje na drug prenos …</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
index 7e54b03..579ca8e2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Më të vjetra se 30 ditë</translation>
 <translation id="5858741533101922242">Chrome nuk mund ta aktivizojë përshtatësin e Bluetooth-it</translation>
 <translation id="5860033963881614850">Çaktivizuar</translation>
+<translation id="5860491529813859533">Aktivizo</translation>
 <translation id="5862731021271217234">Për të marrë skedat e tua nga pajisjet e tjera, aktivizo sinkronizimin</translation>
 <translation id="5864174910718532887">Detajet: Renditur sipas emrit të sajtit</translation>
 <translation id="5864419784173784555">Në pritje të një shkarkimi tjetër…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
index 616ece4..a0dff6a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Старије од 30 дана</translation>
 <translation id="5858741533101922242">Chrome не може да укључи Bluetooth адаптер</translation>
 <translation id="5860033963881614850">Искључено</translation>
+<translation id="5860491529813859533">Укључи</translation>
 <translation id="5862731021271217234">Да би вам картице биле доступне на другим уређајима, укључите синхронизацију</translation>
 <translation id="5864174910718532887">Детаљи: сортирано према називу сајта</translation>
 <translation id="5864419784173784555">Чека се друго преузимање...</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
index ef967a40..8d530c2c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Äldre än 30 dagar</translation>
 <translation id="5858741533101922242">Det gick inte att aktivera Bluetooth-adaptern i Chrome</translation>
 <translation id="5860033963881614850">Av</translation>
+<translation id="5860491529813859533">Aktivera</translation>
 <translation id="5862731021271217234">Aktivera synkronisering om du vill ha samma flikar tillgängliga på alla enheter</translation>
 <translation id="5864174910718532887">Mer information: Sorterad efter webbplatsnamn</translation>
 <translation id="5864419784173784555">Väntar på nästa nedladdning …</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
index 24b5cbc..250a0e1 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Iliyohifadhiwa kwa zaidi ya siku 30</translation>
 <translation id="5858741533101922242">Chrome imeshindwa kuwasha adapta ya Bluetooth</translation>
 <translation id="5860033963881614850">Kimezimwa</translation>
+<translation id="5860491529813859533">Washa</translation>
 <translation id="5862731021271217234">Washa kipengele cha usawazishaji ili upate vichupo kutoka kwenye vifaa vyako vingine</translation>
 <translation id="5864174910718532887">Maelezo: Imepangwa kulingana na jina la tovuti</translation>
 <translation id="5864419784173784555">Inasubiri kipakuliwa kingine…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
index a1e8f63..9475692 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 நாட்களுக்கு முந்தையவை</translation>
 <translation id="5858741533101922242">Chrome ஆல் புளூடூத் அடாப்டரை இயக்க முடியவில்லை</translation>
 <translation id="5860033963881614850">ஆஃப்</translation>
+<translation id="5860491529813859533">இயக்கு</translation>
 <translation id="5862731021271217234">உங்கள் பிற சாதனங்களிலிருந்து தாவல்களைப் பெற, ஒத்திசைவை இயக்கவும்</translation>
 <translation id="5864174910718532887">விவரங்கள்: தளப் பெயரின்படி வரிசைப்படுத்தப்பட்டுள்ளன</translation>
 <translation id="5864419784173784555">வேறொரு பதிவிறக்கத்திற்காகக் காத்திருக்கிறது…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
index 7a5abc0c..dfffef9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 రోజుల కన్నా పాతవి</translation>
 <translation id="5858741533101922242">Chrome బ్లూటూత్ అడాప్టర్‌ను ఆన్ చేయలేకపోయింది</translation>
 <translation id="5860033963881614850">ఆఫ్ అయ్యింది</translation>
+<translation id="5860491529813859533">ఆన్ చేయండి</translation>
 <translation id="5862731021271217234">మీ ఇతర పరికరాలలో ఉన్న మీ అన్ని ట్యాబ్‌లను పొందాలనుకుంటే, సమకాలీకరణ ఎంపికను ఆన్ చేయాలి</translation>
 <translation id="5864174910718532887">వివరాలు: సైట్ పేరుతో క్రమీకరించబడ్డాయి</translation>
 <translation id="5864419784173784555">మరొక డౌన్‌లోడ్ కోసం వేచి ఉంది…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
index 973f35e..3252f7e15 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">เกิน 30 วัน</translation>
 <translation id="5858741533101922242">Chrome ไม่สามารถเปิดอะแดปเตอร์บลูทูธ</translation>
 <translation id="5860033963881614850">ปิด</translation>
+<translation id="5860491529813859533">เปิด</translation>
 <translation id="5862731021271217234">เปิดการซิงค์เพื่อรับแท็บจากอุปกรณ์เครื่องอื่นๆ ของคุณ</translation>
 <translation id="5864174910718532887">รายละเอียด: จัดเรียงตามชื่อเว็บไซต์</translation>
 <translation id="5864419784173784555">กำลังรอการดาวน์โหลดรายการอื่น…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
index b7ef2a6..40379263 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 günden daha eski</translation>
 <translation id="5858741533101922242">Chrome, Bluetooth adaptörünü açamıyor</translation>
 <translation id="5860033963881614850">Kapalı</translation>
+<translation id="5860491529813859533">Etkinleştir</translation>
 <translation id="5862731021271217234">Diğer cihazlarınızdaki sekmelerinize ulaşmak için senkronizasyonu etkinleştirin</translation>
 <translation id="5864174910718532887">Ayrıntılar: Site adına göre sıralı</translation>
 <translation id="5864419784173784555">Başka bir indirme işlemi bekleniyor…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
index d3445eb1..f0918e46 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Понад 30 днів тому</translation>
 <translation id="5858741533101922242">Chrome не може ввімкнути адаптер Bluetooth</translation>
 <translation id="5860033963881614850">Вимк.</translation>
+<translation id="5860491529813859533">Увімкнути</translation>
 <translation id="5862731021271217234">Щоб мати доступ до вкладок з інших пристроїв, увімкніть синхронізацію</translation>
 <translation id="5864174910718532887">Деталі: відсортовано за назвою сайту</translation>
 <translation id="5864419784173784555">Очікується інше завантаження…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
index 29ff8b7..29e9618 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 دن سے زیادہ پرانا</translation>
 <translation id="5858741533101922242">‏Chrome بلوٹوتھ اڈاپٹر آن کرنے سے قاصر ہے</translation>
 <translation id="5860033963881614850">آف</translation>
+<translation id="5860491529813859533">آن کریں</translation>
 <translation id="5862731021271217234">اپنے دیگر آلات سے اپنے ٹیبز حاصل کرنے کیلئے، سِنک کو آن کریں</translation>
 <translation id="5864174910718532887">تفصیلات: سائٹ کے نام کے لحاظ سے ترتیب دیا گیا</translation>
 <translation id="5864419784173784555">ایک اور ڈاؤن لوڈ کا منتظر…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
index 90ced4f..033eb6d2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 kundan oldin saqlanganlar</translation>
 <translation id="5858741533101922242">Bluetooth adapterini yoqib bo‘lmadi</translation>
 <translation id="5860033963881614850">O‘chiq</translation>
+<translation id="5860491529813859533">Yoqish</translation>
 <translation id="5862731021271217234">Boshqa qurilmalardagi brauzer sahifalarini ko‘rish uchun sinxronizatsiyani yoqing</translation>
 <translation id="5864174910718532887">Tafsilot: Saytlar nomi asosida saralandi</translation>
 <translation id="5864419784173784555">Oldingi yuklanma yakuni kutilmoqda…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
index 975bdcc..1e6f399 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Đã tồn tại hơn 30 ngày</translation>
 <translation id="5858741533101922242">Chrome không thể bật bộ điều hợp Bluetooth</translation>
 <translation id="5860033963881614850">Tắt</translation>
+<translation id="5860491529813859533">Bật</translation>
 <translation id="5862731021271217234">Để sử dụng các tab từ những thiết bị khác, hãy bật tính năng đồng bộ hóa</translation>
 <translation id="5864174910718532887">Thông tin chi tiết: Sắp xếp theo tên trang web</translation>
 <translation id="5864419784173784555">Đang chờ đến lần tải xuống tiếp theo…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
index e24a51b..a494d37 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">30 天之前的</translation>
 <translation id="5858741533101922242">Chrome 无法开启蓝牙适配器</translation>
 <translation id="5860033963881614850">关闭</translation>
+<translation id="5860491529813859533">启用</translation>
 <translation id="5862731021271217234">要访问您在其他设备上打开的标签页,请开启同步功能</translation>
 <translation id="5864174910718532887">详细信息:按网站名称排序</translation>
 <translation id="5864419784173784555">正在等待完成另一项下载…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
index 1d3740e5..6b94bb0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">超過 30 天</translation>
 <translation id="5858741533101922242">Chrome 無法開啟藍牙適配器</translation>
 <translation id="5860033963881614850">關閉</translation>
+<translation id="5860491529813859533">開啟</translation>
 <translation id="5862731021271217234">如要取得其他裝置上的分頁,請開啟同步處理功能</translation>
 <translation id="5864174910718532887">詳情:依網站名稱排序</translation>
 <translation id="5864419784173784555">正在等待其他下載程序完成…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
index 4f9b74bc..21ff9da 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">超過 30 天前</translation>
 <translation id="5858741533101922242">Chrome 無法開啟藍牙轉接器</translation>
 <translation id="5860033963881614850">關閉</translation>
+<translation id="5860491529813859533">啟用</translation>
 <translation id="5862731021271217234">如要存取你在其他裝置上開啟的分頁,請開啟同步處理功能</translation>
 <translation id="5864174910718532887">詳細資料:依網站名稱排序</translation>
 <translation id="5864419784173784555">正在等待其他下載程序完成…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
index 5ea551c..1417c157 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
@@ -659,6 +659,7 @@
 <translation id="5854790677617711513">Kudala kunezinsuku ezingu-30</translation>
 <translation id="5858741533101922242">I-Chrome ayikwazi ukuvula i-adaptha ye-Bluetooth</translation>
 <translation id="5860033963881614850">Valiwe</translation>
+<translation id="5860491529813859533">Vula</translation>
 <translation id="5862731021271217234">Ukuze uthole amathebhu akho kusukela kwamanye amadivayisi akho, vula ukuvumelanisa</translation>
 <translation id="5864174910718532887">Imininingwane: Ihlungwe ngegama lesayithi</translation>
 <translation id="5864419784173784555">Ilindele okunye ukulandwa…</translation>
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
index 4b845d94..a873754 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
@@ -96,6 +96,7 @@
     const std::string& extension_id) {
   DCHECK(CanDoShowAppInfoFlow());
 
+  // TODO(crbug.com/1029221): Make DoShowAppInfoFlow extensions-agnostic.
   const extensions::Extension* extension = GetExtension(profile, extension_id);
   DCHECK(extension);
 
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index 442ec40..7e0237b 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -476,20 +476,20 @@
   EXPECT_EQ(page_break_sync_item->item_type,
             sync_pb::AppListSpecifics::TYPE_PAGE_BREAK);
 
-  // Since internal apps are added by default, we'll use the camera and the
-  // settings apps to test the ordering.
+  // Since internal apps are added by default, we'll use the settings apps to
+  // test the ordering.
   auto* settings_app_sync_item = GetSyncItem(ash::kInternalAppIdSettings);
-  auto* camera_app_sync_item = GetSyncItem(ash::kInternalAppIdCamera);
+  auto* hosted_app_sync_item = GetSyncItem(kHostedAppId);
   ASSERT_TRUE(settings_app_sync_item);
-  ASSERT_TRUE(camera_app_sync_item);
+  ASSERT_TRUE(hosted_app_sync_item);
 
-  // The default page break should be between the camera app, and the settings
-  // app; i.e. the camera app is in the first page, and the settings app is in
+  // The default page break should be between the hosted app, and the settings
+  // app; i.e. the hosted app is in the first page, and the settings app is in
   // the second page.
   EXPECT_TRUE(page_break_sync_item->item_ordinal.LessThan(
       settings_app_sync_item->item_ordinal));
   EXPECT_TRUE(page_break_sync_item->item_ordinal.GreaterThan(
-      camera_app_sync_item->item_ordinal));
+      hosted_app_sync_item->item_ordinal));
 }
 
 TEST_F(AppListSyncableServiceTest, InitialMerge_BadData) {
@@ -925,7 +925,7 @@
   EXPECT_FALSE(GetSyncItem(extension_misc::kYoutubeAppId));
   // Attributes transfer from non-existing app fails.
   EXPECT_FALSE(app_list_syncable_service()->TransferItemAttributes(
-      extension_misc::kCameraAppId, extension_misc::kYoutubeAppId));
+      extension_misc::kCameraAppDevId, extension_misc::kYoutubeAppId));
 
   // Now Chrome app attributes match Webstore app.
   EXPECT_TRUE(AreAllAppAtributesEqualInAppList(webstore_item, chrome_item));
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
index e370e74..5f64ed9 100644
--- a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
+++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
@@ -6,6 +6,8 @@
 
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -14,7 +16,9 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_context_menu.h"
 #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h"
 #include "chrome/browser/ui/app_list/extension_app_context_menu.h"
+#include "chrome/browser/ui/app_list/web_app_context_menu.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
+#include "chrome/common/chrome_features.h"
 
 // static
 const char AppServiceAppItem::kItemType[] = "AppServiceAppItem";
@@ -47,8 +51,16 @@
       return std::make_unique<CrostiniAppContextMenu>(profile, app_id,
                                                       controller);
 
-    case apps::mojom::AppType::kExtension:
     case apps::mojom::AppType::kWeb:
+      if (base::FeatureList::IsEnabled(
+              features::kDesktopPWAsWithoutExtensions)) {
+        return std::make_unique<app_list::WebAppContextMenu>(
+            delegate, profile, app_id, controller);
+      }
+      // Otherwise deliberately fall through to fallback on Bookmark Apps.
+      FALLTHROUGH;
+
+    case apps::mojom::AppType::kExtension:
       return std::make_unique<app_list::ExtensionAppContextMenu>(
           delegate, profile, app_id, controller, is_platform_app);
 
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index c0c7ad6..a282e08 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -96,7 +96,6 @@
 
 constexpr char const* kAppIdsHiddenInLauncher[] = {
     kAndroidClockAppId,   kSettingsAppId,     kAndroidFilesAppId,
-    kCameraAppId,         kLegacyCameraAppId, kCameraMigrationAppId,
     kAndroidContactsAppId};
 
 // Returns true if |event_flags| came from a mouse or touch event.
@@ -220,15 +219,12 @@
 constexpr char kSettingsAppPackage[] = "com.android.settings";
 
 // App IDs, kept in sorted order.
-const char kCameraAppId[] = "goamfaniemdfcajgcmmflhchgkmbngka";
-const char kCameraMigrationAppId[] = "ngmkobaiicipbagcngcmilfkhejlnfci";
 const char kGmailAppId[] = "hhkfkjpmacfncmbapfohfocpjpdnobjg";
 const char kGoogleCalendarAppId[] = "decaoeahkmjpajbmlbpogjjkjbjokeed";
 const char kGoogleDuoAppId[] = "djkcbcmkefiiphjkonbeknmcgiheajce";
 const char kGoogleMapsAppId[] = "gmhipfhgnoelkiiofcnimehjnpaejiel";
 const char kGooglePhotosAppId[] = "fdbkkojdbojonckghlanfaopfakedeca";
 const char kInfinitePainterAppId[] = "afihfgfghkmdmggakhkgnfhlikhdpima";
-const char kLegacyCameraAppId[] = "obfofkigjfamlldmipdegnjlcpincibc";
 const char kLightRoomAppId[] = "fpegfnbgomakooccabncdaelhfppceni";
 const char kPlayBooksAppId[] = "cafegjnmmjpfibnlddppihpnkbkgicbg";
 const char kPlayGamesAppId[] = "nplnnjkbeijcggmpdcecpabgbjgeiedc";
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.h b/chrome/browser/ui/app_list/arc/arc_app_utils.h
index 2e946fb..114c9e63 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.h
@@ -31,7 +31,6 @@
 extern const char kPlayStorePackage[];
 extern const char kSettingsAppDomainUrlActivity[];
 
-extern const char kCameraAppId[];
 extern const char kCameraMigrationAppId[];
 extern const char kGmailAppId[];
 extern const char kGoogleCalendarAppId[];
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc
index 35960e7..937d47507 100644
--- a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc
+++ b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.cc
@@ -24,55 +24,41 @@
 using syncer::ModelTypeControllerDelegate;
 using syncer::SyncableServiceBasedBridge;
 
-// static
-std::unique_ptr<ArcPackageSyncModelTypeController>
-ArcPackageSyncModelTypeController::Create(
+ArcPackageSyncModelTypeController::ArcPackageSyncModelTypeController(
     syncer::OnceModelTypeStoreFactory store_factory,
     base::WeakPtr<syncer::SyncableService> syncable_service,
     const base::RepeatingClosure& dump_stack,
     syncer::SyncService* sync_service,
-    Profile* profile) {
-  auto bridge = std::make_unique<SyncableServiceBasedBridge>(
-      syncer::ARC_PACKAGE, std::move(store_factory),
-      std::make_unique<ClientTagBasedModelTypeProcessor>(syncer::ARC_PACKAGE,
-                                                         dump_stack),
-      syncable_service.get());
-  ModelTypeControllerDelegate* delegate =
-      bridge->change_processor()->GetControllerDelegate().get();
-  auto delegate_for_full_sync_mode =
-      std::make_unique<ForwardingModelTypeControllerDelegate>(delegate);
-
-  if (chromeos::features::IsSplitSettingsSyncEnabled()) {
-    // Runs in transport-mode and full-sync mode, sharing the bridge's delegate.
-    return base::WrapUnique(new ArcPackageSyncModelTypeController(
-        std::move(bridge), std::move(delegate_for_full_sync_mode),
-        /*delegate_for_transport_mode=*/
-        std::make_unique<ForwardingModelTypeControllerDelegate>(delegate),
-        sync_service, profile));
-  } else {
-    // Only runs in full-sync mode.
-    return base::WrapUnique(new ArcPackageSyncModelTypeController(
-        std::move(bridge), std::move(delegate_for_full_sync_mode),
-        /*delegate_for_transport_mode=*/
-        nullptr, sync_service, profile));
-  }
-}
-
-ArcPackageSyncModelTypeController::ArcPackageSyncModelTypeController(
-    std::unique_ptr<syncer::ModelTypeSyncBridge> bridge,
-    std::unique_ptr<ModelTypeControllerDelegate> delegate_for_full_sync_mode,
-    std::unique_ptr<ModelTypeControllerDelegate> delegate_for_transport_mode,
-    syncer::SyncService* sync_service,
     Profile* profile)
-    : ModelTypeController(syncer::ARC_PACKAGE,
-                          std::move(delegate_for_full_sync_mode),
-                          std::move(delegate_for_transport_mode)),
-      bridge_(std::move(bridge)),
+    : ModelTypeController(syncer::ARC_PACKAGE),
+      bridge_(std::make_unique<SyncableServiceBasedBridge>(
+          syncer::ARC_PACKAGE,
+          std::move(store_factory),
+          std::make_unique<ClientTagBasedModelTypeProcessor>(
+              syncer::ARC_PACKAGE,
+              dump_stack),
+          syncable_service.get())),
       sync_service_(sync_service),
       profile_(profile),
       arc_prefs_(ArcAppListPrefs::Get(profile)) {
   DCHECK(arc_prefs_);
   DCHECK(profile_);
+  ModelTypeControllerDelegate* delegate =
+      bridge_->change_processor()->GetControllerDelegate().get();
+  auto delegate_for_full_sync_mode =
+      std::make_unique<ForwardingModelTypeControllerDelegate>(delegate);
+
+  if (chromeos::features::IsSplitSettingsSyncEnabled()) {
+    // Runs in transport-mode and full-sync mode, sharing the bridge's delegate.
+    InitModelTypeController(
+        std::move(delegate_for_full_sync_mode),
+        /*delegate_for_transport_mode=*/
+        std::make_unique<ForwardingModelTypeControllerDelegate>(delegate));
+  } else {
+    // Only runs in full-sync mode.
+    InitModelTypeController(std::move(delegate_for_full_sync_mode),
+                            /*delegate_for_transport_mode=*/nullptr);
+  }
 
   arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
   if (arc_session_manager) {
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h
index b79e8375..92fc14b 100644
--- a/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h
+++ b/chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h
@@ -33,7 +33,7 @@
       public arc::ArcSessionManager::Observer {
  public:
   // |dump_stack| is called when an unrecoverable error occurs.
-  static std::unique_ptr<ArcPackageSyncModelTypeController> Create(
+  ArcPackageSyncModelTypeController(
       syncer::OnceModelTypeStoreFactory store_factory,
       base::WeakPtr<syncer::SyncableService> syncable_service,
       const base::RepeatingClosure& dump_stack,
@@ -53,15 +53,6 @@
   void OnArcInitialStart() override;
 
  private:
-  ArcPackageSyncModelTypeController(
-      std::unique_ptr<syncer::ModelTypeSyncBridge> bridge,
-      std::unique_ptr<syncer::ModelTypeControllerDelegate>
-          delegate_for_full_sync_mode,
-      std::unique_ptr<syncer::ModelTypeControllerDelegate>
-          delegate_for_transport_mode,
-      syncer::SyncService* sync_service,
-      Profile* profile);
-
   void OnOsSyncFeaturePrefChanged();
 
   std::unique_ptr<syncer::ModelTypeSyncBridge> bridge_;
diff --git a/chrome/browser/ui/app_list/extension_app_utils.cc b/chrome/browser/ui/app_list/extension_app_utils.cc
index 90cce9b..efd50666 100644
--- a/chrome/browser/ui/app_list/extension_app_utils.cc
+++ b/chrome/browser/ui/app_list/extension_app_utils.cc
@@ -22,7 +22,6 @@
 namespace {
 
 constexpr char const* kAppIdsHiddenInLauncher[] = {
-    extension_misc::kChromeCameraAppId,
     chromeos::default_web_apps::kReleaseNotesAppId};
 
 }  // namespace
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
index 01c3dcad4..44103e1 100644
--- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
+++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
@@ -33,7 +33,6 @@
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
-#include "chrome/browser/ui/webui/chromeos/camera/camera_ui.h"
 #include "chrome/browser/ui/webui/chromeos/login/discover/discover_window_manager.h"
 #include "chrome/browser/web_applications/system_web_app_manager.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
@@ -91,18 +90,6 @@
   internal_app_list->insert(internal_app_list->begin(),
                             internal_app_list_static->begin(),
                             internal_app_list_static->end());
-
-  const bool add_camera_app = get_all || !profile->IsGuestSession();
-  if (add_camera_app && !chromeos::CameraUI::IsEnabled()) {
-    internal_app_list->push_back({ash::kInternalAppIdCamera,
-                                  IDS_INTERNAL_APP_CAMERA, IDR_CAMERA_LOGO_192,
-                                  /*recommendable=*/true,
-                                  /*searchable=*/true,
-                                  /*show_in_launcher=*/true,
-                                  apps::BuiltInAppName::kCamera,
-                                  /*searchable_string_resource_id=*/0});
-  }
-
   const bool add_discover_app =
       get_all || !chromeos::ProfileHelper::IsEphemeralUserProfile(profile);
   if (base::FeatureList::IsEnabled(chromeos::features::kDiscoverApp) &&
@@ -182,25 +169,6 @@
   return app ? app->icon_resource_id : 0;
 }
 
-void OpenChromeCameraApp(Profile* profile, int event_flags) {
-  const extensions::ExtensionRegistry* registry =
-      extensions::ExtensionRegistry::Get(profile);
-  const extensions::Extension* extension =
-      registry->GetInstalledExtension(extension_misc::kChromeCameraAppId);
-  if (extension) {
-    AppListClientImpl* controller = AppListClientImpl::GetInstance();
-    apps::AppLaunchParams params = CreateAppLaunchParamsWithEventFlags(
-        profile, extension, event_flags,
-        apps::mojom::AppLaunchSource::kSourceAppLauncher,
-        controller->GetAppListDisplayId());
-    params.launch_id = ash::ShelfID(extension->id()).launch_id;
-    apps::LaunchService::Get(profile)->OpenApplication(params);
-    VLOG(1) << "Launched CCA.";
-  } else {
-    LOG(ERROR) << "CCA not found on device";
-  }
-}
-
 void OpenInternalApp(const std::string& app_id,
                      Profile* profile,
                      int event_flags) {
@@ -208,21 +176,6 @@
     ash::ToggleKeyboardShortcutViewer();
   } else if (app_id == ash::kInternalAppIdSettings) {
     chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(profile);
-  } else if (app_id == ash::kInternalAppIdCamera) {
-    // In case Camera app is already running, use it to prevent appearing double
-    // apps, from Chrome and Android domains.
-    const ash::ShelfID shelf_id(ash::kInternalAppIdCamera);
-    AppWindowLauncherItemController* const app_controller =
-        ChromeLauncherController::instance()
-            ->shelf_model()
-            ->GetAppWindowLauncherItemController(shelf_id);
-    if (app_controller) {
-      VLOG(1)
-          << "Camera app controller already exists, activating existing app.";
-      app_controller->ActivateIndexedApp(0 /* index */);
-    } else {
-      OpenChromeCameraApp(profile, event_flags);
-    }
   } else if (app_id == ash::kInternalAppIdDiscover) {
     base::RecordAction(base::UserMetricsAction("ShowDiscover"));
     chromeos::DiscoverWindowManager::GetInstance()
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
index 6099964..deb21257 100644
--- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -384,16 +384,14 @@
   prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(5));
   // Allow async callbacks to run.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
-            RunQuery(""));
+  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings", RunQuery(""));
 
   prefs->SetLastLaunchTime(kHostedAppId, base::Time::FromInternalValue(5));
   prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(10));
   prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(20));
   // Allow async callbacks to run.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ("Packaged App 2,Packaged App 1,Hosted App,Settings,Camera",
-            RunQuery(""));
+  EXPECT_EQ("Packaged App 2,Packaged App 1,Hosted App,Settings", RunQuery(""));
 
   // Times in the future should just be handled as highest priority.
   prefs->SetLastLaunchTime(kHostedAppId,
@@ -402,8 +400,7 @@
   prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(5));
   // Allow async callbacks to run.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
-            RunQuery(""));
+  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings", RunQuery(""));
 }
 
 TEST_F(AppSearchProviderTest, FetchRecommendationsWithContinueReading) {
@@ -470,7 +467,7 @@
     session_tracker()->GetSession(kForeignSessionTag3)->device_type =
         sync_pb::SyncEnums::TYPE_PHONE;
 
-    EXPECT_EQ("title2,Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("title2,Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -494,7 +491,7 @@
     session_tracker()->GetSession(kLocalSessionTag)->device_type =
         sync_pb::SyncEnums::TYPE_PHONE;
 
-    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -519,7 +516,7 @@
     session_tracker()->GetSession(kForeignSessionTag1)->device_type =
         sync_pb::SyncEnums::TYPE_PHONE;
 
-    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -544,7 +541,7 @@
     session_tracker()->GetSession(kForeignSessionTag1)->device_type =
         sync_pb::SyncEnums::TYPE_TABLET;
 
-    EXPECT_EQ("title1,Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("title1,Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -569,7 +566,7 @@
     session_tracker()->GetSession(kForeignSessionTag1)->device_type =
         sync_pb::SyncEnums::TYPE_CROS;
 
-    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -594,7 +591,7 @@
     session_tracker()->GetSession(kForeignSessionTag1)->device_type =
         sync_pb::SyncEnums::TYPE_CROS;
 
-    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
+    EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings",
               RunQueryNotSortingByRelevance(""));
   }
 
@@ -632,8 +629,7 @@
   prefs->SetLastLaunchTime(kHostedAppId, base::Time::Now());
   prefs->SetLastLaunchTime(kPackagedApp1Id, base::Time::FromInternalValue(0));
   prefs->SetLastLaunchTime(kPackagedApp2Id, base::Time::FromInternalValue(0));
-  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings,Camera",
-            RunQuery(""));
+  EXPECT_EQ("Hosted App,Packaged App 1,Packaged App 2,Settings", RunQuery(""));
 }
 
 TEST_F(AppSearchProviderTest, FilterDuplicate) {
diff --git a/chrome/browser/ui/app_list/web_app_context_menu.cc b/chrome/browser/ui/app_list/web_app_context_menu.cc
new file mode 100644
index 0000000..f2e45b9
--- /dev/null
+++ b/chrome/browser/ui/app_list/web_app_context_menu.cc
@@ -0,0 +1,168 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/app_list/web_app_context_menu.h"
+
+#include "ash/public/cpp/app_menu_constants.h"
+#include "base/bind.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/app_context_menu_delegate.h"
+#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
+#include "chrome/browser/web_applications/components/app_registry_controller.h"
+#include "chrome/browser/web_applications/components/install_finalizer.h"
+#include "chrome/browser/web_applications/components/web_app_constants.h"
+#include "chrome/browser/web_applications/system_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "content/public/common/context_menu_params.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/controls/menu/menu_config.h"
+#include "ui/views/vector_icons.h"
+
+namespace app_list {
+
+namespace {
+
+web_app::DisplayMode ConvertUseLaunchTypeCommandToDisplayMode(int command_id) {
+  DCHECK(command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START &&
+         command_id < ash::USE_LAUNCH_TYPE_COMMAND_END);
+  switch (command_id) {
+    case ash::USE_LAUNCH_TYPE_REGULAR:
+      return web_app::DisplayMode::kBrowser;
+    case ash::USE_LAUNCH_TYPE_WINDOW:
+      return web_app::DisplayMode::kStandalone;
+    case ash::USE_LAUNCH_TYPE_PINNED:
+    case ash::USE_LAUNCH_TYPE_FULLSCREEN:
+    default:
+      return web_app::DisplayMode::kUndefined;
+  }
+}
+
+}  // namespace
+
+WebAppContextMenu::WebAppContextMenu(AppContextMenuDelegate* delegate,
+                                     Profile* profile,
+                                     const std::string& app_id,
+                                     AppListControllerDelegate* controller)
+    : AppContextMenu(delegate, profile, app_id, controller) {}
+
+WebAppContextMenu::~WebAppContextMenu() = default;
+
+int WebAppContextMenu::GetLaunchStringId() const {
+  bool launch_in_window = IsCommandIdChecked(ash::USE_LAUNCH_TYPE_WINDOW);
+  return launch_in_window ? IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW
+                          : IDS_APP_LIST_CONTEXT_MENU_NEW_TAB;
+}
+
+void WebAppContextMenu::GetMenuModel(GetMenuModelCallback callback) {
+  if (!GetProvider().registrar().IsInstalled(app_id())) {
+    std::move(callback).Run(nullptr);
+    return;
+  }
+
+  AppContextMenu::GetMenuModel(std::move(callback));
+}
+
+void WebAppContextMenu::BuildMenu(ui::SimpleMenuModel* menu_model) {
+  const bool is_system_web_app =
+      GetProvider().system_web_app_manager().IsSystemWebApp(app_id());
+
+  if (!is_system_web_app)
+    CreateOpenNewSubmenu(menu_model);
+
+  AppContextMenu::BuildMenu(menu_model);
+
+  AddContextMenuOption(menu_model, ash::UNINSTALL, IDS_APP_LIST_UNINSTALL_ITEM);
+
+  if (controller()->CanDoShowAppInfoFlow() && !is_system_web_app) {
+    AddContextMenuOption(menu_model, ash::SHOW_APP_INFO,
+                         IDS_APP_CONTEXT_MENU_SHOW_INFO);
+  }
+}
+
+base::string16 WebAppContextMenu::GetLabelForCommandId(int command_id) const {
+  if (command_id == ash::LAUNCH_NEW)
+    return l10n_util::GetStringUTF16(GetLaunchStringId());
+
+  return AppContextMenu::GetLabelForCommandId(command_id);
+}
+
+const gfx::VectorIcon* WebAppContextMenu::GetVectorIconForCommandId(
+    int command_id) const {
+  if (command_id == ash::LAUNCH_NEW)
+    return &GetMenuItemVectorIcon(ash::LAUNCH_NEW, GetLaunchStringId());
+
+  return AppContextMenu::GetVectorIconForCommandId(command_id);
+}
+
+bool WebAppContextMenu::IsItemForCommandIdDynamic(int command_id) const {
+  return command_id == ash::LAUNCH_NEW ||
+         AppContextMenu::IsItemForCommandIdDynamic(command_id);
+}
+
+bool WebAppContextMenu::IsCommandIdChecked(int command_id) const {
+  if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START &&
+      command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) {
+    web_app::DisplayMode effective_display_mode =
+        GetProvider().registrar().GetAppEffectiveDisplayMode(app_id());
+    return effective_display_mode != web_app::DisplayMode::kUndefined &&
+           effective_display_mode ==
+               ConvertUseLaunchTypeCommandToDisplayMode(command_id);
+  }
+  return AppContextMenu::IsCommandIdChecked(command_id);
+}
+
+bool WebAppContextMenu::IsCommandIdEnabled(int command_id) const {
+  if (command_id == ash::UNINSTALL) {
+    return GetProvider().install_finalizer().CanUserUninstallExternalApp(
+        app_id());
+  }
+  return AppContextMenu::IsCommandIdEnabled(command_id);
+}
+
+void WebAppContextMenu::ExecuteCommand(int command_id, int event_flags) {
+  if (command_id == ash::LAUNCH_NEW) {
+    delegate()->ExecuteLaunchCommand(event_flags);
+  } else if (command_id == ash::SHOW_APP_INFO) {
+    controller()->DoShowAppInfoFlow(profile(), app_id());
+  } else if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START &&
+             command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) {
+    // Web apps can only toggle between kStandalone and kBrowser.
+    web_app::DisplayMode user_display_mode =
+        ConvertUseLaunchTypeCommandToDisplayMode(command_id);
+    if (user_display_mode != web_app::DisplayMode::kUndefined) {
+      GetProvider().registry_controller().SetAppUserDisplayMode(
+          app_id(), user_display_mode);
+    }
+  } else if (command_id == ash::UNINSTALL) {
+    controller()->UninstallApp(profile(), app_id());
+  } else {
+    AppContextMenu::ExecuteCommand(command_id, event_flags);
+  }
+}
+
+void WebAppContextMenu::CreateOpenNewSubmenu(ui::SimpleMenuModel* menu_model) {
+  // Touchable app context menus use an actionable submenu for LAUNCH_NEW.
+  const int kGroupId = 1;
+  open_new_submenu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
+  open_new_submenu_model_->AddRadioItemWithStringId(
+      ash::USE_LAUNCH_TYPE_REGULAR, IDS_APP_LIST_CONTEXT_MENU_NEW_TAB,
+      kGroupId);
+  open_new_submenu_model_->AddRadioItemWithStringId(
+      ash::USE_LAUNCH_TYPE_WINDOW, IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW,
+      kGroupId);
+  menu_model->AddActionableSubmenuWithStringIdAndIcon(
+      ash::LAUNCH_NEW, GetLaunchStringId(), open_new_submenu_model_.get(),
+      GetMenuItemVectorIcon(ash::LAUNCH_NEW, GetLaunchStringId()));
+}
+
+web_app::WebAppProvider& WebAppContextMenu::GetProvider() const {
+  auto* provider = web_app::WebAppProvider::Get(profile());
+  DCHECK(provider);
+  return *provider;
+}
+
+}  // namespace app_list
diff --git a/chrome/browser/ui/app_list/web_app_context_menu.h b/chrome/browser/ui/app_list/web_app_context_menu.h
new file mode 100644
index 0000000..f03dad29
--- /dev/null
+++ b/chrome/browser/ui/app_list/web_app_context_menu.h
@@ -0,0 +1,64 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_WEB_APP_CONTEXT_MENU_H_
+#define CHROME_BROWSER_UI_APP_LIST_WEB_APP_CONTEXT_MENU_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/ui/app_list/app_context_menu.h"
+
+class AppListControllerDelegate;
+class Profile;
+
+namespace web_app {
+class WebAppProvider;
+}
+
+namespace app_list {
+
+class AppContextMenuDelegate;
+
+class WebAppContextMenu : public AppContextMenu {
+ public:
+  WebAppContextMenu(AppContextMenuDelegate* delegate,
+                    Profile* profile,
+                    const std::string& app_id,
+                    AppListControllerDelegate* controller);
+  ~WebAppContextMenu() override;
+
+  // Returns the string id based on launch type.
+  int GetLaunchStringId() const;
+
+  // AppContextMenu overrides:
+  void GetMenuModel(GetMenuModelCallback callback) override;
+  void BuildMenu(ui::SimpleMenuModel* menu_model) override;
+
+  // ui::SimpleMenuModel::Delegate overrides:
+  base::string16 GetLabelForCommandId(int command_id) const override;
+  const gfx::VectorIcon* GetVectorIconForCommandId(
+      int command_id) const override;
+  bool IsItemForCommandIdDynamic(int command_id) const override;
+  bool IsCommandIdChecked(int command_id) const override;
+  bool IsCommandIdEnabled(int command_id) const override;
+  void ExecuteCommand(int command_id, int event_flags) override;
+
+ private:
+  // Creates the actionable submenu for LAUNCH_NEW.
+  void CreateOpenNewSubmenu(ui::SimpleMenuModel* menu_model);
+
+  web_app::WebAppProvider& GetProvider() const;
+
+  // The MenuModel used to control LAUNCH_NEW's icon, label, and
+  // execution when touchable app context menus are enabled.
+  std::unique_ptr<ui::SimpleMenuModel> open_new_submenu_model_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebAppContextMenu);
+};
+
+}  // namespace app_list
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_WEB_APP_CONTEXT_MENU_H_
diff --git a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
index 0ec85f0..3d467fa 100644
--- a/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
+++ b/chrome/browser/ui/ash/assistant/proactive_suggestions_client_impl.cc
@@ -18,7 +18,7 @@
 // Helpers ---------------------------------------------------------------------
 
 syncer::SyncService* GetSyncService(Profile* profile) {
-  return profile->IsSyncAllowed()
+  return ProfileSyncServiceFactory::IsSyncAllowed(profile)
              ? ProfileSyncServiceFactory::GetForProfile(profile)
              : nullptr;
 }
diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
index 87a838b..f54ef538 100644
--- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc
+++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
@@ -60,7 +60,7 @@
                                           extension_misc::kGoogleSheetsAppId,
                                           extension_misc::kGoogleSlidesAppId,
                                           extension_misc::kFilesManagerAppId,
-                                          ash::kInternalAppIdCamera,
+                                          extension_misc::kCameraAppId,
                                           extension_misc::kGooglePhotosAppId,
                                           arc::kPlayStoreAppId};
 
@@ -68,6 +68,14 @@
 const char kDefaultPinnedApps7AppsKey[] = "7apps";
 const char kDefaultPinnedApps10AppsKey[] = "10apps";
 
+bool IsLegacyCameraAppId(const std::string& app_id) {
+  return app_id ==
+             "ngmkobaiicipbagcngcmilfkhejlnfci" ||  // Migration Camera App.
+         app_id == "goamfaniemdfcajgcmmflhchgkmbngka" ||  // Google Camera App.
+         app_id == "obfofkigjfamlldmipdegnjlcpincibc" ||  // Legacy Camera App.
+         app_id == "iniodglblcgmngkgdipeiclkdjjpnlbn";  // Internal Camera App.
+}
+
 bool IsAppIdArcPackage(const std::string& app_id) {
   return app_id.find('.') != app_id.npos;
 }
@@ -439,44 +447,53 @@
   // not.
   std::set<std::string> pins_from_sync_raw;
 
-  // Check that the camera app was pinned by a real app id or mapped internal
-  // app id.
-  bool has_pinned_camera_app = false;
+  bool has_camera_app = false;
+  syncer::StringOrdinal legacy_camera_pinned_position;
 
   for (const auto& sync_peer : syncable_service->sync_items()) {
+    if (sync_peer.first == extension_misc::kCameraAppId) {
+      has_camera_app = true;
+    }
+
     if (!sync_peer.second->item_pin_ordinal.IsValid())
       continue;
 
     pins_from_sync_raw.insert(sync_peer.first);
 
-    // Don't include apps that currently do not exist on device.
     if (sync_peer.first != extension_misc::kChromeAppId &&
         !helper->IsValidIDForCurrentUser(sync_peer.first)) {
+      // Don't include apps that currently do not exist on device.
+
+      // For legacy camera app which has a valid pinned position, use this
+      // position to set the camera app later.
+      if (IsLegacyCameraAppId(sync_peer.first) &&
+          !legacy_camera_pinned_position.IsValid()) {
+        legacy_camera_pinned_position = sync_peer.second->item_pin_ordinal;
+
+        // Wipe the position for legacy camera app.
+        syncable_service->SetPinPosition(sync_peer.first,
+                                         syncer::StringOrdinal());
+      }
       continue;
     }
 
-    std::string pinned_app_id;
-
-    // Map any real camera app id to the internal camera app id.
-    if (IsCameraApp(sync_peer.first) ||
-        sync_peer.first == ash::kInternalAppIdCamera) {
-      // Prevent internal camera app being pinned twice.
-      if (has_pinned_camera_app) {
-        continue;
-      }
-      // Check the validity of internal camera app id.
-      if (!helper->IsValidIDForCurrentUser(ash::kInternalAppIdCamera)) {
-        continue;
-      }
-      has_pinned_camera_app = true;
-      pinned_app_id = ash::kInternalAppIdCamera;
-    } else {
-      pinned_app_id = sync_peer.first;
-    }
-
+    std::string pinned_app_id = sync_peer.first;
     pin_infos.emplace_back(pinned_app_id, sync_peer.second->item_pin_ordinal);
   }
 
+  syncer::StringOrdinal camera_app_position =
+      syncable_service->GetPinPosition(extension_misc::kCameraAppId);
+  // If the camera app is in the sync list with no valid position and there is a
+  // legacy camera app which has valid position, use this position for the
+  // camera app.
+  if (has_camera_app && !camera_app_position.IsValid() &&
+      legacy_camera_pinned_position.IsValid()) {
+    syncable_service->SetPinPosition(extension_misc::kCameraAppId,
+                                     legacy_camera_pinned_position);
+    pin_infos.emplace_back(extension_misc::kCameraAppId,
+                           legacy_camera_pinned_position);
+  }
+
   // Make sure Chrome is always pinned.
   syncer::StringOrdinal chrome_position =
       syncable_service->GetPinPosition(extension_misc::kChromeAppId);
@@ -595,8 +612,6 @@
                     const ash::ShelfID& shelf_id_before,
                     const std::vector<ash::ShelfID>& shelf_ids_after) {
   DCHECK(profile);
-  // Camera apps are mapped to the internal app.
-  DCHECK(!IsCameraApp(shelf_id.app_id));
 
   const std::string& app_id = shelf_id.app_id;
   if (!shelf_id.launch_id.empty()) {
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index 0e529b2c..38f8be8 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -486,10 +486,10 @@
   const extensions::ExtensionRegistry* registry =
       extensions::ExtensionRegistry::Get(profile);
   const extensions::Extension* extension =
-      registry->GetInstalledExtension(extension_misc::kChromeCameraAppId);
+      registry->GetInstalledExtension(extension_misc::kCameraAppId);
 
   auto url = GURL(extensions::Extension::GetBaseURLFromExtensionId(
-                      extension_misc::kChromeCameraAppId)
+                      extension_misc::kCameraAppId)
                       .spec() +
                   queries);
 
@@ -499,7 +499,7 @@
 }
 
 void ChromeNewWindowClient::CloseCameraApp() {
-  const ash::ShelfID shelf_id(ash::kInternalAppIdCamera);
+  const ash::ShelfID shelf_id(extension_misc::kCameraAppId);
   AppWindowLauncherItemController* const app_controller =
       ChromeLauncherController::instance()
           ->shelf_model()
diff --git a/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.cc b/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.cc
index 520381a7..40e545d2 100644
--- a/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.cc
+++ b/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.cc
@@ -18,7 +18,9 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_launcher_item_controller.h"
+#include "chrome/browser/ui/ash/launcher/app_window_base.h"
 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
+#include "chrome/browser/ui/ash/launcher/arc_app_window.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h"
 #include "ui/aura/client/aura_constants.h"
@@ -107,7 +109,31 @@
   prefs->RemoveObserver(this);
 }
 
-void AppServiceAppWindowArcTracker::OnWindowVisibilityChanging(
+void AppServiceAppWindowArcTracker::ActiveUserChanged(
+    const std::string& user_email) {
+  const std::string& primary_user_email = user_manager::UserManager::Get()
+                                              ->GetPrimaryUser()
+                                              ->GetAccountId()
+                                              .GetUserEmail();
+  if (user_email == primary_user_email) {
+    // Make sure that we created items for all apps, not only which have a
+    // window.
+    for (const auto& info : task_id_to_arc_app_window_info_)
+      AttachControllerToTask(info.first);
+
+    // Update active status.
+    OnTaskSetActive(active_task_id_);
+  } else {
+    // Some controllers might have no windows attached, for example background
+    // task when foreground tasks is in full screen.
+    for (const auto& it : app_shelf_group_to_controller_map_)
+      app_service_controller_->owner()->CloseLauncherItem(
+          it.second->shelf_id());
+    app_shelf_group_to_controller_map_.clear();
+  }
+}
+
+void AppServiceAppWindowArcTracker::OnWindowVisibilityChanged(
     aura::Window* window) {
   const int task_id = arc::GetWindowTaskId(window);
   if (task_id == arc::kNoTaskId || task_id == arc::kSystemWindowTaskId)
@@ -191,8 +217,10 @@
   ArcAppWindowInfo* const info = it->second.get();
   DCHECK(info);
   info->SetDescription(label, icon_png_data);
-
-  // TODO(crbug.com/1011235): Set title and image
+  AppWindowBase* app_window =
+      app_service_controller_->GetAppWindow(it->second->window());
+  if (app_window)
+    app_window->SetDescription(label, icon_png_data);
 }
 
 void AppServiceAppWindowArcTracker::OnTaskDestroyed(int task_id) {
@@ -201,8 +229,19 @@
     return;
 
   aura::Window* const window = it->second.get()->window();
-  if (window)
+  if (window) {
+    // For ARC apps, window may be recreated in some cases, and OnTaskSetActive
+    // could be called after the window is destroyed, so controller is not
+    // closed on window destroying. Controller will be closed onTaskDestroyed
+    // event which is generated when the actual task is destroyed. So when the
+    // task is destroyed, delete the instance, otherwise, we might have an
+    // instance though the window has been closed, and the task has been
+    // destroyed.
+    app_service_controller_->app_service_instance_helper()->OnInstances(
+        it->second.get()->app_shelf_id().app_id(), window, std::string(),
+        apps::InstanceState::kDestroyed);
     app_service_controller_->UnregisterWindow(window);
+  }
 
   // Check if we may close controller now, at this point we can safely remove
   // controllers without window.
@@ -234,7 +273,15 @@
     DCHECK(previous_arc_app_window_info);
     app_service_controller_->owner()->SetItemStatus(
         previous_arc_app_window_info->shelf_id(), ash::STATUS_RUNNING);
-    // TODO(crbug.com/1011235): Set previous window full screen mode.
+    AppWindowBase* previous_app_window = app_service_controller_->GetAppWindow(
+        previous_arc_app_window_info->window());
+    if (previous_app_window) {
+      previous_app_window->SetFullscreenMode(
+          previous_app_window->widget() &&
+                  previous_app_window->widget()->IsFullscreen()
+              ? ArcAppWindow::FullScreenMode::kActive
+              : ArcAppWindow::FullScreenMode::kNonActive);
+    }
   }
 
   active_task_id_ = task_id;
@@ -278,8 +325,8 @@
   ArcAppWindowInfo* const info = it->second.get();
   DCHECK(info);
 
-  // Check if we have set the window for this task.
-  if (info->window())
+  // Check if we have set the AppWindowBase for this task.
+  if (app_service_controller_->GetAppWindow(window))
     return;
 
   views::Widget* const widget = views::Widget::GetWidgetForNativeWindow(window);
@@ -288,6 +335,10 @@
   const ash::ShelfID shelf_id = info->shelf_id();
   AttachControllerToTask(task_id);
   app_service_controller_->AddWindowToShelf(window, shelf_id);
+  AppWindowBase* app_window = app_service_controller_->GetAppWindow(window);
+  if (app_window)
+    app_window->SetDescription(info->title(), info->icon_data_png());
+
   window->SetProperty(ash::kShelfIDKey, shelf_id.Serialize());
   window->SetProperty(ash::kArcPackageNameKey,
                       new std::string(info->package_name()));
diff --git a/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.h b/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.h
index 611bc36..f4f8afbf 100644
--- a/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.h
+++ b/chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.h
@@ -34,9 +34,6 @@
 
 // AppServiceAppWindowArcTracker observes the ArcAppListPrefs to handle ARC app
 // window special cases, e.g. task id, closing ARC app windows, etc.
-//
-// TODO(crbug.com/1011235):
-// 1. Add ActiveUserChanged to handle the user switch case.
 class AppServiceAppWindowArcTracker : public ArcAppListPrefs::Observer,
                                       public arc::ArcSessionManager::Observer {
  public:
@@ -48,8 +45,10 @@
   AppServiceAppWindowArcTracker& operator=(
       const AppServiceAppWindowArcTracker&) = delete;
 
-  // Invoked by controller to notify |window| visibility is changing.
-  void OnWindowVisibilityChanging(aura::Window* window);
+  void ActiveUserChanged(const std::string& user_email);
+
+  // Invoked by controller to notify |window| visibility is changed.
+  void OnWindowVisibilityChanged(aura::Window* window);
 
   // Invoked by controller to notify |window| is destroying.
   void OnWindowDestroying(aura::Window* window);
@@ -83,6 +82,8 @@
 
   ash::ShelfID GetShelfId(int task_id) const;
 
+  int active_task_id() const { return active_task_id_; }
+
  private:
   class ArcAppWindowInfo;
 
diff --git a/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.cc
index d6cf82f..99c202a 100644
--- a/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.cc
@@ -4,7 +4,10 @@
 
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h"
 
+#include <memory>
+
 #include "ash/public/cpp/app_list/internal_app_id_constants.h"
+#include "ash/public/cpp/multi_user_window_manager.h"
 #include "ash/public/cpp/shelf_model.h"
 #include "ash/public/cpp/window_properties.h"
 #include "base/stl_util.h"
@@ -13,14 +16,19 @@
 #include "chrome/browser/chromeos/crostini/crostini_features.h"
 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_arc_tracker.h"
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_crostini_tracker.h"
 #include "chrome/browser/ui/ash/launcher/app_service_app_window_launcher_item_controller.h"
 #include "chrome/browser/ui/ash/launcher/app_window_base.h"
 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
+#include "chrome/browser/ui/ash/launcher/arc_app_window.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
+#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
+#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h"
 #include "chrome/services/app_service/public/cpp/instance.h"
 #include "chrome/services/app_service/public/mojom/types.mojom.h"
+#include "components/account_id/account_id.h"
 #include "components/arc/arc_util.h"
 #include "extensions/common/constants.h"
 #include "ui/aura/env.h"
@@ -44,11 +52,21 @@
   if (crostini::CrostiniFeatures::Get()->IsUIAllowed(owner->profile()))
     crostini_tracker_ =
         std::make_unique<AppServiceAppWindowCrostiniTracker>(this);
+
+  profile_list_.push_back(owner->profile());
 }
 
 AppServiceAppWindowLauncherController::
     ~AppServiceAppWindowLauncherController() {
   aura::Env::GetInstance()->RemoveObserver(this);
+
+  // We need to remove all Registry observers for added users.
+  for (auto* profile : profile_list_) {
+    apps::AppServiceProxy* proxy =
+        apps::AppServiceProxyFactory::GetForProfile(profile);
+    DCHECK(proxy);
+    proxy->InstanceRegistry().RemoveObserver(this);
+  }
 }
 
 AppWindowLauncherItemController*
@@ -68,35 +86,38 @@
 
 void AppServiceAppWindowLauncherController::ActiveUserChanged(
     const std::string& user_email) {
-  if (proxy_)
-    Observe(nullptr);
-
-  auto* new_proxy =
-      apps::AppServiceProxyFactory::GetForProfile(owner()->profile());
-  DCHECK(new_proxy);
-
+  proxy_ = apps::AppServiceProxyFactory::GetForProfile(owner()->profile());
+  DCHECK(proxy_);
   // Deactivates the running app windows in InstanceRegistry for the inactive
   // user, and activates the app windows for the active user.
-  for (const auto& window_item : aura_window_to_app_window_) {
-    AppWindowBase* app_window = window_item.second.get();
-    const std::string app_id = app_window->shelf_id().app_id;
-    // Skips ARC apps, because task id is used for ARC apps.
-    if (app_id == ash::kInternalAppIdKeyboardShortcutViewer)
-      continue;
-
-    if (!new_proxy->InstanceRegistry()
-             .GetWindows(app_window->shelf_id().app_id)
-             .empty()) {
-      AddAppWindowToShelf(app_window);
+  for (auto* window : window_list_) {
+    ash::ShelfID shelf_id;
+    if (proxy_->InstanceRegistry().ForOneInstance(
+            window, [&shelf_id](const apps::InstanceUpdate& update) {
+              shelf_id = ash::ShelfID(update.AppId(), update.LaunchId());
+            })) {
+      RegisterWindow(window, shelf_id);
     } else {
-      RemoveAppWindowFromShelf(app_window);
+      auto app_window_it = aura_window_to_app_window_.find(window);
+      if (app_window_it != aura_window_to_app_window_.end()) {
+        RemoveAppWindowFromShelf(app_window_it->second.get());
+        aura_window_to_app_window_.erase(app_window_it);
+      }
     }
   }
-
-  proxy_ = new_proxy;
-  Observe(&proxy_->InstanceRegistry());
-
   app_service_instance_helper_->ActiveUserChanged();
+  if (arc_tracker_)
+    arc_tracker_->ActiveUserChanged(user_email);
+}
+
+void AppServiceAppWindowLauncherController::AdditionalUserAddedToSession(
+    Profile* profile) {
+  // Each users InstanceRegister needs to be observed.
+  apps::AppServiceProxy* proxy =
+      apps::AppServiceProxyFactory::GetForProfile(profile);
+  DCHECK(proxy);
+  proxy->InstanceRegistry().AddObserver(this);
+  profile_list_.push_back(profile);
 }
 
 void AppServiceAppWindowLauncherController::OnWindowInitialized(
@@ -139,7 +160,7 @@
   RegisterWindow(window, shelf_id);
 }
 
-void AppServiceAppWindowLauncherController::OnWindowVisibilityChanging(
+void AppServiceAppWindowLauncherController::OnWindowVisibilityChanged(
     aura::Window* window,
     bool visible) {
   // Skip OnWindowVisibilityChanged for ancestors/descendants.
@@ -147,7 +168,7 @@
     return;
 
   if (arc_tracker_)
-    arc_tracker_->OnWindowVisibilityChanging(window);
+    arc_tracker_->OnWindowVisibilityChanged(window);
 
   ash::ShelfID shelf_id = GetShelfId(window);
   if (shelf_id.IsNull())
@@ -224,6 +245,9 @@
   AppWindowLauncherController::OnWindowActivated(reason, new_active,
                                                  old_active);
 
+  if (arc_tracker_)
+    arc_tracker_->OnTaskSetActive(arc_tracker_->active_task_id());
+
   SetWindowActivated(new_active, /*active*/ true);
   SetWindowActivated(old_active, /*active*/ false);
 }
@@ -234,21 +258,38 @@
   if (!observed_windows_.IsObserving(window))
     return;
 
+  ash::ShelfID shelf_id(update.AppId(), update.LaunchId());
+
   // This is the first update for the given window.
   if (update.StateIsNull() &&
       (update.State() & apps::InstanceState::kDestroyed) ==
           apps::InstanceState::kUnknown) {
     std::string app_id = update.AppId();
     window->SetProperty(ash::kAppIDKey, update.AppId());
-    ash::ShelfID shelf_id(update.AppId(), update.LaunchId());
     window->SetProperty(ash::kShelfIDKey, shelf_id.Serialize());
     window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_APP);
+
+    // Web apps and Chrome are managed by browser, so skip them.
+    if (app_service_instance_helper_->IsWebApp(shelf_id.app_id) ||
+        shelf_id.app_id == extension_misc::kChromeAppId) {
+      return;
+    }
+    window_list_.push_back(window);
     return;
   }
 
+  // For Chrome apps, when it is shown, call UserHasAppOnActiveDesktop to handle
+  // teleport function.
+  if (update.BrowserContext() &&
+      (update.State() & apps::InstanceState::kStarted) !=
+          apps::InstanceState::kUnknown &&
+      (update.State() & apps::InstanceState::kRunning) !=
+          apps::InstanceState::kUnknown) {
+    UserHasAppOnActiveDesktop(window, shelf_id, update.BrowserContext());
+  }
+
   // Launch id is updated, so constructs a new shelf id.
   if (update.LaunchIdChanged()) {
-    ash::ShelfID shelf_id(update.AppId(), update.LaunchId());
     window->SetProperty(ash::kShelfIDKey, shelf_id.Serialize());
     window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_APP);
   }
@@ -262,12 +303,31 @@
     // window is just added or hidden, and we don't need to add the app window
     // to Shelf. When the app window is visible or activeted, it can be added to
     // Shelf.
+    //
+    // The the window is teleported to the current user could be hidden as
+    // well. But we only remove the window added for the active user, and skip
+    // the window teleported to the current user, because
+    // MultiUserWindowManagerHelper manages those windows.
     auto app_window_it = aura_window_to_app_window_.find(window);
-    if (app_window_it != aura_window_to_app_window_.end()) {
+    if (app_window_it != aura_window_to_app_window_.end() &&
+        proxy_->InstanceRegistry().ForOneInstance(
+            window, [](const apps::InstanceUpdate& update) {})) {
       RemoveAppWindowFromShelf(app_window_it->second.get());
       aura_window_to_app_window_.erase(app_window_it);
     }
   }
+
+  if (update.StateChanged() &&
+      update.State() == apps::InstanceState::kDestroyed) {
+    // For Chrome apps edge case, it could be added for the inactive users, and
+    // then removed. Since it is not registered we don't need to do anything
+    // anyways. As such, all which is left to do here is to get rid of our own
+    // reference.
+    WindowList::iterator it =
+        std::find(window_list_.begin(), window_list_.end(), update.Window());
+    if (it != window_list_.end())
+      window_list_.erase(it);
+  }
 }
 
 void AppServiceAppWindowLauncherController::OnInstanceRegistryWillBeDestroyed(
@@ -275,6 +335,12 @@
   Observe(nullptr);
 }
 
+int AppServiceAppWindowLauncherController::GetActiveTaskId() const {
+  if (arc_tracker_)
+    return arc_tracker_->active_task_id();
+  return arc::kNoTaskId;
+}
+
 void AppServiceAppWindowLauncherController::UnregisterWindow(
     aura::Window* window) {
   auto app_window_it = aura_window_to_app_window_.find(window);
@@ -289,14 +355,32 @@
   if (base::Contains(aura_window_to_app_window_, window))
     return;
 
-  auto app_window_ptr = std::make_unique<AppWindowBase>(
-      shelf_id, views::Widget::GetWidgetForNativeWindow(window));
-  AppWindowBase* app_window = app_window_ptr.get();
-  aura_window_to_app_window_[window] = std::move(app_window_ptr);
-
+  AppWindowBase* app_window;
+  if (arc::GetWindowTaskId(window) != arc::kNoTaskId) {
+    std::unique_ptr<ArcAppWindow> app_window_ptr =
+        std::make_unique<ArcAppWindow>(
+            arc::GetWindowTaskId(window),
+            arc::ArcAppShelfId::FromString(shelf_id.app_id),
+            views::Widget::GetWidgetForNativeWindow(window), this,
+            owner()->profile());
+    app_window = app_window_ptr.get();
+    aura_window_to_app_window_[window] = std::move(app_window_ptr);
+  } else {
+    auto app_window_ptr = std::make_unique<AppWindowBase>(
+        shelf_id, views::Widget::GetWidgetForNativeWindow(window));
+    app_window = app_window_ptr.get();
+    aura_window_to_app_window_[window] = std::move(app_window_ptr);
+  }
   AddAppWindowToShelf(app_window);
 }
 
+AppWindowBase* AppServiceAppWindowLauncherController::GetAppWindow(
+    aura::Window* window) {
+  if (!base::Contains(aura_window_to_app_window_, window))
+    return nullptr;
+  return aura_window_to_app_window_[window].get();
+}
+
 void AppServiceAppWindowLauncherController::SetWindowActivated(
     aura::Window* window,
     bool active) {
@@ -328,10 +412,13 @@
   if (app_window_it != aura_window_to_app_window_.end())
     return;
 
-  if (arc_tracker_)
+  // For the ARC apps window, AttachControllerToWindow calls AddWindowToShelf,
+  // so we don't need to call AddWindowToShelf again.
+  if (arc_tracker_ && arc::GetWindowTaskId(window) != arc::kNoTaskId) {
     arc_tracker_->AttachControllerToWindow(window);
-
-  AddWindowToShelf(window, shelf_id);
+  } else {
+    AddWindowToShelf(window, shelf_id);
+  }
 }
 
 void AppServiceAppWindowLauncherController::UnregisterAppWindow(
@@ -349,10 +436,6 @@
 void AppServiceAppWindowLauncherController::AddAppWindowToShelf(
     AppWindowBase* app_window) {
   const ash::ShelfID shelf_id = app_window->shelf_id();
-  // Internal Camera app does not have own window. Either ARC or extension
-  // window controller would add window to controller.
-  if (shelf_id.app_id == ash::kInternalAppIdCamera)
-    return;
 
   AppWindowLauncherItemController* item_controller =
       owner()->shelf_model()->GetAppWindowLauncherItemController(shelf_id);
@@ -368,6 +451,13 @@
                                                    std::move(controller));
       owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
     }
+  } else {
+    // The window for ARC Play Store is is a special window, which is created by
+    // both Extensions and ARC. If Extensions's window is generated after
+    // ARC window, calls OnItemDelegateDiscarded to remove the ARC apps
+    // window.
+    if (shelf_id.app_id == arc::kPlayStoreAppId)
+      OnItemDelegateDiscarded(item_controller);
   }
 
   item_controller->AddWindow(app_window);
@@ -377,10 +467,6 @@
 void AppServiceAppWindowLauncherController::RemoveAppWindowFromShelf(
     AppWindowBase* app_window) {
   const ash::ShelfID shelf_id = app_window->shelf_id();
-  // Internal Camera app does not have own window. Either ARC or extension
-  // window controller would remove window from controller.
-  if (shelf_id.app_id == ash::kInternalAppIdCamera)
-    return;
 
   UnregisterAppWindow(app_window);
 
@@ -450,3 +536,47 @@
 
   return shelf_id;
 }
+
+void AppServiceAppWindowLauncherController::UserHasAppOnActiveDesktop(
+    aura::Window* window,
+    const ash::ShelfID& shelf_id,
+    content::BrowserContext* browser_context) {
+  // If the window was created for the active user, register it to show an item
+  // on the shelf.
+  if (proxy_->InstanceRegistry().ForOneInstance(
+          window, [](const apps::InstanceUpdate& update) {})) {
+    RegisterWindow(window, shelf_id);
+    return;
+  }
+
+  // If the window was created for the inactive user and it has been teleported
+  // to the current user's desktop, register it to show an item on the shelf.
+  const AccountId current_account_id = multi_user_util::GetCurrentAccountId();
+  MultiUserWindowManagerHelper* helper =
+      MultiUserWindowManagerHelper::GetInstance();
+  aura::Window* other_window = nullptr;
+  for (auto* it : profile_list_) {
+    apps::AppServiceProxy* proxy =
+        apps::AppServiceProxyFactory::GetForProfile(it);
+    if (proxy == proxy_)
+      continue;
+    proxy->InstanceRegistry().ForEachInstance(
+        [&other_window, &window, &shelf_id, &browser_context, &helper,
+         &current_account_id](const apps::InstanceUpdate& update) {
+          if (helper->IsWindowOnDesktopOfUser(update.Window(),
+                                              current_account_id) &&
+              (update.AppId() == shelf_id.app_id) &&
+              (update.BrowserContext() == browser_context) &&
+              update.Window() != window) {
+            other_window = update.Window();
+          }
+        });
+    if (other_window)
+      break;
+  }
+  if (other_window) {
+    MultiUserWindowManagerHelper::GetWindowManager()->ShowWindowForUser(
+        window, multi_user_util::GetCurrentAccountId());
+    RegisterWindow(window, shelf_id);
+  }
+}
diff --git a/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h
index 12903c8..a260db1 100644
--- a/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/app_service_app_window_launcher_controller.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
 #include "ash/public/cpp/shelf_types.h"
 #include "base/macros.h"
@@ -14,6 +15,7 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/ui/ash/launcher/app_service_instance_registry_helper.h"
 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
+#include "chrome/browser/ui/ash/launcher/arc_app_window_delegate.h"
 #include "chrome/services/app_service/public/cpp/instance_registry.h"
 #include "ui/aura/env_observer.h"
 #include "ui/aura/window.h"
@@ -24,9 +26,10 @@
 }  // namespace apps
 
 class AppServiceAppWindowCrostiniTracker;
-class AppWindowBase;
 class AppServiceAppWindowArcTracker;
+class AppWindowBase;
 class ChromeLauncherController;
+class Profile;
 
 // AppServiceAppWindowLauncherController observes the AppService
 // InstanceRegistry and the aura window manager. It manages app shelf items,
@@ -36,7 +39,8 @@
     : public AppWindowLauncherController,
       public aura::EnvObserver,
       public aura::WindowObserver,
-      public apps::InstanceRegistry::Observer {
+      public apps::InstanceRegistry::Observer,
+      public ArcAppWindowDelegate {
  public:
   explicit AppServiceAppWindowLauncherController(
       ChromeLauncherController* owner);
@@ -46,6 +50,7 @@
   AppWindowLauncherItemController* ControllerForWindow(
       aura::Window* window) override;
   void ActiveUserChanged(const std::string& user_email) override;
+  void AdditionalUserAddedToSession(Profile* profile) override;
 
   // aura::EnvObserver:
   void OnWindowInitialized(aura::Window* window) override;
@@ -54,7 +59,7 @@
   void OnWindowPropertyChanged(aura::Window* window,
                                const void* key,
                                intptr_t old) override;
-  void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
+  void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
   void OnWindowDestroying(aura::Window* window) override;
 
   // wm::ActivationChangeObserver:
@@ -68,15 +73,18 @@
   void OnInstanceRegistryWillBeDestroyed(
       apps::InstanceRegistry* instance_registry) override;
 
+  // ArcAppWindowDelegate:
+  int GetActiveTaskId() const override;
+
   // Removes an AppWindowBase from its AppWindowLauncherItemController by
   // |window|.
   void UnregisterWindow(aura::Window* window);
 
-  // Creates an AppWindowBase, adds it to |aura_window_to_app_window_|, and
-  // updates its AppWindowLauncherItemController by |window| and |shelf_id|.
+  // Creates an AppWindowBase, adds it to |aura_window_to_app_window_|,
+  // and updates its AppWindowLauncherItemController by |window| and |shelf_id|.
   // This function is used by AppServiceAppWindowArcTracker when the task id is
-  // created after the window created, to make sure the AppWindowBase and the
-  // shelf item are created.
+  // created after the window created, to make sure the AppWindowBase and
+  // the shelf item are created.
   void AddWindowToShelf(aura::Window* window, const ash::ShelfID& shelf_id);
 
   AppServiceInstanceRegistryHelper* app_service_instance_helper() {
@@ -87,14 +95,18 @@
     return crostini_tracker_.get();
   }
 
+  AppWindowBase* GetAppWindow(aura::Window* window);
+
  private:
   using AuraWindowToAppWindow =
       std::map<aura::Window*, std::unique_ptr<AppWindowBase>>;
+  using ProfileList = std::vector<Profile*>;
+  using WindowList = std::vector<aura::Window*>;
 
   void SetWindowActivated(aura::Window* window, bool active);
 
-  // Creates an AppWindowBase and updates its AppWindowLauncherItemController by
-  // |window| and |shelf_id|.
+  // Creates an AppWindowBase and updates its
+  // AppWindowLauncherItemController by |window| and |shelf_id|.
   void RegisterWindow(aura::Window* window, const ash::ShelfID& shelf_id);
 
   // Removes an AppWindowBase from its AppWindowLauncherItemController.
@@ -108,6 +120,12 @@
 
   ash::ShelfID GetShelfId(aura::Window* window) const;
 
+  // Register |window| if the owner of the given |window| has a window
+  // teleported of the |window|'s application type to the current desktop.
+  void UserHasAppOnActiveDesktop(aura::Window* window,
+                                 const ash::ShelfID& shelf_id,
+                                 content::BrowserContext* browser_context);
+
   AuraWindowToAppWindow aura_window_to_app_window_;
   ScopedObserver<aura::Window, aura::WindowObserver> observed_windows_{this};
 
@@ -117,6 +135,12 @@
   std::unique_ptr<AppServiceAppWindowArcTracker> arc_tracker_;
   std::unique_ptr<AppServiceAppWindowCrostiniTracker> crostini_tracker_;
 
+  // A list of profiles which we additionally observe.
+  ProfileList profile_list_;
+
+  // A list of windows added for users.
+  WindowList window_list_;
+
   DISALLOW_COPY_AND_ASSIGN(AppServiceAppWindowLauncherController);
 };
 
diff --git a/chrome/browser/ui/ash/launcher/app_window_base.h b/chrome/browser/ui/ash/launcher/app_window_base.h
index 27db0892..b5b144d 100644
--- a/chrome/browser/ui/ash/launcher/app_window_base.h
+++ b/chrome/browser/ui/ash/launcher/app_window_base.h
@@ -21,6 +21,12 @@
 // Crostini, and interal apps.
 class AppWindowBase : public ui::BaseWindow {
  public:
+  enum class FullScreenMode {
+    kNotDefined,  // Fullscreen mode was not defined.
+    kActive,      // Fullscreen is activated for an app.
+    kNonActive,   // Fullscreen was not activated for an app.
+  };
+
   AppWindowBase(const ash::ShelfID& shelf_id, views::Widget* widget);
 
   virtual ~AppWindowBase() {}
@@ -37,6 +43,12 @@
 
   AppWindowLauncherItemController* controller() const { return controller_; }
 
+  virtual void SetDescription(
+      const std::string& title,
+      const std::vector<uint8_t>& unsafe_icon_data_png) {}
+
+  virtual void SetFullscreenMode(FullScreenMode mode) {}
+
   // ui::BaseWindow:
   bool IsActive() const override;
   bool IsMaximized() const override;
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window.cc b/chrome/browser/ui/ash/launcher/arc_app_window.cc
index 1bfa702..c3b79534 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_window.cc
@@ -12,6 +12,8 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.h"
+#include "chrome/common/chrome_features.h"
+#include "components/arc/arc_util.h"
 #include "components/exo/shell_surface_base.h"
 #include "components/exo/shell_surface_util.h"
 #include "extensions/common/constants.h"
@@ -31,13 +33,19 @@
 ArcAppWindow::ArcAppWindow(int task_id,
                            const arc::ArcAppShelfId& app_shelf_id,
                            views::Widget* widget,
-                           ArcAppWindowLauncherController* owner,
+                           ArcAppWindowDelegate* owner,
                            Profile* profile)
     : AppWindowBase(ash::ShelfID(app_shelf_id.app_id()), widget),
       task_id_(task_id),
       app_shelf_id_(app_shelf_id),
       owner_(owner),
       profile_(profile) {
+  DCHECK(owner_);
+
+  // AppService uses app_shelf_id as the app_id to construct ShelfID.
+  if (base::FeatureList::IsEnabled(features::kAppServiceInstanceRegistry))
+    set_shelf_id(ash::ShelfID(app_shelf_id.ToString()));
+
   SetDefaultAppIcon();
 }
 
@@ -46,7 +54,7 @@
 }
 
 void ArcAppWindow::SetFullscreenMode(FullScreenMode mode) {
-  DCHECK(mode != FullScreenMode::NOT_DEFINED);
+  DCHECK(mode != FullScreenMode::kNotDefined);
   fullscreen_mode_ = mode;
 }
 
@@ -76,7 +84,7 @@
 }
 
 bool ArcAppWindow::IsActive() const {
-  return widget()->IsActive() && owner_->active_task_id() == task_id_;
+  return widget()->IsActive() && owner_->GetActiveTaskId() == task_id_;
 }
 
 void ArcAppWindow::Close() {
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window.h b/chrome/browser/ui/ash/launcher/arc_app_window.h
index de25192..e76c20b 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window.h
+++ b/chrome/browser/ui/ash/launcher/arc_app_window.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/ui/ash/launcher/app_window_base.h"
 #include "chrome/browser/ui/ash/launcher/arc_app_shelf_id.h"
 
-class ArcAppWindowLauncherController;
+class ArcAppWindowDelegate;
 
 namespace gfx {
 class ImageSkia;
@@ -33,28 +33,21 @@
                      public ImageDecoder::ImageRequest,
                      public AppIconLoaderDelegate {
  public:
-  // TODO(khmel): use a bool set to false by default, or use an existing enum,
-  // like ash::WindowStateType.
-  enum class FullScreenMode {
-    NOT_DEFINED,  // Fullscreen mode was not defined.
-    ACTIVE,       // Fullscreen is activated for an app.
-    NON_ACTIVE,   // Fullscreen was not activated for an app.
-  };
-
   ArcAppWindow(int task_id,
                const arc::ArcAppShelfId& app_shelf_id,
                views::Widget* widget,
-               ArcAppWindowLauncherController* owner,
+               ArcAppWindowDelegate* owner,
                Profile* profile);
 
   ~ArcAppWindow() override;
 
-  void SetFullscreenMode(FullScreenMode mode);
+  void SetFullscreenMode(FullScreenMode mode) override;
 
   // Sets optional window title and icon. Note that |unsafe_icon_data_png| has
   // to be decoded in separate process for security reason.
-  void SetDescription(const std::string& title,
-                      const std::vector<uint8_t>& unsafe_icon_data_png);
+  void SetDescription(
+      const std::string& title,
+      const std::vector<uint8_t>& unsafe_icon_data_png) override;
 
   FullScreenMode fullscreen_mode() const { return fullscreen_mode_; }
 
@@ -85,8 +78,8 @@
   // Keeps ARC shelf grouping id.
   const arc::ArcAppShelfId app_shelf_id_;
   // Keeps current full-screen mode.
-  FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED;
-  ArcAppWindowLauncherController* const owner_;
+  FullScreenMode fullscreen_mode_ = FullScreenMode::kNotDefined;
+  ArcAppWindowDelegate* const owner_;
 
   // Set to true in case image fetch is requested. This indicates that default
   // app icon is returned in |OnAppImageUpdated|.
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_delegate.h b/chrome/browser/ui/ash/launcher/arc_app_window_delegate.h
new file mode 100644
index 0000000..92855e3
--- /dev/null
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_delegate.h
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ASH_LAUNCHER_ARC_APP_WINDOW_DELEGATE_H_
+#define CHROME_BROWSER_UI_ASH_LAUNCHER_ARC_APP_WINDOW_DELEGATE_H_
+
+// Delegate interface for ArcAppWindow.
+class ArcAppWindowDelegate {
+ public:
+  ArcAppWindowDelegate() = default;
+  ~ArcAppWindowDelegate() = default;
+
+  ArcAppWindowDelegate(const ArcAppWindowDelegate&) = delete;
+  ArcAppWindowDelegate& operator=(const ArcAppWindowDelegate&) = delete;
+
+  // Returns the active task id.
+  virtual int GetActiveTaskId() const = 0;
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_LAUNCHER_ARC_APP_WINDOW_DELEGATE_H_
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
index c4b3652..65d1566 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -35,13 +35,6 @@
 
 constexpr size_t kMaxIconPngSize = 64 * 1024;  // 64 kb
 
-// Map any ARC Camera app to internal Camera app.
-ash::ShelfID MaybeMapShelfId(const arc::ArcAppShelfId& arc_app_shelf_id) {
-  if (IsCameraApp(arc_app_shelf_id.app_id()))
-    return ash::ShelfID(ash::kInternalAppIdCamera);
-  return ash::ShelfID(arc_app_shelf_id.ToString());
-}
-
 }  // namespace
 
 // The information about the arc application window which has to be kept
@@ -366,8 +359,8 @@
     previous_app_window->SetFullscreenMode(
         previous_app_window->widget() &&
                 previous_app_window->widget()->IsFullscreen()
-            ? ArcAppWindow::FullScreenMode::ACTIVE
-            : ArcAppWindow::FullScreenMode::NON_ACTIVE);
+            ? ArcAppWindow::FullScreenMode::kActive
+            : ArcAppWindow::FullScreenMode::kNonActive);
   }
 
   active_task_id_ = task_id;
@@ -384,11 +377,15 @@
     // if (new_active_app_it->second->widget()) {
     //   new_active_app_it->second->widget()->SetFullscreen(
     //       new_active_app_it->second->fullscreen_mode() ==
-    //       ArcAppWindow::FullScreenMode::ACTIVE);
+    //       ArcAppWindow::FullScreenMode::kActive);
     // }
   }
 }
 
+int ArcAppWindowLauncherController::GetActiveTaskId() const {
+  return active_task_id_;
+}
+
 AppWindowLauncherItemController*
 ArcAppWindowLauncherController::ControllerForWindow(aura::Window* window) {
   if (!window)
@@ -471,13 +468,12 @@
   const arc::ArcAppShelfId& app_shelf_id = app_window_info.app_shelf_id();
   const auto it = app_shelf_group_to_controller_map_.find(app_shelf_id);
   if (it != app_shelf_group_to_controller_map_.end()) {
-    DCHECK(IsCameraApp(app_shelf_id.ToString()) ||
-           it->second->app_id() == app_shelf_id.ToString());
+    DCHECK(it->second->app_id() == app_shelf_id.ToString());
     it->second->AddTaskId(task_id);
     return it->second;
   }
 
-  const ash::ShelfID shelf_id = MaybeMapShelfId(app_shelf_id);
+  const ash::ShelfID shelf_id = ash::ShelfID(app_shelf_id.ToString());
   std::unique_ptr<ArcAppWindowLauncherItemController> controller =
       std::make_unique<ArcAppWindowLauncherItemController>(shelf_id);
   ArcAppWindowLauncherItemController* item_controller = controller.get();
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
index 903051e..a09afcf4 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/arc_app_shelf_id.h"
+#include "chrome/browser/ui/ash/launcher/arc_app_window_delegate.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/aura/env_observer.h"
 #include "ui/aura/window_observer.h"
@@ -34,7 +35,8 @@
                                        public aura::EnvObserver,
                                        public aura::WindowObserver,
                                        public ArcAppListPrefs::Observer,
-                                       public arc::ArcSessionManager::Observer {
+                                       public arc::ArcSessionManager::Observer,
+                                       public ArcAppWindowDelegate {
  public:
   explicit ArcAppWindowLauncherController(ChromeLauncherController* owner);
   ~ArcAppWindowLauncherController() override;
@@ -70,7 +72,8 @@
   void OnTaskDestroyed(int task_id) override;
   void OnTaskSetActive(int32_t task_id) override;
 
-  int active_task_id() const { return active_task_id_; }
+  // ArcAppWindowDelegate:
+  int GetActiveTaskId() const override;
 
   const std::vector<aura::Window*>& GetObservedWindows() {
     return observed_windows_;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
index 4e84d91..f0b5ca8 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -75,7 +75,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chromeos/constants/chromeos_switches.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "components/crx_file/id_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
@@ -2199,12 +2199,14 @@
 
   // ShelfAppBrowserTest:
   void SetUp() override {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        chromeos::switches::kShelfHotseat);
+    scoped_feature_list_.InitAndEnableFeature(
+        chromeos::features::kShelfHotseat);
     ShelfAppBrowserTest::SetUp();
   }
 
  private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
   DISALLOW_COPY_AND_ASSIGN(HotseatShelfAppBrowserTest);
 };
 
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index 03bb86b..821294d 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -40,6 +40,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/app_service_test.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/crostini/crostini_test_helper.h"
@@ -159,10 +161,6 @@
 constexpr char kWebAppId[] = "lpikggcgamknpihimepdkohalcnpofed";
 constexpr char kWebAppUrl[] = "https://foo.example/";
 
-constexpr char kCameraAppName[] = "Camera";
-constexpr char kCameraAppPackage[] = "com.google.android.GoogleCameraArc";
-constexpr char kCameraAppActivity[] = "com.android.camera.CameraLauncher";
-
 // Test implementation of AppIconLoader.
 class TestAppIconLoaderImpl : public AppIconLoader {
  public:
@@ -1032,6 +1030,7 @@
         {extension_misc::kGoogleSheetsAppId, "Sheets"},
         {extension_misc::kGoogleSlidesAppId, "Slides"},
         {extension_misc::kFilesManagerAppId, "Files"},
+        {extension_misc::kCameraAppId, "Camera"},
         {extension_misc::kGooglePhotosAppId, "Photos"},
     };
 
@@ -1213,15 +1212,6 @@
         ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED);
     ash::MultiUserWindowManagerImpl::Get()->OnActiveUserSessionChanged(
         account_id);
-    // TODO(crbug.com/956841) This should be redundant with the FlushBindings
-    // call, but removing it breaks some tests.
-    launcher_controller_->browser_status_monitor_for_test()->ActiveUserChanged(
-        account_id.GetUserEmail());
-
-    for (const auto& controller :
-         launcher_controller_->app_window_controllers_for_test()) {
-      controller->ActiveUserChanged(account_id.GetUserEmail());
-    }
   }
 
   // Creates a browser with a |profile| and load a tab with a |title| and |url|.
@@ -2298,6 +2288,7 @@
   arc::mojom::AppInfo app_info = CreateAppInfo(
       "Play Store", arc::kPlayStoreActivity, arc::kPlayStorePackage);
   EXPECT_EQ(arc::kPlayStoreAppId, AddArcAppAndShortcut(app_info));
+  app_service_test().WaitForAppService();
 
   std::string window_app_id("org.chromium.arc.1");
   const ash::ShelfID play_store_shelf_id(arc::kPlayStoreAppId);
@@ -3377,6 +3368,7 @@
   EXPECT_EQ(1, model_->item_count());
 
   // Add a v2 app.
+  AddExtension(extension1_.get());
   V2App v2_app(profile(), extension1_.get());
   EXPECT_EQ(2, model_->item_count());
 
@@ -3411,6 +3403,7 @@
   // Add the v2 app to the inactive user and check that no item was added to
   // the launcher.
   {
+    AddExtension(extension1_.get());
     V2App v2_app(profile(), extension1_.get());
     EXPECT_EQ(1, model_->item_count());
 
@@ -3424,6 +3417,7 @@
     EXPECT_EQ(1, model_->item_count());
   }
 
+  app_service_test().WaitForAppService();
   // After the application was killed there should still be 1 item.
   EXPECT_EQ(1, model_->item_count());
 
@@ -3505,13 +3499,27 @@
       multi_user_util::GetAccountIdFromProfile(profile2));
   const AccountId account_id3(
       multi_user_util::GetAccountIdFromProfile(profile3));
+
+  extensions::TestExtensionSystem* extension_system1(
+      static_cast<extensions::TestExtensionSystem*>(
+          extensions::ExtensionSystem::Get(profile1)));
+  extensions::ExtensionService* extension_service1 =
+      extension_system1->CreateExtensionService(
+          base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
+  extension_service1->Init();
+  apps::AppServiceProxy* proxy1 =
+      apps::AppServiceProxyFactory::GetForProfile(profile1);
+
   SwitchActiveUser(account_id1);
 
-  // A v2 app for user #1 should be shown first and get hidden when switching to
-  // desktop #2.
+  // A v2 app for user #1 should be shown first and get hidden when switching
+  // to desktop #2.
+  extension_service1->AddExtension(extension1_.get());
+  proxy1->FlushMojoCallsForTesting();
   V2App v2_app_1(profile1, extension1_.get());
   EXPECT_TRUE(v2_app_1.window()->GetNativeWindow()->IsVisible());
   SwitchActiveUser(account_id2);
+  app_service_test().FlushMojoCalls();
   EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible());
 
   // Add a v2 app for user #1 while on desktop #2 should not be shown.
@@ -3535,15 +3543,17 @@
   // Switching back to desktop#1 and creating an app for user #1 should move
   // the app on desktop #1.
   SwitchActiveUser(account_id1);
+  app_service_test().FlushMojoCalls();
   V2App v2_app_4(profile1, extension1_.get());
   EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible());
   EXPECT_TRUE(v2_app_2.window()->GetNativeWindow()->IsVisible());
   EXPECT_FALSE(v2_app_3.window()->GetNativeWindow()->IsVisible());
   EXPECT_TRUE(v2_app_4.window()->GetNativeWindow()->IsVisible());
 
-  // Switching to desktop #3 and creating an app for user #1 should place it on
-  // that user's desktop (#1).
+  // Switching to desktop #3 and creating an app for user #1 should place it
+  // on that user's desktop (#1).
   SwitchActiveUser(account_id3);
+  app_service_test().FlushMojoCalls();
   V2App v2_app_5(profile1, extension1_.get());
   EXPECT_FALSE(v2_app_5.window()->GetNativeWindow()->IsVisible());
   SwitchActiveUser(account_id1);
@@ -3552,6 +3562,7 @@
   // Switching to desktop #2, hiding the app window and creating an app should
   // teleport there automatically.
   SwitchActiveUser(account_id2);
+  app_service_test().FlushMojoCalls();
   v2_app_1.window()->Hide();
   V2App v2_app_6(profile1, extension1_.get());
   EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible());
@@ -3573,6 +3584,7 @@
   SwitchActiveUser(account_id);
   EXPECT_EQ(1, model_->item_count());
 
+  AddExtension(extension1_.get());
   V2App v2_app_1(profile(), extension1_.get());
   EXPECT_EQ(2, model_->item_count());
   {
@@ -4167,59 +4179,6 @@
   EXPECT_TRUE(window2->IsActive());
 }
 
-// Test that ARC camera app can successfully open and close.
-TEST_F(ChromeLauncherControllerWithArcTest, ArcCameraAppOpenAndClose) {
-  InitLauncherControllerWithBrowser();
-
-  const arc::mojom::AppInfo appinfo =
-      CreateAppInfo(kCameraAppName, kCameraAppActivity, kCameraAppPackage);
-
-  // Widgets will be deleted by the system.
-  views::Widget* window1 = CreateArcWindow("org.chromium.arc.1");
-  NotifyOnTaskCreated(appinfo, 1 /* task_id */);
-  ASSERT_TRUE(window1);
-  EXPECT_TRUE(window1->IsActive());
-
-  // After starting the ARC camera app, it's actually the internal camera app
-  // being put onto the shelf. Therefore, we need to specify the internal
-  // camera app shelf ID to access it.
-  const std::string intern_app_id(ash::kInternalAppIdCamera);
-  const ash::ShelfID intern_shelf_id(intern_app_id);
-  EXPECT_TRUE(launcher_controller_->IsOpen(intern_shelf_id));
-
-  NotifyOnTaskDestroyed(1 /* task_id */);
-  window1->Close();
-
-  EXPECT_FALSE(launcher_controller_->IsOpen(intern_shelf_id));
-}
-
-// Test that the app menu item count is 1 for the built-in camera app.
-TEST_F(ChromeLauncherControllerWithArcTest, ArcCameraAppMenuItemsCount) {
-  InitLauncherControllerWithBrowser();
-
-  const arc::mojom::AppInfo appinfo =
-      CreateAppInfo(kCameraAppName, kCameraAppActivity, kCameraAppPackage);
-
-  // Widgets will be deleted by the system.
-  views::Widget* window1 = CreateArcWindow("org.chromium.arc.1");
-  NotifyOnTaskCreated(appinfo, 1 /* task_id */);
-  ASSERT_TRUE(window1);
-  EXPECT_TRUE(window1->IsActive());
-
-  // After starting the ARC camera app, it's actually the internal camera app
-  // being put onto the shelf. Therefore, we need to specify the internal
-  // camera app shelf ID to access it.
-  const std::string intern_app_id(ash::kInternalAppIdCamera);
-  ash::ShelfItemDelegate* item_delegate =
-      model_->GetShelfItemDelegate(ash::ShelfID(intern_app_id));
-  ASSERT_TRUE(item_delegate);
-
-  // We want to make sure there's only 1 menu item for camera app, even if both
-  // ARC window and internal app window might have been added to
-  // AppWindowLauncherItemController.
-  ASSERT_EQ(1u, item_delegate->GetAppMenuItems(ui::EF_NONE).size());
-}
-
 namespace {
 class ChromeLauncherControllerArcDefaultAppsTest
     : public ChromeLauncherControllerTest {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc
index 79f7765a..2a69e4c 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.cc
@@ -130,9 +130,3 @@
 
   return AppListControllerDelegate::PIN_EDITABLE;
 }
-
-bool IsCameraApp(const std::string& app_id) {
-  return app_id == arc::kCameraAppId || app_id == arc::kLegacyCameraAppId ||
-         app_id == arc::kCameraMigrationAppId ||
-         app_id == extension_misc::kChromeCameraAppId;
-}
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h
index 4106436..abb4b54 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h
@@ -21,8 +21,4 @@
     const std::string& app_id,
     Profile* profile);
 
-// Returns true if |app_id| specifies one of the Android cameras or Chrome
-// camera.
-bool IsCameraApp(const std::string& app_id);
-
 #endif  // CHROME_BROWSER_UI_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_UTIL_H_
diff --git a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
index c03e8d8d..d43a5e28b 100644
--- a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
@@ -31,9 +31,6 @@
 
 // Get the ShelfID for a given |app_window|.
 ash::ShelfID GetShelfId(AppWindow* app_window) {
-  if (IsCameraApp(app_window->extension_id()))
-    return ash::ShelfID(ash::kInternalAppIdCamera);
-
   // Set launch_id default value to an empty string. If showInShelf parameter
   // is true and the window key is not empty, its value is appended to the
   // launch_id. Otherwise, if the window key is empty, the session_id is used.
diff --git a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
index afb39fb..2611a47 100644
--- a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h"
 #include "components/exo/shell_surface_util.h"
 #include "components/user_manager/user_manager.h"
+#include "extensions/common/constants.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
@@ -170,10 +171,6 @@
 
 void InternalAppWindowShelfController::AddToShelf(AppWindowBase* app_window) {
   const ash::ShelfID shelf_id = app_window->shelf_id();
-  // Internal Camera app does not have own window. Either ARC or extension
-  // window controller would add window to controller.
-  if (shelf_id.app_id == ash::kInternalAppIdCamera)
-    return;
 
   AppWindowLauncherItemController* item_controller =
       owner()->shelf_model()->GetAppWindowLauncherItemController(shelf_id);
@@ -198,10 +195,6 @@
 void InternalAppWindowShelfController::RemoveFromShelf(
     AppWindowBase* app_window) {
   const ash::ShelfID shelf_id = app_window->shelf_id();
-  // Internal Camera app does not have own window. Either ARC or extension
-  // window controller would remove window from controller.
-  if (shelf_id.app_id == ash::kInternalAppIdCamera)
-    return;
 
   UnregisterAppWindow(app_window);
 
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index ed842a4..68ab304 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -82,6 +82,7 @@
 #else  // !OS_ANDROID
 #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/save_upi_bubble_controller_impl.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/webauthn_dialog_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/webauthn_dialog_state.h"
 #include "chrome/browser/ui/autofill/payments/webauthn_dialog_view.h"
@@ -328,6 +329,15 @@
       autofill::SaveUPIBubbleControllerImpl::FromWebContents(web_contents());
   controller->OfferUpiIdLocalSave(upi_id, std::move(callback));
 }
+
+void ChromeAutofillClient::OfferVirtualCardOptions(
+    const std::vector<CreditCard*>& candidates,
+    base::OnceCallback<void(const std::string&)> callback) {
+  VirtualCardSelectionDialogControllerImpl::CreateForWebContents(
+      web_contents());
+  VirtualCardSelectionDialogControllerImpl::FromWebContents(web_contents())
+      ->ShowDialog(candidates, std::move(callback));
+}
 #endif
 
 void ChromeAutofillClient::ConfirmSaveAutofillProfile(
@@ -452,9 +462,9 @@
   return CreditCardScannerController::HasCreditCardScanFeature();
 }
 
-void ChromeAutofillClient::ScanCreditCard(
-    const CreditCardScanCallback& callback) {
-  CreditCardScannerController::ScanCreditCard(web_contents(), callback);
+void ChromeAutofillClient::ScanCreditCard(CreditCardScanCallback callback) {
+  CreditCardScannerController::ScanCreditCard(web_contents(),
+                                              std::move(callback));
 }
 
 void ChromeAutofillClient::ShowAutofillPopup(
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index 27038f64..33eca96 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -101,6 +101,9 @@
   void ConfirmSaveUpiIdLocally(
       const std::string& upi_id,
       base::OnceCallback<void(bool accept)> callback) override;
+  void OfferVirtualCardOptions(
+      const std::vector<CreditCard*>& candidates,
+      base::OnceCallback<void(const std::string&)> callback) override;
 #endif  // !defined(OS_ANDROID)
   void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
                                   base::OnceClosure callback) override;
@@ -125,7 +128,7 @@
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    base::OnceClosure callback) override;
   bool HasCreditCardScanFeature() override;
-  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ScanCreditCard(CreditCardScanCallback callback) override;
   void ShowAutofillPopup(
       const gfx::RectF& element_bounds,
       base::i18n::TextDirection text_direction,
diff --git a/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.cc b/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.cc
index 4d94d45e..65a626d 100644
--- a/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.cc
+++ b/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.cc
@@ -26,9 +26,9 @@
                    public base::SupportsWeakPtr<Controller> {
  public:
   Controller(content::WebContents* web_contents,
-             const AutofillClient::CreditCardScanCallback& callback)
+             AutofillClient::CreditCardScanCallback callback)
       : view_(CreditCardScannerView::Create(AsWeakPtr(), web_contents)),
-        callback_(callback) {
+        callback_(std::move(callback)) {
     DCHECK(view_);
   }
 
@@ -52,7 +52,7 @@
   void ScanCompleted(const CreditCard& card) override {
     AutofillMetrics::LogScanCreditCardCompleted(
         base::TimeTicks::Now() - show_time_, true);
-    callback_.Run(card);
+    std::move(callback_).Run(card);
     delete this;
   }
 
@@ -79,8 +79,8 @@
 // static
 void CreditCardScannerController::ScanCreditCard(
     content::WebContents* web_contents,
-    const AutofillClient::CreditCardScanCallback& callback) {
-  (new Controller(web_contents, callback))->Show();
+    AutofillClient::CreditCardScanCallback callback) {
+  (new Controller(web_contents, std::move(callback)))->Show();
 }
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h b/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h
index 3a9657c..dab157d 100644
--- a/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h
+++ b/chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h
@@ -25,9 +25,8 @@
   // |web_contents|. Notifies the |delegate| when scanning completes
   // successfully. Destroys itself when the UI is dismissed. Should be called
   // only if HasCreditCardScanScanFeature() returns true.
-  static void ScanCreditCard(
-      content::WebContents* web_contents,
-      const AutofillClient::CreditCardScanCallback& callback);
+  static void ScanCreditCard(content::WebContents* web_contents,
+                             AutofillClient::CreditCardScanCallback callback);
 };
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller.h b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller.h
new file mode 100644
index 0000000..401717c
--- /dev/null
+++ b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller.h
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_H_
+#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "base/strings/string16.h"
+
+namespace autofill {
+
+class CreditCard;
+
+// An interface that exposes necessary controller functionality to
+// VirtualCardSelectionDialogView.
+class VirtualCardSelectionDialogController {
+ public:
+  virtual ~VirtualCardSelectionDialogController() = default;
+
+  virtual bool IsOkButtonEnabled() = 0;
+
+  virtual base::string16 GetContentTitle() const = 0;
+  virtual base::string16 GetContentExplanation() const = 0;
+  virtual base::string16 GetOkButtonLabel() const = 0;
+  virtual base::string16 GetCancelButtonLabel() const = 0;
+
+  virtual const std::vector<CreditCard*>& GetCardList() const = 0;
+
+  virtual void OnCardSelected(const std::string& selected_card_id) = 0;
+  virtual void OnOkButtonClicked() = 0;
+  virtual void OnCancelButtonClicked() = 0;
+  virtual void OnDialogClosed() = 0;
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.cc b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.cc
new file mode 100644
index 0000000..477f6b5
--- /dev/null
+++ b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.cc
@@ -0,0 +1,106 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h"
+
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h"
+#include "components/autofill/core/browser/data_model/credit_card.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace autofill {
+
+VirtualCardSelectionDialogControllerImpl::
+    VirtualCardSelectionDialogControllerImpl(content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents) {}
+
+VirtualCardSelectionDialogControllerImpl::
+    ~VirtualCardSelectionDialogControllerImpl() {
+  // This part of code is executed only if browser window is closed when the
+  // dialog is visible. In this case the controller is destroyed before
+  // VirtualCardSelectionDialogViewImpl::dtor() being called, but the reference
+  // to controller is not reset. Need to reset via
+  // VirtualCardSelectionDialogViewImpl::Hide() to avoid crash.
+  if (dialog_view_)
+    dialog_view_->Hide();
+}
+
+void VirtualCardSelectionDialogControllerImpl::ShowDialog(
+    const std::vector<CreditCard*>& candidates,
+    base::OnceCallback<void(const std::string&)> callback) {
+  DCHECK(!dialog_view_);
+
+  candidates_ = candidates;
+  // If there is only one card available, the card will be selected by default.
+  // TODO(crbug.com/1020740): Change this to |instrument_token| when a card can
+  // have multiple cloud token data.
+  if (candidates_.size() == 1)
+    selected_card_id_ = candidates_[0]->server_id();
+
+  callback_ = std::move(callback);
+  dialog_view_ =
+      VirtualCardSelectionDialogView::CreateAndShow(this, web_contents());
+}
+
+bool VirtualCardSelectionDialogControllerImpl::IsOkButtonEnabled() {
+  // The OK button is set to be disabled at first when there are multiple
+  // cards. A card must be selected to enable the OK button.
+  return !selected_card_id_.empty();
+}
+
+base::string16 VirtualCardSelectionDialogControllerImpl::GetContentTitle()
+    const {
+  return l10n_util::GetPluralStringFUTF16(
+      IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CONTENT_TITLE,
+      candidates_.size());
+}
+
+base::string16 VirtualCardSelectionDialogControllerImpl::GetContentExplanation()
+    const {
+  return l10n_util::GetPluralStringFUTF16(
+      IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CONTENT_EXPLANATION,
+      candidates_.size());
+}
+
+base::string16 VirtualCardSelectionDialogControllerImpl::GetOkButtonLabel()
+    const {
+  return l10n_util::GetStringUTF16(
+      IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_OK_BUTTON_LABEL);
+}
+
+base::string16 VirtualCardSelectionDialogControllerImpl::GetCancelButtonLabel()
+    const {
+  return l10n_util::GetStringUTF16(
+      IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CANCEL_BUTTON_LABEL);
+}
+
+const std::vector<CreditCard*>&
+VirtualCardSelectionDialogControllerImpl::GetCardList() const {
+  return candidates_;
+}
+
+void VirtualCardSelectionDialogControllerImpl::OnCardSelected(
+    const std::string& selected_card_id) {
+  selected_card_id_ = selected_card_id;
+}
+
+void VirtualCardSelectionDialogControllerImpl::OnOkButtonClicked() {
+  DCHECK(callback_);
+  DCHECK(!selected_card_id_.empty());
+  std::move(callback_).Run(selected_card_id_);
+  // TODO(crbug.com/1020740): Add metrics.
+}
+
+void VirtualCardSelectionDialogControllerImpl::OnCancelButtonClicked() {
+  // TODO(crbug.com/1020740): Add metrics.
+}
+
+void VirtualCardSelectionDialogControllerImpl::OnDialogClosed() {
+  dialog_view_ = nullptr;
+  callback_.Reset();
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(VirtualCardSelectionDialogControllerImpl)
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h
new file mode 100644
index 0000000..7e9509a
--- /dev/null
+++ b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h
@@ -0,0 +1,72 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_IMPL_H_
+#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_IMPL_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace autofill {
+
+class VirtualCardSelectionDialogView;
+
+// Implementation of the per-tab controller to control the
+// VirtualCardSelectionDialogView. Lazily initialized when used.
+class VirtualCardSelectionDialogControllerImpl
+    : public VirtualCardSelectionDialogController,
+      public content::WebContentsObserver,
+      public content::WebContentsUserData<
+          VirtualCardSelectionDialogControllerImpl> {
+ public:
+  ~VirtualCardSelectionDialogControllerImpl() override;
+
+  void ShowDialog(const std::vector<CreditCard*>& candidates,
+                  base::OnceCallback<void(const std::string&)> callback);
+
+  // VirtualCardSelectionDialogController:
+  bool IsOkButtonEnabled() override;
+  base::string16 GetContentTitle() const override;
+  base::string16 GetContentExplanation() const override;
+  base::string16 GetOkButtonLabel() const override;
+  base::string16 GetCancelButtonLabel() const override;
+  const std::vector<CreditCard*>& GetCardList() const override;
+  void OnCardSelected(const std::string& selected_card_id) override;
+  void OnOkButtonClicked() override;
+  void OnCancelButtonClicked() override;
+  void OnDialogClosed() override;
+
+  VirtualCardSelectionDialogView* dialog_view() { return dialog_view_; }
+
+ protected:
+  explicit VirtualCardSelectionDialogControllerImpl(
+      content::WebContents* web_contents);
+
+ private:
+  friend class content::WebContentsUserData<
+      VirtualCardSelectionDialogControllerImpl>;
+
+  // Local copy of all the candidate cards.
+  std::vector<CreditCard*> candidates_;
+
+  // The identifier of the selected card in the list. When there is more than
+  // one card, no card is set to be selected by default.
+  std::string selected_card_id_;
+
+  // Callback invoked when a card from the |candidates_| is selected and dialog
+  // is accepted. Will pass the |selected_card_id_| as the param.
+  base::OnceCallback<void(const std::string&)> callback_;
+
+  VirtualCardSelectionDialogView* dialog_view_ = nullptr;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+
+  DISALLOW_COPY_AND_ASSIGN(VirtualCardSelectionDialogControllerImpl);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h
new file mode 100644
index 0000000..5ed5350
--- /dev/null
+++ b/chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_H_
+#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_H_
+
+#include "base/macros.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace autofill {
+
+class VirtualCardSelectionDialogController;
+
+// The view of the dialog that offers the all the available credit cards that
+// can be used as virtual card. Shown when the option of using a virtual card is
+// clicked in the Autofill popup bubble.
+class VirtualCardSelectionDialogView {
+ public:
+  static VirtualCardSelectionDialogView* CreateAndShow(
+      VirtualCardSelectionDialogController* controller,
+      content::WebContents* web_content);
+
+  virtual void Hide() = 0;
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/blocked_content/popup_blocker.cc b/chrome/browser/ui/blocked_content/popup_blocker.cc
index e930af6..80e1004 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
 #include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
-#include "chrome/common/chrome_switches.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings.h"
+#include "components/embedder_support/switches.h"
 #include "components/safe_browsing/triggers/ad_popup_trigger.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/render_frame_host.h"
@@ -30,7 +30,7 @@
                                 bool user_gesture,
                                 const content::OpenURLParams* open_url_params) {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisablePopupBlocking)) {
+          embedder_support::kDisablePopupBlocking)) {
     return PopupBlockType::kNotBlocked;
   }
   // If an explicit opener is not given, use the current committed load in this
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index 759db40f..9c0caf2 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -33,7 +33,6 @@
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -44,6 +43,7 @@
 #include "components/app_modal/javascript_dialog_manager.h"
 #include "components/app_modal/native_app_modal_dialog.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/embedder_support/switches.h"
 #include "components/omnibox/browser/autocomplete_match.h"
 #include "components/omnibox/browser/autocomplete_result.h"
 #include "components/omnibox/browser/omnibox_edit_model.h"
@@ -435,7 +435,7 @@
 
 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, NoPopupsLaunchWhenTabIsClosed) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   GURL url(
       embedded_test_server()->GetURL("/popup_blocker/popup-on-unload.html"));
   ui_test_utils::NavigateToURL(browser(), url);
@@ -485,7 +485,7 @@
 IN_PROC_BROWSER_TEST_F(PopupBlockerSpecialPolicyBrowserTest,
                        AllowPopupsWhenTabIsClosedWithSpecialPolicy) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   GURL url(
       embedded_test_server()->GetURL("/popup_blocker/popup-on-unload.html"));
   ui_test_utils::NavigateToURL(browser(), url);
@@ -498,7 +498,7 @@
 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
                        UnblockedPopupShowsInHistoryAndOmnibox) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   GURL url(embedded_test_server()->GetURL(
       "/popup_blocker/popup-blocked-to-post-blank.html"));
   NavigateAndCheckPopupShown(url, kExpectForegroundTab);
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index d17a197..8e27d8a 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -75,6 +75,7 @@
 #include "components/app_modal/javascript_app_modal_dialog.h"
 #include "components/app_modal/native_app_modal_dialog.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/embedder_support/switches.h"
 #include "components/omnibox/common/omnibox_focus_state.h"
 #include "components/prefs/pref_service.h"
 #include "components/sessions/core/base_session_service_test_helper.h"
@@ -1027,7 +1028,7 @@
 // See http://crbug.com/93517.
 IN_PROC_BROWSER_TEST_F(BrowserTest, NullOpenerRedirectForksProcess) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
 
   // Create http and https servers for a cross-site transition.
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -1112,7 +1113,7 @@
 // fork a new renderer process.
 IN_PROC_BROWSER_TEST_F(BrowserTest, OtherRedirectsDontForkProcess) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
 
   // Create http and https servers for a cross-site transition.
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -2029,7 +2030,7 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose1) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url = embedded_test_server()->GetURL("/window.close.html");
   GURL::Replacements add_query;
@@ -2046,7 +2047,7 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose2) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url = embedded_test_server()->GetURL("/window.close.html");
   GURL::Replacements add_query;
@@ -2067,7 +2068,7 @@
   ui::CATransactionCoordinator::Get().DisableForTesting();
 #endif
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url = embedded_test_server()->GetURL("/window.close.html");
   GURL::Replacements add_query;
diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
index ad6f588..8a4abd2 100644
--- a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
+++ b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
@@ -174,7 +174,7 @@
 }
 
 // Order of windows.
-IN_PROC_BROWSER_TEST_F(WindowAppleScriptTest, WindowOrder) {
+IN_PROC_BROWSER_TEST_F(WindowAppleScriptTest, DISABLED_WindowOrder) {
   base::scoped_nsobject<WindowAppleScript> window2(
       [[WindowAppleScript alloc] initWithBrowser:browser()]);
   base::scoped_nsobject<WindowAppleScript> window1(
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller_browsertest.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller_browsertest.mm
index 2610388..dca5ca4 100644
--- a/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller_browsertest.mm
@@ -105,8 +105,14 @@
 
 // Tests to see if the touch bar's bookmark tab helper observer gets removed
 // when the touch bar is destroyed.
+// Flaky on Mac ASAN: https://crbug.com/1035117.
+#if defined(ADDRESS_SANITIZER)
+#define MAYBE_DestroyNotificationBridge DISABLED_DestroyNotificationBridge
+#else
+#define MAYBE_DestroyNotificationBridge DestroyNotificationBridge
+#endif
 IN_PROC_BROWSER_TEST_F(BrowserWindowTouchBarControllerTest,
-                       DestroyNotificationBridge) {
+                       MAYBE_DestroyNotificationBridge) {
   if (@available(macOS 10.12.2, *)) {
     MakeTouchBar();
 
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 017a3dd..ff78156 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -703,8 +703,16 @@
   NavigateAndCheckForToolbar(app_browser_, app_url, true);
 }
 
+// Flaky, mostly on Windows: http://crbug.com/1032319
+#if defined(OS_WIN)
+#define MAYBE_ShouldShowCustomTabBarForHTTPAppHTTPSUrl \
+  DISABLED_ShouldShowCustomTabBarForHTTPAppHTTPSUrl
+#else
+#define MAYBE_ShouldShowCustomTabBarForHTTPAppHTTPSUrl \
+  ShouldShowCustomTabBarForHTTPAppHTTPSUrl
+#endif
 IN_PROC_BROWSER_TEST_P(HostedAppTest,
-                       ShouldShowCustomTabBarForHTTPAppHTTPSUrl) {
+                       MAYBE_ShouldShowCustomTabBarForHTTPAppHTTPSUrl) {
   ASSERT_TRUE(https_server()->Start());
 
   const GURL app_url = https_server()->GetURL("app.com", "/simple.html");
diff --git a/chrome/browser/ui/input_method/input_method_engine.cc b/chrome/browser/ui/input_method/input_method_engine.cc
index 3c346df..af44b36 100644
--- a/chrome/browser/ui/input_method/input_method_engine.cc
+++ b/chrome/browser/ui/input_method/input_method_engine.cc
@@ -23,12 +23,17 @@
 
 namespace {
 
+const char kErrorWrongContext[] = "Context is not active.";
 const char kErrorFollowCursorWindowExists[] =
     "A follow cursor IME window exists.";
 const char kErrorNoInputFocus[] =
     "The follow cursor IME window cannot be created without an input focus.";
 const char kErrorReachMaxWindowCount[] =
     "Cannot create more than 5 normal IME windows.";
+const char kErrorSentKeyEventsNotAllowed[] =
+    "input.ime.sendKeyEvents API is not allowed on non-text fields.";
+const char kErrorSpecialKeysNotAllowed[] =
+    "ENTER et al. keys are allowed only on http:, https: etc.";
 
 const int kMaxNormalWindowCount = 5;
 
@@ -120,25 +125,34 @@
 }
 
 bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event,
-                                     const std::string& code) {
+                                     const std::string& code,
+                                     std::string* error) {
   DCHECK(event);
 
   // input.ime.sendKeyEvents API is only allowed to work on text fields.
-  if (current_input_type_ == ui::TEXT_INPUT_TYPE_NONE)
+  if (current_input_type_ == ui::TEXT_INPUT_TYPE_NONE) {
+    *error =
+        base::StringPrintf("%s current input type = %d",
+                           kErrorSentKeyEventsNotAllowed, current_input_type_);
     return false;
+  }
 
   if (event->key_code() == ui::VKEY_UNKNOWN)
     event->set_key_code(ui::DomCodeToUsLayoutKeyboardCode(event->code()));
 
   ui::IMEInputContextHandlerInterface* input_context =
       ui::IMEBridge::Get()->GetInputContextHandler();
-  if (!input_context)
+  if (!input_context) {
+    *error = kErrorWrongContext;
     return false;
+  }
 
   // ENTER et al. keys are allowed to work only on http:, https: etc.
   if (!IsValidKeyForAllPages(event)) {
-    if (IsSpecialPage(input_context->GetInputMethod()))
+    if (IsSpecialPage(input_context->GetInputMethod())) {
+      *error = kErrorSpecialKeysNotAllowed;
       return false;
+    }
   }
 
   input_context->SendKeyEvent(event);
diff --git a/chrome/browser/ui/input_method/input_method_engine.h b/chrome/browser/ui/input_method/input_method_engine.h
index 5908a93..b8105c7 100644
--- a/chrome/browser/ui/input_method/input_method_engine.h
+++ b/chrome/browser/ui/input_method/input_method_engine.h
@@ -40,7 +40,11 @@
 
   void CommitTextToInputContext(int context_id,
                                 const std::string& text) override;
-  bool SendKeyEvent(ui::KeyEvent* ui_event, const std::string& code) override;
+
+  bool SendKeyEvent(ui::KeyEvent* ui_event,
+                    const std::string& code,
+                    std::string* error) override;
+
   bool IsActive() const override;
 
   std::string GetExtensionId() const;
diff --git a/chrome/browser/ui/input_method/input_method_engine_base.cc b/chrome/browser/ui/input_method/input_method_engine_base.cc
index 44ad487a..920a0cf 100644
--- a/chrome/browser/ui/input_method/input_method_engine_base.cc
+++ b/chrome/browser/ui/input_method/input_method_engine_base.cc
@@ -39,9 +39,9 @@
 
 namespace {
 
-const char kErrorNotActive[] = "IME is not active";
-const char kErrorWrongContext[] = "Context is not active";
-const char kErrorInvalidValue[] = "Argument '%s' with value '%d' is not valid";
+const char kErrorNotActive[] = "IME is not active.";
+const char kErrorWrongContext[] = "Context is not active.";
+const char kErrorInvalidValue[] = "Argument '%s' with value '%d' is not valid.";
 
 #if defined(OS_CHROMEOS)
 std::string GetKeyFromEvent(const ui::KeyEvent& event) {
@@ -284,7 +284,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
 
@@ -301,7 +303,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
 
@@ -312,7 +316,9 @@
 bool InputMethodEngineBase::FinishComposingText(int context_id,
                                                 std::string* error) {
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
   ConfirmCompositionText(/* reset_engine */ false, /* keep_selection */ true);
@@ -328,7 +334,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
 
@@ -341,12 +349,20 @@
 
 bool InputMethodEngineBase::SendKeyEvents(
     int context_id,
-    const std::vector<KeyboardEvent>& events) {
+    const std::vector<KeyboardEvent>& events,
+    std::string* error) {
+  if (!IsActive()) {
+    *error = kErrorNotActive;
+    return false;
+  }
   // context_id  ==  0, means sending key events to non-input field.
   // context_id_ == -1, means the focus is not in an input field.
-  if (!IsActive() ||
-      (context_id != 0 && (context_id != context_id_ || context_id_ == -1)))
+  if ((context_id != 0 && (context_id != context_id_ || context_id_ == -1))) {
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
+  }
 
   for (size_t i = 0; i < events.size(); ++i) {
     const KeyboardEvent& event = events[i];
@@ -365,7 +381,7 @@
         type, key_code, ui::KeycodeConverter::CodeStringToDomCode(event.code),
         flags, ui::KeycodeConverter::KeyStringToDomKey(event.key),
         ui::EventTimeForNow());
-    if (!SendKeyEvent(&ui_event, event.code))
+    if (!SendKeyEvent(&ui_event, event.code, error))
       return false;
   }
   return true;
@@ -384,7 +400,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
 
@@ -433,7 +451,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
 
@@ -486,7 +506,9 @@
     return false;
   }
   if (context_id != context_id_ || context_id_ == -1) {
-    *error = kErrorWrongContext;
+    *error = base::StringPrintf(
+        "%s request context id = %d, current context id = %d",
+        kErrorWrongContext, context_id, context_id_);
     return false;
   }
   if (!IsUint32Value(start)) {
diff --git a/chrome/browser/ui/input_method/input_method_engine_base.h b/chrome/browser/ui/input_method/input_method_engine_base.h
index 687ee43..e252b979 100644
--- a/chrome/browser/ui/input_method/input_method_engine_base.h
+++ b/chrome/browser/ui/input_method/input_method_engine_base.h
@@ -180,7 +180,9 @@
   bool FinishComposingText(int context_id, std::string* error);
 
   // Send the sequence of key events.
-  bool SendKeyEvents(int context_id, const std::vector<KeyboardEvent>& events);
+  bool SendKeyEvents(int context_id,
+                     const std::vector<KeyboardEvent>& events,
+                     std::string* error);
 
   // Set the current composition and associated properties.
   bool SetComposition(int context_id,
@@ -256,11 +258,14 @@
   // Notifies InputContextHanlder to commit |text|.
   virtual void CommitTextToInputContext(int context_id,
                                         const std::string& text) = 0;
+
   // Notifies InputContextHandler to delete surrounding text.
   void DeleteSurroundingTextToInputContext(int offset, size_t number_of_chars);
+
   // Sends the key event to the window tree host.
   virtual bool SendKeyEvent(ui::KeyEvent* ui_event,
-                            const std::string& code) = 0;
+                            const std::string& code,
+                            std::string* error) = 0;
 
   ui::TextInputType current_input_type_;
 
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
index 4c1d2ff..862f31f 100644
--- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
+++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "components/ukm/content/source_url_recorder.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "content/public/browser/render_frame_host.h"
@@ -59,7 +59,7 @@
   // Turn off popup blocking.
   base::test::ScopedCommandLine scoped_command_line;
   scoped_command_line.GetProcessCommandLine()->AppendSwitch(
-      switches::kDisablePopupBlocking);
+      embedder_support::kDisablePopupBlocking);
 
   // Two tabs, one render process.
   content::WebContents* tab1 =
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc
index 1fb49df..33f5f9a 100644
--- a/chrome/browser/ui/popup_browsertest.cc
+++ b/chrome/browser/ui/popup_browsertest.cc
@@ -11,6 +11,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/common/content_switches.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
@@ -29,7 +30,7 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     InProcessBrowserTest::SetUpCommandLine(command_line);
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kDisablePopupBlocking);
+        embedder_support::kDisablePopupBlocking);
     const bool enable_window_placement = GetParam();
     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
         enable_window_placement ? switches::kEnableBlinkFeatures
diff --git a/chrome/browser/ui/renderer_event_injection_browsertest.cc b/chrome/browser/ui/renderer_event_injection_browsertest.cc
index c952fa0e..7f3ea705 100644
--- a/chrome/browser/ui/renderer_event_injection_browsertest.cc
+++ b/chrome/browser/ui/renderer_event_injection_browsertest.cc
@@ -87,8 +87,8 @@
         for (unsigned i = 0; i < web_touch.touches_length; i++) {
           const blink::WebTouchPoint& touch_point = web_touch.touches[i];
           const gfx::Point location(
-              static_cast<int>(touch_point.PositionInWidget().x),
-              static_cast<int>(touch_point.PositionInWidget().y));
+              static_cast<int>(touch_point.PositionInWidget().x()),
+              static_cast<int>(touch_point.PositionInWidget().y()));
           if (touch_point.state == blink::WebTouchPoint::kStatePressed &&
               location == expected_location_) {
             quit_closure_.Run();
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
index 644102cc..098e347 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
@@ -235,8 +235,7 @@
 
     content::WebContents* contents = web_ui()->GetWebContents();
     content::StoragePartition* partition =
-        content::BrowserContext::GetStoragePartitionForSite(
-            contents->GetBrowserContext(), signin::GetSigninPartitionURL());
+        signin::GetSigninPartition(contents->GetBrowserContext());
 
     // Regardless of the results of ParseArgs, |signin_callback_| will always
     // be called to allow it to release any additional references it may hold
diff --git a/chrome/browser/ui/startup/startup_tab_provider.cc b/chrome/browser/ui/startup/startup_tab_provider.cc
index 194e2d5..3e5b36d 100644
--- a/chrome/browser/ui/startup/startup_tab_provider.cc
+++ b/chrome/browser/ui/startup/startup_tab_provider.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_util.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/chrome_pages.h"
@@ -57,7 +58,8 @@
   PrefService* prefs = profile->GetPrefs();
   standard_params.has_seen_welcome_page =
       prefs && prefs->GetBoolean(prefs::kHasSeenWelcomePage);
-  standard_params.is_signin_allowed = profile->IsSyncAllowed();
+  standard_params.is_signin_allowed =
+      ProfileSyncServiceFactory::IsSyncAllowed(profile);
   if (auto* identity_manager = IdentityManagerFactory::GetForProfile(profile)) {
     standard_params.is_signed_in = identity_manager->HasPrimaryAccount();
   }
@@ -76,7 +78,8 @@
   if (!process_startup || !browser_creator)
     return tabs;
   if (browser_creator->welcome_back_page() &&
-      CanShowWelcome(profile->IsSyncAllowed(), profile->IsSupervised(),
+      CanShowWelcome(ProfileSyncServiceFactory::IsSyncAllowed(profile),
+                     profile->IsSupervised(),
                      signin_util::IsForceSigninEnabled())) {
     tabs.emplace_back(GetWelcomePageUrl(false), false);
   }
diff --git a/chrome/browser/ui/sync/sync_promo_ui.cc b/chrome/browser/ui/sync/sync_promo_ui.cc
index f84177a7..75c2d526 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.cc
+++ b/chrome/browser/ui/sync/sync_promo_ui.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_promo_util.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/sync/base/sync_prefs.h"
 
 bool SyncPromoUI::ShouldShowSyncPromo(Profile* profile) {
@@ -16,8 +17,10 @@
 
   syncer::SyncPrefs prefs(profile->GetPrefs());
   // Don't show if sync is not allowed to start or is running in local mode.
-  if (!profile->IsSyncAllowed() || prefs.IsLocalSyncEnabled())
+  if (!ProfileSyncServiceFactory::IsSyncAllowed(profile) ||
+      prefs.IsLocalSyncEnabled()) {
     return false;
+  }
 
   return true;
 }
diff --git a/chrome/browser/ui/views/apps/app_uninstall_dialog_view.cc b/chrome/browser/ui/views/apps/app_uninstall_dialog_view.cc
index b9a1ad8..aaf02ad 100644
--- a/chrome/browser/ui/views/apps/app_uninstall_dialog_view.cc
+++ b/chrome/browser/ui/views/apps/app_uninstall_dialog_view.cc
@@ -287,6 +287,7 @@
       break;
     case apps::mojom::AppType::kExtension:
     case apps::mojom::AppType::kWeb:
+      // TODO(crbug.com/1029221): Implement uninstallation for web apps.
       InitializeViewForExtension(profile, app_id);
       break;
   }
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
index c585b8d..9c84764b 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -60,7 +60,9 @@
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/test/fake_server/fake_server.h"
 #include "components/sync/test/fake_server/fake_server_network_resources.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/back_forward_cache_util.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -216,6 +218,8 @@
         browser()->profile(), username, "password",
         ProfileSyncServiceHarness::SigninType::FAKE_SIGNIN);
 
+    content::BackForwardCacheDisabledTester back_forward_cache_disabled_tester;
+
     // Set up the URL loader factory for the payments client so we can intercept
     // those network requests too.
     test_shared_loader_factory_ =
@@ -228,6 +232,11 @@
         ->GetPaymentsClient()
         ->set_url_loader_factory_for_testing(test_shared_loader_factory_);
 
+    EXPECT_TRUE(back_forward_cache_disabled_tester.IsDisabledForFrameWithReason(
+        GetActiveWebContents()->GetMainFrame()->GetProcess()->GetID(),
+        GetActiveWebContents()->GetMainFrame()->GetRoutingID(),
+        "autofill::ContentAutofillDriver"));
+
     // Set up this class as the ObserverForTest implementation.
     credit_card_save_manager_ = ContentAutofillDriver::GetForRenderFrameHost(
                                     GetActiveWebContents()->GetMainFrame())
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_browsertest.cc b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_browsertest.cc
new file mode 100644
index 0000000..a405f1b0
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_browsertest.cc
@@ -0,0 +1,116 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/run_loop.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller_impl.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/test/test_browser_dialog.h"
+#include "chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "ui/views/controls/button/label_button.h"
+
+namespace autofill {
+
+namespace {
+constexpr char kOneCardTest[] = "OneCard";
+constexpr char kTwoCardsTest[] = "TwoCards";
+}  // namespace
+
+class VirtualCardSelectionDialogBrowserTest : public DialogBrowserTest {
+ public:
+  VirtualCardSelectionDialogBrowserTest() = default;
+
+  // DialogBrowserTest:
+  void ShowUi(const std::string& name) override {
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+
+    // Do lazy initialization of VirtualCardSelectionDialogControllerImpl.
+    VirtualCardSelectionDialogControllerImpl::CreateForWebContents(
+        web_contents);
+
+    CreditCard card1 = test::GetFullServerCard();
+    if (name == kOneCardTest) {
+      controller()->ShowDialog({&card1}, base::DoNothing());
+    } else if (name == kTwoCardsTest) {
+      CreditCard card2 = test::GetFullServerCard();
+      controller()->ShowDialog({&card1, &card2}, base::DoNothing());
+    }
+  }
+
+  VirtualCardSelectionDialogViewImpl* GetDialog() {
+    if (!controller())
+      return nullptr;
+
+    VirtualCardSelectionDialogView* dialog_view = controller()->dialog_view();
+    if (!dialog_view)
+      return nullptr;
+
+    return static_cast<VirtualCardSelectionDialogViewImpl*>(dialog_view);
+  }
+
+  VirtualCardSelectionDialogControllerImpl* controller() {
+    if (!browser() || !browser()->tab_strip_model() ||
+        !browser()->tab_strip_model()->GetActiveWebContents())
+      return nullptr;
+
+    return VirtualCardSelectionDialogControllerImpl::FromWebContents(
+        browser()->tab_strip_model()->GetActiveWebContents());
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(VirtualCardSelectionDialogBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(VirtualCardSelectionDialogBrowserTest,
+                       InvokeUi_OneCard) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_F(VirtualCardSelectionDialogBrowserTest,
+                       CanCloseTabWhileDialogShowing) {
+  ShowUi(kOneCardTest);
+  VerifyUi();
+  browser()->tab_strip_model()->GetActiveWebContents()->Close();
+  base::RunLoop().RunUntilIdle();
+}
+
+// Ensures closing browser while dialog being visible is correctly handled.
+IN_PROC_BROWSER_TEST_F(VirtualCardSelectionDialogBrowserTest,
+                       CanCloseBrowserWhileDialogShowing) {
+  ShowUi(kOneCardTest);
+  VerifyUi();
+  browser()->window()->Close();
+  base::RunLoop().RunUntilIdle();
+}
+
+// Ensures dialog is closed when ok button is clicked when there is one card
+// available.
+IN_PROC_BROWSER_TEST_F(VirtualCardSelectionDialogBrowserTest,
+                       ClickOkButton_OneCard) {
+  ShowUi(kOneCardTest);
+  VerifyUi();
+  ASSERT_TRUE(GetDialog()->GetOkButton()->GetEnabled());
+  GetDialog()->AcceptDialog();
+  base::RunLoop().RunUntilIdle();
+}
+
+// TODO(crbug.com/1020740): Add browser test for OK button when there are two
+// cards. The logic to update button state will be implemented in the CL adding
+// card list in the dialog.
+
+// Ensures dialog is closed when cancel button is clicked.
+IN_PROC_BROWSER_TEST_F(VirtualCardSelectionDialogBrowserTest,
+                       ClickCancelButton) {
+  ShowUi(kOneCardTest);
+  VerifyUi();
+  GetDialog()->CancelDialog();
+  base::RunLoop().RunUntilIdle();
+}
+
+// TODO(crbug.com/1020740): Add more browsertests for interactions.
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.cc b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.cc
new file mode 100644
index 0000000..bc9d60677
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.cc
@@ -0,0 +1,128 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.h"
+
+#include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_controller.h"
+#include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
+#include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "chrome/browser/ui/views/chrome_typography.h"
+#include "components/constrained_window/constrained_window_views.h"
+#include "components/grit/components_scaled_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/background.h"
+#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/style/typography.h"
+#include "ui/views/view.h"
+
+namespace autofill {
+
+VirtualCardSelectionDialogViewImpl::VirtualCardSelectionDialogViewImpl(
+    VirtualCardSelectionDialogController* controller)
+    : controller_(controller) {
+  DialogDelegate::set_button_label(ui::DIALOG_BUTTON_OK,
+                                   controller_->GetOkButtonLabel());
+  DialogDelegate::set_button_label(ui::DIALOG_BUTTON_CANCEL,
+                                   controller_->GetCancelButtonLabel());
+}
+
+VirtualCardSelectionDialogViewImpl::~VirtualCardSelectionDialogViewImpl() {
+  if (controller_) {
+    controller_->OnDialogClosed();
+    controller_ = nullptr;
+  }
+}
+
+// static
+VirtualCardSelectionDialogView* VirtualCardSelectionDialogView::CreateAndShow(
+    VirtualCardSelectionDialogController* controller,
+    content::WebContents* web_content) {
+  VirtualCardSelectionDialogViewImpl* dialog =
+      new VirtualCardSelectionDialogViewImpl(controller);
+  constrained_window::ShowWebModalDialogViews(dialog, web_content);
+  return dialog;
+}
+
+void VirtualCardSelectionDialogViewImpl::Hide() {
+  // Reset controller reference if the controller has been destroyed before the
+  // view being destroyed. This happens if browser window is closed when the
+  // dialog is visible.
+  if (controller_) {
+    controller_->OnDialogClosed();
+    controller_ = nullptr;
+  }
+  GetWidget()->Close();
+}
+
+gfx::Size VirtualCardSelectionDialogViewImpl::CalculatePreferredSize() const {
+  const int width = ChromeLayoutProvider::Get()->GetDistanceMetric(
+      DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
+  return gfx::Size(width, GetHeightForWidth(width));
+}
+
+void VirtualCardSelectionDialogViewImpl::AddedToWidget() {
+  // TODO(crbug.com/1020740): The header image is not ready. Implement it later.
+}
+
+bool VirtualCardSelectionDialogViewImpl::Accept() {
+  controller_->OnOkButtonClicked();
+  return true;
+}
+
+bool VirtualCardSelectionDialogViewImpl::Cancel() {
+  controller_->OnCancelButtonClicked();
+  return true;
+}
+
+bool VirtualCardSelectionDialogViewImpl::IsDialogButtonEnabled(
+    ui::DialogButton button) const {
+  return button == ui::DIALOG_BUTTON_OK ? controller_->IsOkButtonEnabled()
+                                        : true;
+}
+
+ui::ModalType VirtualCardSelectionDialogViewImpl::GetModalType() const {
+  return ui::MODAL_TYPE_CHILD;
+}
+
+views::View* VirtualCardSelectionDialogViewImpl::GetContentsView() {
+  RemoveAllChildViews(/*delete_children=*/true);
+
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kVertical, gfx::Insets(),
+      ChromeLayoutProvider::Get()->GetDistanceMetric(
+          views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
+  SetBorder(views::CreateEmptyBorder(
+      ChromeLayoutProvider::Get()->GetDialogInsetsForContentType(
+          views::TEXT, views::CONTROL)));
+
+  auto* instructions = AddChildView(std::make_unique<views::Label>(
+      controller_->GetContentExplanation(), CONTEXT_BODY_TEXT_LARGE,
+      views::style::STYLE_SECONDARY));
+  instructions->SetMultiLine(true);
+  instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+  // TODO(crbug.com/1020740): Add the card list in a separate CL.
+
+  return this;
+}
+
+base::string16 VirtualCardSelectionDialogViewImpl::GetWindowTitle() const {
+  return controller_->GetContentTitle();
+}
+
+bool VirtualCardSelectionDialogViewImpl::ShouldShowWindowTitle() const {
+  return true;
+}
+
+bool VirtualCardSelectionDialogViewImpl::ShouldShowCloseButton() const {
+  return false;
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.h b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.h
new file mode 100644
index 0000000..0670666
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/payments/virtual_card_selection_dialog_view_impl.h
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_IMPL_H_
+#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_IMPL_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/autofill/payments/virtual_card_selection_dialog_view.h"
+#include "ui/views/window/dialog_delegate.h"
+
+namespace autofill {
+
+class VirtualCardSelectionDialogController;
+
+// The Views implementation of VirtualCardSelectionDialogView.
+class VirtualCardSelectionDialogViewImpl
+    : public VirtualCardSelectionDialogView,
+      public views::DialogDelegateView {
+ public:
+  VirtualCardSelectionDialogViewImpl(
+      VirtualCardSelectionDialogController* controller);
+  ~VirtualCardSelectionDialogViewImpl() override;
+
+  // VirtualCardSelectionDialogView:
+  void Hide() override;
+
+  // views::DialogDelegateView:
+  gfx::Size CalculatePreferredSize() const override;
+  void AddedToWidget() override;
+  bool Accept() override;
+  bool Cancel() override;
+  bool IsDialogButtonEnabled(ui::DialogButton button) const override;
+  ui::ModalType GetModalType() const override;
+  View* GetContentsView() override;
+  base::string16 GetWindowTitle() const override;
+  bool ShouldShowWindowTitle() const override;
+  bool ShouldShowCloseButton() const override;
+
+ private:
+  VirtualCardSelectionDialogController* controller_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(VirtualCardSelectionDialogViewImpl);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_VIRTUAL_CARD_SELECTION_DIALOG_VIEW_IMPL_H_
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.cc b/chrome/browser/ui/views/crostini/crostini_installer_view.cc
deleted file mode 100644
index 754c26a..0000000
--- a/chrome/browser/ui/views/crostini/crostini_installer_view.cc
+++ /dev/null
@@ -1,485 +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/ui/views/crostini/crostini_installer_view.h"
-
-#include <memory>
-#include <vector>
-
-#include "ash/public/cpp/ash_typography.h"
-#include "base/bind.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/system/sys_info.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/crostini/crostini_features.h"
-#include "chrome/browser/chromeos/crostini/crostini_installer.h"
-#include "chrome/browser/chromeos/crostini/crostini_installer_types.mojom.h"
-#include "chrome/browser/chromeos/crostini/crostini_installer_ui_delegate.h"
-#include "chrome/browser/chromeos/crostini/crostini_manager.h"
-#include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/views/chrome_layout_provider.h"
-#include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h"
-#include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/chrome_unscaled_resources.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/strings/grit/components_strings.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/text/bytes_formatting.h"
-#include "ui/chromeos/devicetype_utils.h"
-#include "ui/strings/grit/ui_strings.h"
-#include "ui/views/border.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
-#include "ui/views/controls/progress_bar.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/layout_provider.h"
-
-using crostini::CrostiniResult;
-using crostini::mojom::InstallerError;
-using crostini::mojom::InstallerState;
-
-namespace {
-
-CrostiniInstallerView* g_crostini_installer_view = nullptr;
-
-constexpr gfx::Insets kOOBEButtonRowInsets(32, 64, 32, 64);
-constexpr int kOOBEWindowWidth = 768;
-// TODO(timloh): The button row's preferred height (48px) adds to this. I'm not
-// sure where this actually comes from but since we plan to rewrite this dialog
-// in WebUI soon, this constant just hard-coded here.
-constexpr int kOOBEWindowHeight = 640 - 48;
-constexpr int kLinuxIllustrationWidth = 448;
-constexpr int kLinuxIllustrationHeight = 180;
-
-constexpr char kCrostiniSetupSourceHistogram[] = "Crostini.SetupSource";
-
-// Generates a Google Help URL which includes a "board type" parameter. Some
-// help pages need to be adjusted depending on the type of CrOS device that is
-// accessing the page.
-base::string16 GetHelpUrlWithBoard(const std::string& original_url) {
-  return base::ASCIIToUTF16(original_url +
-                            "&b=" + base::SysInfo::GetLsbReleaseBoard());
-}
-
-base::string16 GetErrorMessage(InstallerError error) {
-  switch (error) {
-    case InstallerError::kErrorLoadingTermina:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_LOAD_TERMINA_ERROR);
-    case InstallerError::kErrorStartingConcierge:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_START_CONCIERGE_ERROR);
-    case InstallerError::kErrorCreatingDiskImage:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_CREATE_DISK_IMAGE_ERROR);
-    case InstallerError::kErrorStartingTermina:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_START_TERMINA_VM_ERROR);
-    case InstallerError::kErrorStartingContainer:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_START_CONTAINER_ERROR);
-    case InstallerError::kErrorConfiguringContainer:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_CONFIGURE_CONTAINER_ERROR);
-    case InstallerError::kErrorOffline:
-      return l10n_util::GetStringFUTF16(IDS_CROSTINI_INSTALLER_OFFLINE_ERROR,
-                                        ui::GetChromeOSDeviceName());
-    case InstallerError::kErrorFetchingSshKeys:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_FETCH_SSH_KEYS_ERROR);
-    case InstallerError::kErrorMountingContainer:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_MOUNT_CONTAINER_ERROR);
-    case InstallerError::kErrorSettingUpContainer:
-      return l10n_util::GetStringUTF16(
-          IDS_CROSTINI_INSTALLER_SETUP_CONTAINER_ERROR);
-    case InstallerError::kErrorInsufficientDiskSpace:
-      return l10n_util::GetStringFUTF16(
-          IDS_CROSTINI_INSTALLER_INSUFFICIENT_DISK,
-          ui::FormatBytesWithUnits(
-              crostini::CrostiniInstallerUIDelegate::kMinimumFreeDiskSpace,
-              ui::DATA_UNITS_GIBIBYTE,
-              /*show_units=*/true));
-    default:
-      return {};
-  }
-}
-
-}  // namespace
-
-// TODO(lxj): |CrostiniInstallerView| will be removed at some point. We will
-// wait until then to find a better place for this function.
-void crostini::ShowCrostiniInstallerView(
-    Profile* profile,
-    crostini::CrostiniUISurface ui_surface) {
-  // Defensive check to prevent showing the installer when crostini is not
-  // allowed.
-  if (!CrostiniFeatures::Get()->IsUIAllowed(profile)) {
-    return;
-  }
-  base::UmaHistogramEnumeration(kCrostiniSetupSourceHistogram, ui_surface,
-                                crostini::CrostiniUISurface::kCount);
-
-  if (chromeos::CrostiniInstallerUI::IsEnabled()) {
-    return chromeos::CrostiniInstallerDialog::Show(profile);
-  } else {
-    return CrostiniInstallerView::Show(
-        profile, crostini::CrostiniInstaller::GetForProfile(profile));
-  }
-}
-
-// static
-void CrostiniInstallerView::Show(
-    Profile* profile,
-    crostini::CrostiniInstallerUIDelegate* delegate) {
-  DCHECK(crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
-  if (!g_crostini_installer_view) {
-    DCHECK(!crostini::CrostiniManager::GetForProfile(profile)
-                ->GetInstallerViewStatus());
-    g_crostini_installer_view = new CrostiniInstallerView(profile, delegate);
-    views::DialogDelegate::CreateDialogWidget(g_crostini_installer_view,
-                                              nullptr, nullptr);
-
-    // TODO(ellyjones): Why is this necessary? Why can't we use the default
-    // button row insets?
-    g_crostini_installer_view->SetButtonRowInsets(kOOBEButtonRowInsets);
-    // We do our layout when the big message is at its biggest. Then we can
-    // set it to the desired value.
-    g_crostini_installer_view->big_message_label_->SetText(
-        l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_INSTALLING));
-    g_crostini_installer_view->GetWidget()->GetRootView()->Layout();
-    const base::string16 device_type = ui::GetChromeOSDeviceName();
-    g_crostini_installer_view->big_message_label_->SetText(
-        l10n_util::GetStringFUTF16(IDS_CROSTINI_INSTALLER_TITLE, device_type));
-
-    crostini::CrostiniManager::GetForProfile(profile)->SetInstallerViewStatus(
-        true);
-  }
-
-  g_crostini_installer_view->GetWidget()->Show();
-}
-
-// static
-CrostiniInstallerView* CrostiniInstallerView::GetActiveViewForTesting() {
-  return g_crostini_installer_view;
-}
-
-bool CrostiniInstallerView::IsDialogButtonEnabled(
-    ui::DialogButton button) const {
-  if (button == ui::DIALOG_BUTTON_CANCEL &&
-      (state_ == State::CANCELING || state_ == State::CANCELED)) {
-    return false;
-  }
-  return true;
-}
-
-bool CrostiniInstallerView::ShouldShowCloseButton() const {
-  return false;
-}
-
-bool CrostiniInstallerView::ShouldShowWindowTitle() const {
-  return false;
-}
-
-bool CrostiniInstallerView::Accept() {
-  // This dialog can be accepted from State::ERROR. In that case, we're doing a
-  // Retry.
-  DCHECK(state_ == State::PROMPT || state_ == State::ERROR);
-
-  // |learn_more_link_| should only be present in State::PROMPT.
-  delete learn_more_link_;
-  learn_more_link_ = nullptr;
-
-  state_ = State::INSTALLING;
-  installing_state_ = InstallerState::kStart;
-  progress_bar_->SetValue(0);
-  progress_bar_->SetVisible(true);
-  SetMessageLabel();
-  big_message_label_->SetText(
-      l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_INSTALLING));
-  UpdateDialogButtonsAfterStateChange();
-  GetWidget()->GetRootView()->Layout();
-
-  VLOG(1) << "delegate_->Install()";
-  delegate_->Install(
-      crostini::CrostiniManager::RestartOptions{},
-      base::BindRepeating(&CrostiniInstallerView::OnProgressUpdate,
-                          weak_ptr_factory_.GetWeakPtr()),
-      base::BindOnce(&CrostiniInstallerView::OnInstallFinished,
-                     weak_ptr_factory_.GetWeakPtr()));
-
-  return false;
-}
-
-bool CrostiniInstallerView::Cancel() {
-  switch (state_) {
-    case State::PROMPT:
-      delegate_->CancelBeforeStart();
-      return true;
-    case State::INSTALLING:
-      state_ = State::CANCELING;
-      big_message_label_->SetText(
-          l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_CANCELING_TITLE));
-      message_label_->SetText(
-          l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_CANCELING));
-      message_label_->SetVisible(true);
-      progress_bar_->SetValue(-1);
-      progress_bar_->SetVisible(true);
-      UpdateDialogButtonsAfterStateChange();
-      GetWidget()->GetRootView()->Layout();
-      delegate_->Cancel(base::BindOnce(&CrostiniInstallerView::OnCanceled,
-                                       weak_ptr_factory_.GetWeakPtr()));
-      return false;
-    case State::CANCELING:
-      return false;
-    default:
-      return true;  // Close the dialog.
-  }
-}
-
-gfx::Size CrostiniInstallerView::CalculatePreferredSize() const {
-  return gfx::Size(kOOBEWindowWidth, kOOBEWindowHeight);
-}
-
-void CrostiniInstallerView::LinkClicked(views::Link* source, int event_flags) {
-  DCHECK_EQ(source, learn_more_link_);
-
-  NavigateParams params(
-      profile_, GURL(GetHelpUrlWithBoard(chrome::kLinuxAppsLearnMoreURL)),
-      ui::PAGE_TRANSITION_LINK);
-  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
-  Navigate(&params);
-}
-
-CrostiniInstallerView::CrostiniInstallerView(
-    Profile* profile,
-    crostini::CrostiniInstallerUIDelegate* delegate)
-    : profile_(profile), delegate_(delegate) {
-  // Layout constants from the spec.
-  constexpr gfx::Insets kDialogInsets(60, 64, 0, 64);
-  constexpr int kDialogSpacingVertical = 32;
-  constexpr gfx::Size kLogoImageSize(32, 32);
-  constexpr gfx::Insets kLowerContainerInsets(0, 0, 80, 0);
-
-  views::BoxLayout* layout =
-      SetLayoutManager(std::make_unique<views::BoxLayout>(
-          views::BoxLayout::Orientation::kVertical, gfx::Insets(),
-          kDialogSpacingVertical));
-
-  views::View* upper_container_view = new views::View();
-  upper_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical, kDialogInsets,
-      kDialogSpacingVertical));
-  AddChildView(upper_container_view);
-
-  views::View* lower_container_view = new views::View();
-  views::BoxLayout* lower_container_layout =
-      lower_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
-          views::BoxLayout::Orientation::kVertical, kLowerContainerInsets));
-  AddChildView(lower_container_view);
-
-  logo_image_ = new views::ImageView();
-  logo_image_->SetImageSize(kLogoImageSize);
-  logo_image_->SetImage(
-      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-          IDR_LOGO_CROSTINI_DEFAULT_32));
-  logo_image_->SetHorizontalAlignment(views::ImageView::Alignment::kLeading);
-  upper_container_view->AddChildView(logo_image_);
-
-  const base::string16 device_type = ui::GetChromeOSDeviceName();
-
-  big_message_label_ =
-      new views::Label({}, ash::AshTextContext::CONTEXT_HEADLINE_OVERSIZED);
-  big_message_label_->SetMultiLine(true);
-  big_message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  upper_container_view->AddChildView(big_message_label_);
-
-  // TODO(timloh): Descenders in the message appear to be clipped, re-visit once
-  // the UI has been fleshed out more.
-  const base::string16 message = l10n_util::GetStringFUTF16(
-      IDS_CROSTINI_INSTALLER_BODY,
-      ui::FormatBytesWithUnits(
-          crostini::CrostiniInstallerUIDelegate::kDownloadSizeInBytes,
-          ui::DATA_UNITS_MEBIBYTE,
-          /*show_units=*/true));
-
-  // Make a view to keep |message_label_| and |learn_more_link_| together with
-  // less vertical spacing than the other dialog views.
-  views::View* message_view = new views::View();
-  message_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical));
-  message_label_ = new views::Label(message);
-  message_label_->SetMultiLine(true);
-  message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  message_view->AddChildView(message_label_);
-
-  learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-  learn_more_link_->set_listener(this);
-  learn_more_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  message_view->AddChildView(learn_more_link_);
-
-  upper_container_view->AddChildView(message_view);
-
-  // Make a slot for the progress bar, but it's not initially visible.
-  progress_bar_ = new views::ProgressBar();
-  upper_container_view->AddChildView(progress_bar_);
-  progress_bar_->SetVisible(false);
-
-  big_image_ = new views::ImageView();
-  big_image_->SetImageSize(
-      gfx::Size(kLinuxIllustrationWidth, kLinuxIllustrationHeight));
-  big_image_->SetImage(
-      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-          IDR_LINUX_ILLUSTRATION));
-  lower_container_view->AddChildView(big_image_);
-
-  // Make sure the lower_container_view is pinned to the bottom of the dialog.
-  lower_container_layout->set_main_axis_alignment(
-      views::BoxLayout::MainAxisAlignment::kEnd);
-  layout->SetFlexForView(lower_container_view, 1, true);
-
-  chrome::RecordDialogCreation(chrome::DialogIdentifier::CROSTINI_INSTALLER);
-}
-
-CrostiniInstallerView::~CrostiniInstallerView() {
-  crostini::CrostiniManager::GetForProfile(profile_)->SetInstallerViewStatus(
-      false);
-  g_crostini_installer_view = nullptr;
-}
-
-void CrostiniInstallerView::OnProgressUpdate(InstallerState installing_state,
-                                             double progress_fraction) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, State::INSTALLING);
-  if (installing_state_ != installing_state) {
-    installing_state_ = installing_state;
-    SetMessageLabel();
-  }
-  // |progress_bar_| has been set visible in |Accept()|.
-  progress_bar_->SetValue(progress_fraction);
-
-  DialogModelChanged();
-  GetWidget()->GetRootView()->Layout();
-}
-
-void CrostiniInstallerView::OnInstallFinished(InstallerError error) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  if (error == InstallerError::kNone) {
-    state_ = State::SUCCESS;
-    GetWidget()->Close();
-    return;
-  }
-
-  state_ = State::ERROR;
-  big_message_label_->SetText(
-      l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_ERROR_TITLE));
-  message_label_->SetText(GetErrorMessage(error));
-  message_label_->SetVisible(true);
-  progress_bar_->SetVisible(false);
-  // Remove the buttons so they get recreated with correct color and
-  // highlighting. Without this it is possible for both buttons to be styled
-  // as default buttons.
-  // TODO(ellyjones): This shouldn't be necessary - DialogModelChanged() should
-  // handle this case. Investigate.
-  delete GetOkButton();
-  delete GetCancelButton();
-
-  UpdateDialogButtonsAfterStateChange();
-  GetWidget()->GetRootView()->Layout();
-}
-
-void CrostiniInstallerView::OnCanceled() {
-  state_ = State::CANCELED;
-  GetWidget()->Close();
-}
-
-void CrostiniInstallerView::SetMessageLabel() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  int message_id = 0;
-
-  switch (installing_state_) {
-    case InstallerState::kInstallImageLoader:
-      message_id = IDS_CROSTINI_INSTALLER_LOAD_TERMINA_MESSAGE;
-      break;
-    case InstallerState::kStartConcierge:
-      message_id = IDS_CROSTINI_INSTALLER_START_CONCIERGE_MESSAGE;
-      break;
-    case InstallerState::kCreateDiskImage:
-      message_id = IDS_CROSTINI_INSTALLER_CREATE_DISK_IMAGE_MESSAGE;
-      break;
-    case InstallerState::kStartTerminaVm:
-      message_id = IDS_CROSTINI_INSTALLER_START_TERMINA_VM_MESSAGE;
-      break;
-    case InstallerState::kCreateContainer:
-      // TODO(lxj): we are using the same message as for |START_CONTAINER|,
-      // which is weird because user is going to see message "start container"
-      // then "setup container" and then "start container" again.
-      message_id = IDS_CROSTINI_INSTALLER_START_CONTAINER_MESSAGE;
-      break;
-    case InstallerState::kSetupContainer:
-      message_id = IDS_CROSTINI_INSTALLER_SETUP_CONTAINER_MESSAGE;
-      break;
-    case InstallerState::kStartContainer:
-      message_id = IDS_CROSTINI_INSTALLER_START_CONTAINER_MESSAGE;
-      break;
-    case InstallerState::kConfigureContainer:
-      message_id = IDS_CROSTINI_INSTALLER_CONFIGURE_CONTAINER_MESSAGE;
-      break;
-    case InstallerState::kFetchSshKeys:
-      message_id = IDS_CROSTINI_INSTALLER_FETCH_SSH_KEYS_MESSAGE;
-      break;
-    case InstallerState::kMountContainer:
-      message_id = IDS_CROSTINI_INSTALLER_MOUNT_CONTAINER_MESSAGE;
-      break;
-    default:
-      break;
-  }
-
-  if (message_id == 0) {
-    message_label_->SetVisible(false);
-  } else {
-    message_label_->SetText(l10n_util::GetStringUTF16(message_id));
-    message_label_->SetVisible(true);
-  }
-}
-
-void CrostiniInstallerView::UpdateDialogButtonsAfterStateChange() {
-  DialogDelegate::set_buttons(GetCurrentDialogButtons());
-  DialogDelegate::set_button_label(
-      ui::DIALOG_BUTTON_CANCEL,
-      GetCurrentDialogButtonLabel(ui::DIALOG_BUTTON_CANCEL));
-  DialogDelegate::set_button_label(
-      ui::DIALOG_BUTTON_OK, GetCurrentDialogButtonLabel(ui::DIALOG_BUTTON_OK));
-  DialogModelChanged();
-}
-
-int CrostiniInstallerView::GetCurrentDialogButtons() const {
-  if (state_ == State::PROMPT || state_ == State::ERROR) {
-    return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
-  }
-  return ui::DIALOG_BUTTON_CANCEL;
-}
-
-base::string16 CrostiniInstallerView::GetCurrentDialogButtonLabel(
-    ui::DialogButton button) const {
-  if (button == ui::DIALOG_BUTTON_OK) {
-    if (state_ == State::ERROR) {
-      return l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_RETRY_BUTTON);
-    } else if (state_ == State::PROMPT) {
-      return l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_INSTALL_BUTTON);
-    }
-  } else if (button == ui::DIALOG_BUTTON_CANCEL) {
-    if (state_ == State::SUCCESS)
-      return l10n_util::GetStringUTF16(IDS_APP_CLOSE);
-    else
-      return l10n_util::GetStringUTF16(IDS_APP_CANCEL);
-  }
-  return {};
-}
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.h b/chrome/browser/ui/views/crostini/crostini_installer_view.h
deleted file mode 100644
index 0ee7b2a..0000000
--- a/chrome/browser/ui/views/crostini/crostini_installer_view.h
+++ /dev/null
@@ -1,86 +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 CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_INSTALLER_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_INSTALLER_VIEW_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/crostini/crostini_installer_ui_delegate.h"
-#include "ui/views/controls/link_listener.h"
-#include "ui/views/window/dialog_delegate.h"
-
-namespace views {
-class ImageView;
-class Label;
-class Link;
-class ProgressBar;
-}  // namespace views
-
-class Profile;
-
-// The Crostini installer. Provides details about Crostini to the user and
-// installs it if the user chooses to do so.
-class CrostiniInstallerView : public views::DialogDelegateView,
-                              public views::LinkListener {
- public:
-  static void Show(Profile* profile,
-                   crostini::CrostiniInstallerUIDelegate* delegate);
-  static CrostiniInstallerView* GetActiveViewForTesting();
-
-  // views::DialogDelegateView:
-  bool IsDialogButtonEnabled(ui::DialogButton button) const override;
-  bool ShouldShowCloseButton() const override;
-  bool ShouldShowWindowTitle() const override;
-  bool Accept() override;
-  bool Cancel() override;
-  gfx::Size CalculatePreferredSize() const override;
-
-  // views::LinkListener:
-  void LinkClicked(views::Link* source, int event_flags) override;
-
- private:
-  enum class State {
-    PROMPT,
-    INSTALLING,
-    SUCCESS,
-    ERROR,
-    CANCELING,
-    CANCELED,
-  };
-
-  explicit CrostiniInstallerView(
-      Profile* profile,
-      crostini::CrostiniInstallerUIDelegate* delegate);
-  ~CrostiniInstallerView() override;
-
-  void OnProgressUpdate(crostini::mojom::InstallerState installing_state,
-                        double progress_fraction);
-  void OnInstallFinished(crostini::mojom::InstallerError error);
-  void OnCanceled();
-  void SetMessageLabel();
-
-  void UpdateDialogButtonsAfterStateChange();
-
-  int GetCurrentDialogButtons() const;
-  base::string16 GetCurrentDialogButtonLabel(ui::DialogButton button) const;
-
-  State state_ = State::PROMPT;
-  crostini::mojom::InstallerState installing_state_;
-  Profile* profile_;
-  crostini::CrostiniInstallerUIDelegate* delegate_;
-
-  views::ImageView* logo_image_ = nullptr;
-  views::Label* big_message_label_ = nullptr;
-  views::Label* message_label_ = nullptr;
-  views::Link* learn_more_link_ = nullptr;
-  views::ImageView* big_image_ = nullptr;
-  views::ProgressBar* progress_bar_ = nullptr;
-
-  base::WeakPtrFactory<CrostiniInstallerView> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(CrostiniInstallerView);
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_INSTALLER_VIEW_H_
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
deleted file mode 100644
index 3074a2d9..0000000
--- a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
+++ /dev/null
@@ -1,193 +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/crostini/crostini_installer_types.mojom.h"
-#include "chrome/browser/ui/views/crostini/crostini_installer_view.h"
-
-#include "base/bind.h"
-#include "base/run_loop.h"
-#include "chrome/browser/chromeos/crostini/crostini_manager.h"
-#include "chrome/browser/chromeos/crostini/crostini_util.h"
-#include "chrome/browser/chromeos/crostini/fake_crostini_installer_ui_delegate.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/views/crostini/crostini_browser_test_util.h"
-#include "chrome/grit/generated_resources.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "components/crx_file/id_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/ui_base_types.h"
-
-using crostini::mojom::InstallerError;
-using crostini::mojom::InstallerState;
-
-class CrostiniInstallerViewBrowserTest : public CrostiniDialogBrowserTest {
- public:
-  CrostiniInstallerViewBrowserTest()
-      : CrostiniDialogBrowserTest(false /*register_termina*/) {}
-
-  // CrostiniDialogBrowserTest:
-  void ShowUi(const std::string& name) override {
-    CrostiniInstallerView::Show(browser()->profile(), &fake_delegate_);
-  }
-
-  CrostiniInstallerView* ActiveView() {
-    return CrostiniInstallerView::GetActiveViewForTesting();
-  }
-
-  bool HasEnabledAcceptButton() {
-    return ActiveView()->GetOkButton() != nullptr &&
-           ActiveView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK);
-  }
-
-  bool HasEnabledCancelButton() {
-    return ActiveView()->GetCancelButton() != nullptr &&
-           ActiveView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL);
-  }
-
- protected:
-  crostini::FakeCrostiniInstallerUIDelegate fake_delegate_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CrostiniInstallerViewBrowserTest);
-};
-
-// Test the dialog is actually launched from the app launcher.
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, InvokeUi_default) {
-  ShowAndVerifyUi();
-}
-
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, InstallFlow) {
-  ShowUi("default");
-  EXPECT_NE(nullptr, ActiveView());
-  EXPECT_EQ(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-            ActiveView()->GetDialogButtons());
-  EXPECT_TRUE(HasEnabledAcceptButton());
-  EXPECT_TRUE(HasEnabledCancelButton());
-  EXPECT_TRUE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                  ->GetInstallerViewStatus());
-  EXPECT_FALSE(fake_delegate_.progress_callback_)
-      << "Install() should not be called";
-
-  ActiveView()->AcceptDialog();
-  EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed());
-  EXPECT_FALSE(HasEnabledAcceptButton());
-  EXPECT_TRUE(HasEnabledCancelButton());
-  EXPECT_TRUE(fake_delegate_.progress_callback_)
-      << "Install() should be called";
-  EXPECT_TRUE(fake_delegate_.result_callback_);
-
-  fake_delegate_.progress_callback_.Run(InstallerState::kCreateContainer, 0.4);
-  fake_delegate_.progress_callback_.Run(InstallerState::kMountContainer, 0.8);
-  std::move(fake_delegate_.result_callback_).Run(InstallerError::kNone);
-
-  // This allow the dialog to be destructed.
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(nullptr, ActiveView());
-  EXPECT_FALSE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                   ->GetInstallerViewStatus());
-}
-
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, ErrorThenCancel) {
-  ShowUi("default");
-  ASSERT_NE(nullptr, ActiveView());
-
-  ActiveView()->AcceptDialog();
-
-  ASSERT_TRUE(fake_delegate_.result_callback_);
-  std::move(fake_delegate_.result_callback_)
-      .Run(InstallerError::kErrorCreatingDiskImage);
-
-  EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed());
-  EXPECT_TRUE(HasEnabledAcceptButton());
-  EXPECT_EQ(ActiveView()->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK),
-            l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_RETRY_BUTTON));
-  EXPECT_TRUE(HasEnabledCancelButton());
-
-  ActiveView()->CancelDialog();
-  EXPECT_TRUE(ActiveView()->GetWidget()->IsClosed());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(nullptr, ActiveView());
-
-  EXPECT_FALSE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                   ->GetInstallerViewStatus());
-}
-
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, ErrorThenRetry) {
-  ShowUi("default");
-  ASSERT_NE(nullptr, ActiveView());
-
-  ActiveView()->AcceptDialog();
-
-  ASSERT_TRUE(fake_delegate_.result_callback_);
-  std::move(fake_delegate_.result_callback_)
-      .Run(InstallerError::kErrorCreatingDiskImage);
-
-  EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed());
-  EXPECT_TRUE(HasEnabledAcceptButton());
-  EXPECT_EQ(ActiveView()->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK),
-            l10n_util::GetStringUTF16(IDS_CROSTINI_INSTALLER_RETRY_BUTTON));
-
-  ActiveView()->AcceptDialog();
-  EXPECT_TRUE(fake_delegate_.result_callback_)
-      << "Install() should be called again";
-
-  std::move(fake_delegate_.result_callback_).Run(InstallerError::kNone);
-
-  // This allow the dialog to be destructed.
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(nullptr, ActiveView());
-  EXPECT_FALSE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                   ->GetInstallerViewStatus());
-}
-
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, CancelBeforeStart) {
-  ShowUi("default");
-  ASSERT_NE(nullptr, ActiveView());
-  EXPECT_TRUE(HasEnabledCancelButton());
-  EXPECT_FALSE(fake_delegate_.cancel_before_start_called_);
-
-  ActiveView()->CancelDialog();
-
-  EXPECT_TRUE(ActiveView()->GetWidget()->IsClosed());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(nullptr, ActiveView());
-  EXPECT_FALSE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                   ->GetInstallerViewStatus());
-  EXPECT_TRUE(fake_delegate_.cancel_before_start_called_);
-}
-
-IN_PROC_BROWSER_TEST_F(CrostiniInstallerViewBrowserTest, CancelAfterStart) {
-  ShowUi("default");
-  ASSERT_NE(nullptr, ActiveView());
-  EXPECT_TRUE(HasEnabledAcceptButton());
-
-  ActiveView()->AcceptDialog();
-  EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed());
-  EXPECT_TRUE(HasEnabledCancelButton());
-  EXPECT_TRUE(fake_delegate_.progress_callback_)
-      << "Install() should be called";
-
-  EXPECT_FALSE(fake_delegate_.cancel_callback_)
-      << "Cancel() should not be called";
-  ActiveView()->CancelDialog();
-  EXPECT_TRUE(fake_delegate_.cancel_callback_) << "Cancel() should be called";
-  EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed())
-      << "Dialog should not close before cancel callback";
-  EXPECT_FALSE(HasEnabledAcceptButton());
-  EXPECT_FALSE(HasEnabledCancelButton());
-
-  std::move(fake_delegate_.cancel_callback_).Run();
-  EXPECT_TRUE(ActiveView()->GetWidget()->IsClosed());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(nullptr, ActiveView());
-  EXPECT_FALSE(crostini::CrostiniManager::GetForProfile(browser()->profile())
-                   ->GetInstallerViewStatus());
-
-  EXPECT_FALSE(fake_delegate_.cancel_before_start_called_);
-}
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 100edb1..ab26909 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -193,6 +193,10 @@
     parent()->OnMouseCaptureLost();
     Button::OnMouseCaptureLost();
   }
+
+  base::string16 GetTooltipText(const gfx::Point& point) const override {
+    return parent()->GetTooltipText(point);
+  }
 };
 
 }  // namespace
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
index 874f4da..495b678 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -15,6 +15,9 @@
 #include "chrome/browser/ui/views/extensions/extensions_toolbar_button.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h"
 #include "ui/views/layout/animating_layout_manager.h"
+#include "ui/views/layout/flex_layout.h"
+#include "ui/views/layout/flex_layout_types.h"
+#include "ui/views/view_class_properties.h"
 #include "ui/views/widget/widget_observer.h"
 
 struct ExtensionsToolbarContainer::DropInfo {
@@ -41,7 +44,16 @@
   model_observer_.Add(model_);
   // Do not flip the Extensions icon in RTL.
   extensions_button_->EnableCanvasFlippingForRTLUI(false);
+  extensions_button_->SetProperty(views::kFlexBehaviorKey,
+                                  views::FlexSpecification());
   AddMainButton(extensions_button_);
+  target_layout_manager()
+      ->SetFlexAllocationOrder(views::FlexAllocationOrder::kReverse)
+      .SetDefault(views::kFlexBehaviorKey,
+                  views::FlexSpecification::ForSizeRule(
+                      views::MinimumFlexSizeRule::kPreferredSnapToZero,
+                      views::MaximumFlexSizeRule::kPreferred)
+                      .WithWeight(0));
   CreateActions();
 
   // TODO(pbos): Consider splitting out tab-strip observing into another class.
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.cc
index f58ea543..040bec6 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/strings/string16.h"
+#include "chrome/browser/ui/tab_dialogs.h"
 #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/grit/generated_resources.h"
@@ -124,6 +125,7 @@
 
   GetBubbleFrameView()->UpdateWindowTitle();
   text_->SetVisible(false);
+  show_cookies_link_->SetVisible(false);
   header_view_->SetVisible(false);
 
   if (intermediate_step_ == IntermediateStep::kTurnOffButton) {
@@ -131,6 +133,7 @@
     text_->SetText(
         l10n_util::GetStringUTF16(IDS_COOKIE_CONTROLS_NOT_WORKING_DESCRIPTION));
     extra_view_ = SetExtraView(CreateInfoIcon());
+    show_cookies_link_->SetVisible(true);
   } else if (status_ == CookieControlsController::Status::kEnabled) {
     header_view_->SetVisible(true);
     header_view_->SetImage(
@@ -185,10 +188,11 @@
 }
 
 void CookieControlsBubbleView::Init() {
-  // Use a BoxLayout because the view might be larger than |text_| and we want
-  // |text_| at the top.
+  const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
   SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical));
+      views::BoxLayout::Orientation::kVertical, gfx::Insets(),
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
+
   auto text = std::make_unique<views::Label>(base::string16(),
                                              views::style::CONTEXT_LABEL,
                                              views::style::STYLE_SECONDARY);
@@ -196,6 +200,13 @@
   text->SetMultiLine(true);
   text_ = AddChildView(std::move(text));
 
+  auto cookie_link = std::make_unique<views::Link>(
+      l10n_util::GetStringUTF16(IDS_BLOCKED_COOKIES_INFO));
+  cookie_link->SetMultiLine(true);
+  cookie_link->set_listener(this);
+  cookie_link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  show_cookies_link_ = AddChildView(std::move(cookie_link));
+
   // TODO(crbug.com/1013092): The bubble should display a header view with full
   // width without having to tweak margins.
   gfx::Insets insets = margins();
@@ -279,10 +290,16 @@
 
 void CookieControlsBubbleView::LinkClicked(views::Link* source,
                                            int event_flags) {
-  DCHECK_EQ(status_, CookieControlsController::Status::kEnabled);
-  base::RecordAction(UserMetricsAction("CookieControls.Bubble.NotWorking"));
-  // Don't go through the controller as this is an intermediary state that
-  // is only relevant for the bubble UI.
-  intermediate_step_ = IntermediateStep::kTurnOffButton;
-  UpdateUi();
+  if (source == show_cookies_link_) {
+    base::RecordAction(UserMetricsAction("CookieControls.Bubble.CookiesInUse"));
+    TabDialogs::FromWebContents(web_contents())->ShowCollectedCookies();
+    GetWidget()->Close();
+  } else {
+    DCHECK_EQ(status_, CookieControlsController::Status::kEnabled);
+    base::RecordAction(UserMetricsAction("CookieControls.Bubble.NotWorking"));
+    // Don't go through the controller as this is an intermediary state that
+    // is only relevant for the bubble UI.
+    intermediate_step_ = IntermediateStep::kTurnOffButton;
+    UpdateUi();
+  }
 }
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h
index 2293d42..8810eb21 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/cookie_controls_bubble_view.h
@@ -85,6 +85,7 @@
   views::ImageView* header_view_ = nullptr;
   views::Label* text_ = nullptr;
   views::View* extra_view_ = nullptr;
+  views::Link* show_cookies_link_ = nullptr;
 
   ScopedObserver<CookieControlsController, CookieControlsView> observer_{this};
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 676d478a..b834a61 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -679,6 +679,28 @@
       return true;
   }
 
+  // If suggestion removal buttons are enabled, make Tab and Shift+Tab less
+  // exotic and allow it to traverse the focus out of the popup. We do this
+  // because removal buttons dramatically increase the number of child buttons.
+  if (base::FeatureList::IsEnabled(
+          omnibox::kOmniboxSuggestionTransparencyOptions)) {
+    // Close the popup if tab traversal exits the list.
+    size_t selected_line = model()->popup_model()->selected_line();
+    bool close_popup = event.IsShiftDown()
+                           ? selected_line == 0
+                           : selected_line == (model()->result().size() - 1);
+    if (close_popup) {
+      CloseOmniboxPopup();
+
+      // When we close the popup, we also want to restore the user's text back
+      // to the state it was before the popup opened.
+      model()->RevertTemporaryTextAndPopup();
+
+      // Return false so the focus manager will go to the next element.
+      return false;
+    }
+  }
+
   // Translate tab and shift-tab into down and up respectively.
   model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1);
   // If we shift-tabbed (and actually moved) to a suggestion with a tab
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
index 0f15877..81bb052 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_ui_util.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/ui_features.h"
@@ -176,7 +177,8 @@
   }
 
 #if !defined(OS_CHROMEOS)
-  if (identity_manager->HasPrimaryAccount() && profile_->IsSyncAllowed() &&
+  if (identity_manager->HasPrimaryAccount() &&
+      ProfileSyncServiceFactory::IsSyncAllowed(profile_) &&
       error_controller_->HasAvatarError()) {
     // When DICE is enabled and the error is an auth error, the sync-paused
     // icon is shown.
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 41619b2..6b90b1d 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -87,7 +87,7 @@
   // |Profile::IsSyncAllowed| is needed to check whether sync is allowed by GPO
   // policy.
   if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile) &&
-      profile->IsSyncAllowed() &&
+      ProfileSyncServiceFactory::IsSyncAllowed(profile) &&
       IdentityManagerFactory::GetForProfile(profile)->HasPrimaryAccount()) {
     return BadgedProfilePhoto::BADGE_TYPE_SYNC_COMPLETE;
   }
@@ -549,7 +549,7 @@
   Profile* profile = browser()->profile();
   // Only show the sync info if signin and sync are allowed.
   if (!profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed) ||
-      !profile->IsSyncAllowed()) {
+      !ProfileSyncServiceFactory::IsSyncAllowed(profile)) {
     return;
   }
 
@@ -816,7 +816,8 @@
   // profile (only selectable when sync is paused or disabled) and when sync is
   // not disabled there is a blue button to resolve the error.
   const bool show_sync_paused_ui = error == sync_ui_util::AUTH_ERROR;
-  const bool sync_disabled = !browser()->profile()->IsSyncAllowed();
+  const bool sync_disabled =
+      !ProfileSyncServiceFactory::IsSyncAllowed(browser()->profile());
   const bool passwords_only_error =
       error == sync_ui_util::TRUSTED_VAULT_KEY_MISSING_FOR_PASSWORDS_ERROR;
 
@@ -883,7 +884,7 @@
     const AvatarMenu::Item& avatar_item,
     bool is_guest) {
   Profile* profile = browser()->profile();
-  const bool sync_disabled = !profile->IsSyncAllowed();
+  const bool sync_disabled = !ProfileSyncServiceFactory::IsSyncAllowed(profile);
   if (!is_guest && sync_disabled) {
     AddDiceSyncErrorView(avatar_item, sync_ui_util::NO_SYNC_ERROR, 0);
     return;
@@ -906,7 +907,8 @@
   // disabled. Otherwise, show the email attached to the profile.
   bool show_email = !is_guest && avatar_item.signed_in;
   const base::string16 hover_button_title =
-      dice_enabled_ && profile->IsSyncAllowed() && show_email
+      dice_enabled_ && ProfileSyncServiceFactory::IsSyncAllowed(profile) &&
+              show_email
           ? l10n_util::GetStringUTF16(IDS_PROFILES_SYNC_COMPLETE_TITLE)
           : profile_name;
 
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
index bb9a488..3c6bf39 100644
--- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
+++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/signin_promo.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -32,8 +33,9 @@
 int GetSyncConfirmationDialogPreferredHeight(Profile* profile) {
   // If sync is disabled, then the sync confirmation dialog looks like an error
   // dialog and thus it has the same preferred size.
-  return profile->IsSyncAllowed() ? kSyncConfirmationDialogHeight
-                                  : kSigninErrorDialogHeight;
+  return ProfileSyncServiceFactory::IsSyncAllowed(profile)
+             ? kSyncConfirmationDialogHeight
+             : kSigninErrorDialogHeight;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc
index ef8768e..0a950fe7 100644
--- a/chrome/browser/ui/views/sad_tab_view.cc
+++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -332,6 +332,132 @@
     case 1073741845:
       error_string = "STATUS_FATAL_APP_EXIT";
       break;
+    case 1072103400:
+      error_string = "STATUS_CURRENT_TRANSACTION_NOT_VALID";
+      break;
+    case 1072365548:
+      error_string = "STATUS_SXS_CORRUPT_ACTIVATION_STACK";
+      break;
+    case 1072365552:
+      error_string = "STATUS_SXS_INVALID_DEACTIVATION";
+      break;
+    case 1072365566:
+      error_string = "STATUS_SXS_CANT_GEN_ACTCTX";
+      break;
+    case 1073739514:
+      error_string = "STATUS_VIRUS_INFECTED";
+      break;
+    case 1073740004:
+      error_string = "STATUS_INVALID_THREAD";
+      break;
+    case 1073740016:
+      error_string = "STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING";
+      break;
+    case 1073740022:
+      error_string = "STATUS_THREADPOOL_HANDLE_EXCEPTION";
+      break;
+    case 1073740767:
+      error_string = "STATUS_VERIFIER_STOP";
+      break;
+    case 1073740768:
+      error_string = "STATUS_ASSERTION_FAILURE";
+      break;
+    case 1073740771:
+      error_string = "STATUS_FATAL_USER_CALLBACK_EXCEPTION";
+      break;
+    case 1073740777:
+      error_string = "STATUS_INVALID_CRUNTIME_PARAMETER";
+      break;
+    case 1073740782:
+      error_string = "STATUS_DELAY_LOAD_FAILED";
+      break;
+    case 1073740959:
+      error_string = "STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT";
+      break;
+    case 1073741131:
+      error_string = "STATUS_FLOAT_MULTIPLE_TRAPS";
+      break;
+    case 1073741132:
+      error_string = "STATUS_FLOAT_MULTIPLE_FAULTS";
+      break;
+    case 1073741205:
+      error_string = "STATUS_DLL_INIT_FAILED_LOGOFF";
+      break;
+    case 1073741212:
+      error_string = "STATUS_RESOURCE_NOT_OWNED";
+      break;
+    case 1073741431:
+      error_string = "STATUS_TOO_LATE";
+      break;
+    case 1073741511:
+      error_string = "STATUS_ENTRYPOINT_NOT_FOUND";
+      break;
+    case 1073741523:
+      error_string = "STATUS_COMMITMENT_LIMIT";
+      break;
+    case 1073741558:
+      error_string = "STATUS_PROCESS_IS_TERMINATING";
+      break;
+    case 1073741569:
+      error_string = "STATUS_BAD_FUNCTION_TABLE";
+      break;
+    case 1073741581:
+      error_string = "STATUS_INVALID_PARAMETER_5";
+      break;
+    case 1073741595:
+      error_string = "STATUS_INTERNAL_ERROR";
+      break;
+    case 1073741662:
+      error_string = "STATUS_MEDIA_WRITE_PROTECTED";
+      break;
+    case 1073741670:
+      error_string = "STATUS_INSUFFICIENT_RESOURCES";
+      break;
+    case 1073741701:
+      error_string = "STATUS_INVALID_IMAGE_FORMAT";
+      break;
+    case 1073741738:
+      error_string = "STATUS_DELETE_PENDING";
+      break;
+    case 1073741744:
+      error_string = "STATUS_EA_TOO_LARGE";
+      break;
+    case 1073741749:
+      error_string = "STATUS_THREAD_IS_TERMINATING";
+      break;
+    case 1073741756:
+      error_string = "STATUS_QUOTA_EXCEEDED";
+      break;
+    case 1073741757:
+      error_string = "STATUS_SHARING_VIOLATION";
+      break;
+    case 1073741766:
+      error_string = "STATUS_OBJECT_PATH_NOT_FOUND";
+      break;
+    case 1073741772:
+      error_string = "STATUS_OBJECT_NAME_NOT_FOUND";
+      break;
+    case 1073741784:
+      error_string = "STATUS_BAD_STACK";
+      break;
+    case 1073741785:
+      error_string = "STATUS_UNWIND";
+      break;
+    case 1073741788:
+      error_string = "STATUS_OBJECT_TYPE_MISMATCH";
+      break;
+    case 1073741796:
+      error_string = "STATUS_INVALID_SYSTEM_SERVICE";
+      break;
+    case 1073741820:
+      error_string = "STATUS_INFO_LENGTH_MISMATCH";
+      break;
+    case 1073741822:
+      error_string = "STATUS_NOT_IMPLEMENTED";
+      break;
+    case 1073741823:
+      error_string = "STATUS_UNSUCCESSFUL";
+      break;
     case 2147483644:
       error_string = "STATUS_SINGLE_STEP";
       break;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index eae45392..77fbb19 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -44,14 +44,6 @@
 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/tabs/window_finder.h"
-#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
-#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
-#include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
-#include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_install_utils.h"
-#include "chrome/browser/web_applications/system_web_app_manager.h"
-#include "chrome/browser/web_applications/web_app_provider.h"
-#include "chrome/common/web_application_info.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -94,6 +86,8 @@
 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
+#include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/service_names.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -629,51 +623,6 @@
     observer.Wait();
   }
 
-  web_app::AppId InstallWebApp(
-      std::unique_ptr<WebApplicationInfo>&& web_app_info) {
-    web_app::AppId app_id;
-    base::RunLoop run_loop;
-    auto* provider = web_app::WebAppProvider::Get(browser()->profile());
-    DCHECK(provider);
-    provider->install_manager().InstallWebAppFromInfo(
-        std::move(web_app_info), web_app::ForInstallableSite::kYes,
-        WebappInstallSource::OMNIBOX_INSTALL_ICON,
-        base::BindLambdaForTesting([&](const web_app::AppId& installed_app_id,
-                                       web_app::InstallResultCode code) {
-          EXPECT_EQ(web_app::InstallResultCode::kSuccessNewInstall, code);
-          app_id = installed_app_id;
-          run_loop.Quit();
-        }));
-
-    run_loop.Run();
-    return app_id;
-  }
-
-  Browser* GetTerminalAppBrowser() {
-    // Install the app (but only once per session).
-    if (!terminal_app_id_) {
-      GURL app_url = embedded_test_server()->GetURL("app.com", "/simple.html");
-      auto web_app_info = std::make_unique<WebApplicationInfo>();
-      web_app_info->app_url = app_url;
-      web_app_info->scope = app_url.GetWithoutFilename();
-      web_app_info->display_mode = blink::mojom::DisplayMode::kStandalone;
-      web_app_info->open_as_window = true;
-      terminal_app_id_ = InstallWebApp(std::move(web_app_info));
-
-      auto* provider = web_app::WebAppProvider::Get(browser()->profile());
-      provider->system_web_app_manager().SetSystemAppsForTesting(
-          {{web_app::SystemAppType::TERMINAL,
-            // "Terminal" can be any string.
-            web_app::SystemAppInfo("Terminal", app_url)}});
-      web_app::ExternallyInstalledWebAppPrefs(browser()->profile()->GetPrefs())
-          .Insert(app_url, *terminal_app_id_,
-                  web_app::ExternalInstallSource::kInternalDefault);
-    }
-
-    return web_app::LaunchWebAppBrowser(browser()->profile(),
-                                        *terminal_app_id_);
-  }
-
   Browser* browser() const { return InProcessBrowserTest::browser(); }
 
  private:
@@ -682,7 +631,7 @@
   aura::Window* root_ = nullptr;
 #endif
   base::test::ScopedFeatureList scoped_feature_list_;
-  base::Optional<web_app::AppId> terminal_app_id_;
+  base::Optional<web_app::AppId> tabbed_app_id_;
 
   DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTest);
 };
@@ -3038,12 +2987,34 @@
                                              this, tab_strip));
 }
 
+class DetachToBrowserTabDragControllerTestWithTabbedSystemApp
+    : public DetachToBrowserTabDragControllerTest {
+ public:
+  DetachToBrowserTabDragControllerTestWithTabbedSystemApp()
+      : test_system_web_app_installation_(
+            web_app::TestSystemWebAppInstallation::
+                SetUpTabbedMultiWindowApp()) {}
+
+  web_app::AppId InstallMockApp() {
+    test_system_web_app_installation_->WaitForAppInstall();
+    return test_system_web_app_installation_->GetAppId();
+  }
+
+  Browser* LaunchWebAppBrowser(web_app::AppId app_id) {
+    return web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
+  }
+
+ private:
+  std::unique_ptr<web_app::TestSystemWebAppInstallation>
+      test_system_web_app_installation_;
+};
+
 // Move tab from TYPE_APP Browser to create new TYPE_APP Browser.
-IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
+IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabbedSystemApp,
                        DragAppToOwnWindow) {
-  // Start the embedded server, and get Terminal System App.
-  ASSERT_TRUE(embedded_test_server()->Start());
-  Browser* app_browser = GetTerminalAppBrowser();
+  // Install and get a tabbed system app.
+  web_app::AppId tabbed_app_id = InstallMockApp();
+  Browser* app_browser = LaunchWebAppBrowser(tabbed_app_id);
   ASSERT_EQ(2u, browser_list->size());
 
   // Close normal browser since other code expects only 1 browser to start.
@@ -3067,12 +3038,12 @@
 }
 
 // Move tab from TYPE_APP Browser to another TYPE_APP Browser.
-IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
+IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabbedSystemApp,
                        DragAppToAppWindow) {
-  // Start the embedded server, and get 2 browsers with Terminal System App.
-  ASSERT_TRUE(embedded_test_server()->Start());
-  Browser* app_browser1 = GetTerminalAppBrowser();
-  Browser* app_browser2 = GetTerminalAppBrowser();
+  // Install and get 2 browsers with tabbed system app.
+  web_app::AppId tabbed_app_id = InstallMockApp();
+  Browser* app_browser1 = LaunchWebAppBrowser(tabbed_app_id);
+  Browser* app_browser2 = LaunchWebAppBrowser(tabbed_app_id);
   ASSERT_EQ(3u, browser_list->size());
   ResetIDs(app_browser2->tab_strip_model(), 100);
   Resize(app_browser1, app_browser2);
@@ -3101,11 +3072,11 @@
 
 // Move tab from TYPE_APP Browser to TYPE_NORMAL Browser.
 // Only allowed with feature MixBrowserTypeTabs.
-IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
+IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabbedSystemApp,
                        DragAppToNormalWindow) {
-  // Start the embedded server, and get a browser with Terminal System App.
-  ASSERT_TRUE(embedded_test_server()->Start());
-  Browser* app_browser = GetTerminalAppBrowser();
+  // Install and get a tabbed system app.
+  web_app::AppId tabbed_app_id = InstallMockApp();
+  Browser* app_browser = LaunchWebAppBrowser(tabbed_app_id);
   ASSERT_EQ(2u, browser_list->size());
   // Close normal browser since other code expects only 1 browser to start.
   CloseBrowserSynchronously(browser());
@@ -4039,6 +4010,10 @@
 INSTANTIATE_TEST_SUITE_P(TabDragging,
                          DetachToBrowserTabDragControllerTestTouch,
                          ::testing::Values("touch"));
+INSTANTIATE_TEST_SUITE_P(
+    TabDragging,
+    DetachToBrowserTabDragControllerTestWithTabbedSystemApp,
+    ::testing::Values("mouse", "touch"));
 #else
 INSTANTIATE_TEST_SUITE_P(TabDragging,
                          DetachToBrowserTabDragControllerTest,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
index 45167d2..822f0e8 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
@@ -9,6 +9,8 @@
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/button_observer.h"
+#include "ui/views/layout/animating_layout_manager.h"
+#include "ui/views/layout/flex_layout.h"
 #include "ui/views/view.h"
 
 // A general view container for any type of toolbar icons.
@@ -53,6 +55,17 @@
 
   bool uses_highlight() { return uses_highlight_; }
 
+  // Provides access to the animating layout manager for subclasses.
+  views::AnimatingLayoutManager* animating_layout_manager() {
+    return static_cast<views::AnimatingLayoutManager*>(GetLayoutManager());
+  }
+
+  // Provides access to the flex layout in the animating layout manager.
+  views::FlexLayout* target_layout_manager() {
+    return static_cast<views::FlexLayout*>(
+        animating_layout_manager()->target_layout_manager());
+  }
+
   static const char kToolbarIconContainerViewClassName[];
 
  protected:
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 079c100..4bec80b 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -707,10 +707,7 @@
           views::MinimumFlexSizeRule::kScaleToMinimum,
           views::MaximumFlexSizeRule::kUnbounded)
           .WithOrder(2);
-  const views::FlexSpecification browser_actions_flex_rule =
-      views::FlexSpecification::ForCustomRule(
-          BrowserActionsContainer::GetFlexRule())
-          .WithOrder(3);
+  constexpr int kExtensionsFlexOrder = 3;
 
   layout_manager_ = SetLayoutManager(std::make_unique<views::FlexLayout>());
 
@@ -724,11 +721,25 @@
                              gfx::Insets(0, location_bar_margin));
 
   if (browser_actions_) {
+    const views::FlexSpecification browser_actions_flex_rule =
+        views::FlexSpecification::ForCustomRule(
+            BrowserActionsContainer::GetFlexRule())
+            .WithOrder(kExtensionsFlexOrder);
+
     browser_actions_->SetProperty(views::kFlexBehaviorKey,
                                   browser_actions_flex_rule);
     browser_actions_->SetProperty(views::kMarginsKey, gfx::Insets());
     browser_actions_->SetProperty(views::kInternalPaddingKey,
                                   gfx::Insets(0, location_bar_margin));
+  } else if (extensions_container_) {
+    const views::FlexSpecification extensions_flex_rule =
+        views::FlexSpecification::ForCustomRule(
+            extensions_container_->animating_layout_manager()
+                ->GetDefaultFlexRule())
+            .WithOrder(kExtensionsFlexOrder);
+
+    extensions_container_->SetProperty(views::kFlexBehaviorKey,
+                                       extensions_flex_rule);
   }
 
   if (toolbar_account_icon_container_) {
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc
index ed8f9bbb..4b4b50f5 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -87,13 +87,14 @@
     : content::WebContentsObserver(nullptr),
       app_id_(std::move(app_id)),
       browser_(browser),
-      // Show tabs for Terminals only
+      system_app_type_(HasAppId() ? WebAppProvider::Get(browser->profile())
+                                        ->system_web_app_manager()
+                                        .GetSystemAppTypeForAppId(GetAppId())
+                                  : base::nullopt),
+      // Show tabs for Terminals only.
       // TODO(crbug.com/846546): Generalise has_tab_strip_ as a SystemWebApp
       // capability.
-      has_tab_strip_(HasAppId() ? GetAppIdForSystemWebApp(
-                                      browser->profile(),
-                                      SystemAppType::TERMINAL) == GetAppId()
-                                : false) {
+      has_tab_strip_(system_app_type_ == SystemAppType::TERMINAL) {
   browser->tab_strip_model()->AddObserver(this);
 }
 
@@ -150,7 +151,7 @@
       return out_of_scope || !InstallableManager::IsOriginConsideredSecure(url);
     }
 
-    if (IsForSystemWebApp()) {
+    if (is_for_system_web_app()) {
       DCHECK_EQ(url.scheme_piece(), content::kChromeUIScheme);
       return false;
     }
@@ -186,33 +187,30 @@
 bool AppBrowserController::HasTitlebarToolbar() const {
   // Show titlebar toolbar for Terminal System App, but not other system apps.
   // TODO(crbug.com/846546): Generalise this as a SystemWebApp capability.
-  if (IsForSystemWebApp()) {
-    return !browser_->is_type_app_popup() &&
-           GetAppIdForSystemWebApp(browser()->profile(),
-                                   SystemAppType::TERMINAL) == GetAppId();
-  }
+  if (is_for_system_web_app())
+    return system_app_type_ == web_app::SystemAppType::TERMINAL;
+
   // Show for all other apps.
   return true;
 }
 
 bool AppBrowserController::HasTitlebarAppOriginText() const {
   // Do not show origin text for System Apps.
-  return !IsForSystemWebApp();
+  return !is_for_system_web_app();
 }
 
 bool AppBrowserController::HasTitlebarContentSettings() const {
   // Do not show content settings for System Apps.
-  return !IsForSystemWebApp();
+  return !is_for_system_web_app();
 }
 
 #if defined(OS_CHROMEOS)
 bool AppBrowserController::UseTitlebarTerminalSystemAppMenu() const {
   // Use the Terminal System App Menu for Terminal System App only.
   // TODO(crbug.com/846546): Generalise this as a SystemWebApp capability.
-  if (IsForSystemWebApp()) {
-    return GetAppIdForSystemWebApp(browser()->profile(),
-                                   SystemAppType::TERMINAL) == GetAppId();
-  }
+  if (is_for_system_web_app())
+    return system_app_type_ == web_app::SystemAppType::TERMINAL;
+
   return false;
 }
 #endif
@@ -243,15 +241,6 @@
                                                     animate);
 }
 
-bool AppBrowserController::IsForSystemWebApp() const {
-  if (!HasAppId())
-    return false;
-
-  return WebAppProvider::Get(browser()->profile())
-      ->system_web_app_manager()
-      .IsSystemWebApp(GetAppId());
-}
-
 void AppBrowserController::DidStartNavigation(
     content::NavigationHandle* navigation_handle) {
   if (!initial_url().is_empty())
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h
index c58c77d3..0fa13250 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -22,6 +22,7 @@
 namespace web_app {
 
 class WebAppBrowserController;
+enum class SystemAppType;
 
 // Returns true if |app_url| and |page_url| are the same origin. To avoid
 // breaking Hosted Apps and Bookmark Apps that might redirect to sites in the
@@ -118,7 +119,7 @@
   void UpdateCustomTabBarVisibility(bool animate) const;
 
   // Returns true if this controller is for a System Web App.
-  bool IsForSystemWebApp() const;
+  bool is_for_system_web_app() const { return system_app_type_.has_value(); }
 
   // Returns true if AppId is non-null
   bool HasAppId() const { return app_id_.has_value(); }
@@ -165,6 +166,8 @@
   Browser* const browser_;
   GURL initial_url_;
 
+  base::Optional<SystemAppType> system_app_type_;
+
   const bool has_tab_strip_;
 
   DISALLOW_COPY_AND_ASSIGN(AppBrowserController);
diff --git a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
index 6858779..f1af2393 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
@@ -12,82 +12,33 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
-#include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/system_web_app_manager.h"
+#include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/web_application_info.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/test/test_utils.h"
 #include "extensions/browser/extension_registry.h"
 
 namespace web_app {
 
-class AppBrowserControllerBrowserTest
-    : public extensions::ExtensionBrowserTest {
+class AppBrowserControllerBrowserTest : public InProcessBrowserTest {
  public:
-  AppBrowserControllerBrowserTest() {
-#if defined(OS_CHROMEOS)
-    scoped_feature_list_.InitWithFeatures({}, {features::kTerminalSystemApp});
-#endif
-  }
-
-  ~AppBrowserControllerBrowserTest() override {}
-
-  void SetUp() override { extensions::ExtensionBrowserTest::SetUp(); }
+  AppBrowserControllerBrowserTest()
+      : test_system_web_app_installation_(
+            TestSystemWebAppInstallation::SetUpTabbedMultiWindowApp()) {}
 
  protected:
-  void InstallAndLaunchTerminalApp() {
-    GURL app_url = GetAppURL();
-    auto web_app_info = std::make_unique<WebApplicationInfo>();
-    web_app_info->app_url = app_url;
-    web_app_info->scope = app_url.GetWithoutFilename();
-    web_app_info->open_as_window = true;
-    AppId app_id = InstallWebApp(std::move(web_app_info));
-
-    auto* provider = WebAppProvider::Get(profile());
-    provider->system_web_app_manager().SetSystemAppsForTesting(
-        {{SystemAppType::TERMINAL, SystemAppInfo("Terminal", app_url)}});
-    ExternallyInstalledWebAppPrefs(profile()->GetPrefs())
-        .Insert(app_url, app_id, ExternalInstallSource::kInternalDefault);
-    ASSERT_EQ(
-        GetAppIdForSystemWebApp(browser()->profile(), SystemAppType::TERMINAL),
-        app_id);
-
-    const extensions::Extension* extension =
-        extensions::ExtensionRegistry::Get(profile())->GetInstalledExtension(
-            app_id);
-    ASSERT_TRUE(extension);
-
-    app_browser_ = LaunchAppBrowser(extension);
-
-    ASSERT_TRUE(app_browser_);
-    ASSERT_NE(app_browser_, browser());
-  }
-
-  std::string InstallWebApp(
-      std::unique_ptr<WebApplicationInfo>&& web_app_info) {
-    std::string app_id;
-    base::RunLoop run_loop;
-    auto* provider = WebAppProvider::Get(profile());
-    DCHECK(provider);
-    provider->install_manager().InstallWebAppFromInfo(
-        std::move(web_app_info), ForInstallableSite::kYes,
-        WebappInstallSource::OMNIBOX_INSTALL_ICON,
-        base::BindLambdaForTesting(
-            [&](const std::string& installed_app_id, InstallResultCode code) {
-              EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code);
-              app_id = installed_app_id;
-              run_loop.Quit();
-            }));
-
-    run_loop.Run();
-    return app_id;
-  }
-
-  GURL GetAppURL() {
-    return embedded_test_server()->GetURL("app.com", "/simple.html");
+  void InstallAndLaunchMockApp() {
+    test_system_web_app_installation_->WaitForAppInstall();
+    app_browser_ = web_app::LaunchWebAppBrowser(
+        browser()->profile(), test_system_web_app_installation_->GetAppId());
+    tabbed_app_url_ = test_system_web_app_installation_->GetAppUrl();
   }
 
   GURL GetActiveTabURL() {
@@ -97,21 +48,22 @@
   }
 
   Browser* app_browser_ = nullptr;
+  GURL tabbed_app_url_;
 
  private:
-  base::test::ScopedFeatureList scoped_feature_list_;
+  std::unique_ptr<TestSystemWebAppInstallation>
+      test_system_web_app_installation_;
 
   DISALLOW_COPY_AND_ASSIGN(AppBrowserControllerBrowserTest);
 };
 
 IN_PROC_BROWSER_TEST_F(AppBrowserControllerBrowserTest, TabsTest) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  InstallAndLaunchTerminalApp();
+  InstallAndLaunchMockApp();
 
   EXPECT_TRUE(app_browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP));
 
   // Check URL of tab1.
-  EXPECT_EQ(GetActiveTabURL(), GetAppURL());
+  EXPECT_EQ(GetActiveTabURL(), tabbed_app_url_);
   // Create tab2 with specific URL, check URL, number of tabs.
   chrome::AddTabAt(app_browser_, GURL(chrome::kChromeUINewTabURL), -1, true);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 2);
@@ -119,11 +71,11 @@
   // Create tab3 with default URL, check URL, number of tabs.
   chrome::NewTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 3);
-  EXPECT_EQ(GetActiveTabURL(), GetAppURL());
+  EXPECT_EQ(GetActiveTabURL(), tabbed_app_url_);
   // Switch to tab1, check URL.
   chrome::SelectNextTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 3);
-  EXPECT_EQ(GetActiveTabURL(), GetAppURL());
+  EXPECT_EQ(GetActiveTabURL(), tabbed_app_url_);
   // Switch to tab2, check URL.
   chrome::SelectNextTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 3);
@@ -131,7 +83,7 @@
   // Switch to tab3, check URL.
   chrome::SelectNextTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 3);
-  EXPECT_EQ(GetActiveTabURL(), GetAppURL());
+  EXPECT_EQ(GetActiveTabURL(), tabbed_app_url_);
   // Close tab3, check number of tabs.
   chrome::CloseTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 2);
@@ -139,7 +91,7 @@
   // Close tab2, check number of tabs.
   chrome::CloseTab(app_browser_);
   EXPECT_EQ(app_browser_->tab_strip_model()->count(), 1);
-  EXPECT_EQ(GetActiveTabURL(), GetAppURL());
+  EXPECT_EQ(GetActiveTabURL(), tabbed_app_url_);
 }
 
 }  // namespace web_app
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
index b815e57..ee230a7 100644
--- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
+++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -160,7 +160,7 @@
 bool IsSystemWebApp(Browser* browser) {
   DCHECK(browser);
   return browser->app_controller() &&
-         browser->app_controller()->IsForSystemWebApp();
+         browser->app_controller()->is_for_system_web_app();
 }
 
 gfx::Size GetSystemWebAppMinimumWindowSize(Browser* browser) {
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 3a04f339..2b11a97c 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -185,6 +185,7 @@
 #include "chromeos/components/media_app_ui/url_constants.h"
 #include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h"
 #include "chromeos/components/multidevice/debug_webui/url_constants.h"
+#include "chromeos/components/sample_system_web_app_ui/url_constants.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/services/multidevice_setup/multidevice_setup_service.h"
@@ -194,6 +195,7 @@
 
 #if defined(OS_CHROMEOS) && !defined(OFFICIAL_BUILD)
 #include "chrome/browser/ui/webui/chromeos/emulator/device_emulator_ui.h"
+#include "chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h"
 #endif
 
 #if !defined(OS_CHROMEOS)
@@ -601,6 +603,8 @@
     if (url.host_piece() == chrome::kChromeUIDeviceEmulatorHost)
       return &NewWebUI<DeviceEmulatorUI>;
   }
+  if (url.host_piece() == chromeos::kChromeUISampleSystemWebAppHost)
+    return &NewWebUI<chromeos::SampleSystemWebAppUI>;
 #endif  // !defined(OFFICIAL_BUILD)
 #endif  // defined(OS_CHROMEOS)
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/ui/webui/chromeos/OWNERS b/chrome/browser/ui/webui/chromeos/OWNERS
index d5176c5..8ae3630 100644
--- a/chrome/browser/ui/webui/chromeos/OWNERS
+++ b/chrome/browser/ui/webui/chromeos/OWNERS
@@ -1,8 +1,9 @@
 achuith@chromium.org
+khorimoto@chromium.org
 michaelpg@chromium.org
 satorux@chromium.org
 stevenjb@chromium.org
 xiyuan@chromium.org
 
-per-file network*=file://chromeos/network/OWNERS
+per-file *net*=file://chromeos/network/OWNERS
 per-file drive_internals_ui.*=file://ui/file_manager/OWNERS
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.cc
index 0468a85..c9c2b3e 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.cc
@@ -123,20 +123,18 @@
   }
 
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
-
-  // Add Mojo bindings to this WebUI so that Mojo calls can occur in JavaScript.
-  AddHandlerToRegistry(base::BindRepeating(
-      &CellularSetupDialogUI::BindCellularSetup, base::Unretained(this)));
 }
 
 CellularSetupDialogUI::~CellularSetupDialogUI() = default;
 
-void CellularSetupDialogUI::BindCellularSetup(
+void CellularSetupDialogUI::BindInterface(
     mojo::PendingReceiver<mojom::CellularSetup> receiver) {
   GetOrCreateServiceHolder(web_ui()->GetWebContents()->GetBrowserContext())
       ->BindReceiver(std::move(receiver));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(CellularSetupDialogUI)
+
 }  // namespace cellular_setup
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.h b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.h
index 53b9ebf..9f9b65c5 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.h
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog.h
@@ -40,9 +40,12 @@
   explicit CellularSetupDialogUI(content::WebUI* web_ui);
   ~CellularSetupDialogUI() override;
 
- private:
-  void BindCellularSetup(mojo::PendingReceiver<mojom::CellularSetup> receiver);
+  // Instantiates implementor of the mojom::CellularSetup mojo interface
+  // passing the pending receiver that will be internally bound.
+  void BindInterface(mojo::PendingReceiver<mojom::CellularSetup> receiver);
 
+ private:
+  WEB_UI_CONTROLLER_TYPE_DECL();
   DISALLOW_COPY_AND_ASSIGN(CellularSetupDialogUI);
 };
 
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.cc b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.cc
index a22310f..807e9e8c 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h"
 
+#include "base/bind_helpers.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/crostini/crostini_features.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h"
@@ -23,7 +25,8 @@
 
 namespace chromeos {
 
-void CrostiniInstallerDialog::Show(Profile* profile) {
+void CrostiniInstallerDialog::Show(Profile* profile,
+                                   OnLoadedCallback on_loaded_callback) {
   DCHECK(crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
   auto* instance = SystemWebDialogDelegate::FindInstance(GetUrl().spec());
   if (instance) {
@@ -37,12 +40,17 @@
   crostini::CrostiniManager::GetForProfile(profile)->SetInstallerViewStatus(
       true);
 
-  instance = new CrostiniInstallerDialog(profile);
+  instance =
+      new CrostiniInstallerDialog(profile, std::move(on_loaded_callback));
   instance->ShowSystemDialog();
 }
 
-CrostiniInstallerDialog::CrostiniInstallerDialog(Profile* profile)
-    : SystemWebDialogDelegate{GetUrl(), /*title=*/{}}, profile_{profile} {}
+CrostiniInstallerDialog::CrostiniInstallerDialog(
+    Profile* profile,
+    OnLoadedCallback on_loaded_callback)
+    : SystemWebDialogDelegate(GetUrl(), /*title=*/base::string16()),
+      profile_(profile),
+      on_loaded_callback_(std::move(on_loaded_callback)) {}
 
 CrostiniInstallerDialog::~CrostiniInstallerDialog() {
   crostini::CrostiniManager::GetForProfile(profile_)->SetInstallerViewStatus(
@@ -81,4 +89,11 @@
   return SystemWebDialogDelegate::OnCloseContents(source, out_close_dialog);
 }
 
+void CrostiniInstallerDialog::OnWebContentsFinishedLoad() {
+  if (!on_loaded_callback_.is_null()) {
+    DCHECK(installer_ui_);
+    std::move(on_loaded_callback_).Run(installer_ui_);
+  }
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h
index 2c96d9f..9933b12 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_CROSTINI_INSTALLER_CROSTINI_INSTALLER_DIALOG_H_
 #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_CROSTINI_INSTALLER_CROSTINI_INSTALLER_DIALOG_H_
 
+#include "base/callback.h"
 #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h"
 
 class Profile;
@@ -15,10 +16,15 @@
 
 class CrostiniInstallerDialog : public SystemWebDialogDelegate {
  public:
-  static void Show(Profile* profile);
+  using OnLoadedCallback = base::OnceCallback<void(CrostiniInstallerUI*)>;
+
+  // |on_loaded_callback| is ignored if the dialog is already showing.
+  static void Show(Profile* profile,
+                   OnLoadedCallback on_loaded_callback = OnLoadedCallback());
 
  private:
-  explicit CrostiniInstallerDialog(Profile* profile);
+  CrostiniInstallerDialog(Profile* profile,
+                          OnLoadedCallback on_loaded_callback);
   ~CrostiniInstallerDialog() override;
 
   // SystemWebDialogDelegate:
@@ -29,9 +35,11 @@
   void OnDialogShown(content::WebUI* webui) override;
   void OnCloseContents(content::WebContents* source,
                        bool* out_close_dialog) override;
+  void OnWebContentsFinishedLoad() override;
 
   Profile* profile_;
   CrostiniInstallerUI* installer_ui_ = nullptr;
+  OnLoadedCallback on_loaded_callback_;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
index b81f73de..6780624 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
@@ -141,6 +141,13 @@
   return can_close_;
 }
 
+void CrostiniInstallerUI::ClickInstallForTesting() {
+  web_ui()->GetWebContents()->GetMainFrame()->ExecuteJavaScriptForTests(
+      base::ASCIIToUTF16("document.querySelector('crostini-installer-app')"
+                         ".$$('.action-button').click()"),
+      base::NullCallback());
+}
+
 void CrostiniInstallerUI::BindPageHandlerFactory(
     mojo::PendingReceiver<
         chromeos::crostini_installer::mojom::PageHandlerFactory>
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h
index f59bc18..d1752a5 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h
@@ -27,6 +27,7 @@
   ~CrostiniInstallerUI() override;
 
   bool can_close();
+  void ClickInstallForTesting();
 
  private:
   void BindPageHandlerFactory(
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
index 57a8d68..244bfc2 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
@@ -239,6 +239,8 @@
       return IDS_APP_START_APP_WAIT_MESSAGE;
     case APP_LAUNCH_STATE_WAITING_APP_WINDOW:
       return IDS_APP_START_WAIT_FOR_APP_WINDOW_MESSAGE;
+    case APP_LAUNCH_STATE_WAITING_APP_WINDOW_INSTALL_FAILED:
+      return IDS_APP_START_WAIT_FOR_APP_WINDOW_INSTALL_FAILED_MESSAGE;
     case APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT:
       return IDS_APP_START_NETWORK_WAIT_TIMEOUT_MESSAGE;
     case APP_LAUNCH_STATE_SHOWING_NETWORK_CONFIGURE_UI:
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
index 09690d5..1197a7e 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
@@ -48,6 +48,7 @@
     APP_LAUNCH_STATE_PREPARING_NETWORK,
     APP_LAUNCH_STATE_INSTALLING_APPLICATION,
     APP_LAUNCH_STATE_WAITING_APP_WINDOW,
+    APP_LAUNCH_STATE_WAITING_APP_WINDOW_INSTALL_FAILED,
     APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT,
     APP_LAUNCH_STATE_SHOWING_NETWORK_CONFIGURE_UI,
   };
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
index f105925e..09462a48 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
@@ -37,8 +37,8 @@
 
 namespace {
 
-constexpr int kDialogHeightPx = 640;
-constexpr int kDialogWidthPx = 768;
+constexpr int kPreferredDialogHeightPx = 640;
+constexpr int kPreferredDialogWidthPx = 768;
 
 }  // namespace
 
@@ -87,7 +87,14 @@
 }
 
 void MultiDeviceSetupDialog::GetDialogSize(gfx::Size* size) const {
-  size->SetSize(kDialogWidthPx, kDialogHeightPx);
+  // Note: The size is calculated once based on the current screen orientation
+  // and is not ever updated. It might be possible to resize the dialog upon
+  // each screen rotation, but https://crbug.com/1030993 prevents this from
+  // working.
+  // TODO(https://crbug.com/1030993): Explore resizing the dialog dynamically.
+  static const gfx::Size dialog_size = ComputeDialogSizeForInternalScreen(
+      gfx::Size(kPreferredDialogWidthPx, kPreferredDialogHeightPx));
+  size->SetSize(dialog_size.width(), dialog_size.height());
 }
 
 void MultiDeviceSetupDialog::OnDialogClosed(const std::string& json_retval) {
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
index 744d42d..d8b924d 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -161,9 +161,10 @@
 }
 
 syncer::SyncService* OSSyncHandler::GetSyncService() const {
-  return profile_->IsSyncAllowed()
-             ? ProfileSyncServiceFactory::GetForProfile(profile_)
-             : nullptr;
+  const bool is_sync_allowed =
+      ProfileSyncServiceFactory::IsSyncAllowed(profile_);
+  return is_sync_allowed ? ProfileSyncServiceFactory::GetForProfile(profile_)
+                         : nullptr;
 }
 
 void OSSyncHandler::AddSyncServiceObserver() {
diff --git a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc
index c90e0ee..3691bb4 100644
--- a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc
+++ b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h"
 
+#include <algorithm>
 #include <list>
 
 #include "ash/public/cpp/shell_window_ids.h"
@@ -21,6 +22,9 @@
 #include "content/public/browser/web_ui.h"
 #include "third_party/blink/public/common/page/page_zoom.h"
 #include "ui/aura/window.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "ui/gfx/geometry/insets.h"
 
 namespace chromeos {
 
@@ -35,6 +39,9 @@
 }  // namespace
 
 // static
+const size_t SystemWebDialogDelegate::kDialogMarginForInternalScreenPx = 48;
+
+// static
 SystemWebDialogDelegate* SystemWebDialogDelegate::FindInstance(
     const std::string& id) {
   auto* instances = GetInstances();
@@ -53,6 +60,46 @@
   return it != instances->end();
 }
 
+// static
+gfx::Size SystemWebDialogDelegate::ComputeDialogSizeForInternalScreen(
+    const gfx::Size& preferred_size) {
+  // If the device has no internal display (e.g., for Chromeboxes), use the
+  // preferred size.
+  // TODO(https://crbug.com/1035060): It could be possible that a Chromebox is
+  // hooked up to a low-resolution monitor. It might be a good idea to check
+  // that display's resolution as well.
+  if (!display::Display::HasInternalDisplay())
+    return preferred_size;
+
+  // According to the Chrome OS dialog spec, dialogs should have a 48px margin
+  // from the edge of an internal display.
+  static const gfx::Insets margins =
+      gfx::Insets(kDialogMarginForInternalScreenPx);
+
+  display::Display internal_display;
+  if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
+          display::Display::InternalDisplayId(), &internal_display)) {
+    NOTREACHED() << "Could not fetch metadata for internal display.";
+  }
+
+  // Work area size does not include the status bar.
+  gfx::Size work_area_size = internal_display.work_area_size();
+
+  // The max width possible is the screen's width adjusted by the left/right
+  // margins.
+  int max_work_area_width =
+      work_area_size.width() - margins.left() - margins.right();
+
+  // The max height possible is the screen's height adjusted by the top/bottom
+  // margins.
+  int max_work_area_height =
+      work_area_size.height() - margins.top() - margins.bottom();
+
+  // Take the minimum of the preferred size and the max size.
+  return gfx::Size(std::min({preferred_size.width(), max_work_area_width}),
+                   std::min({preferred_size.height(), max_work_area_height}));
+}
+
 SystemWebDialogDelegate::SystemWebDialogDelegate(const GURL& gurl,
                                                  const base::string16& title)
     : gurl_(gurl), title_(title), modal_type_(ui::MODAL_TYPE_NONE) {
diff --git a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h
index 1b58252..9f35218c 100644
--- a/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h
+++ b/chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h
@@ -9,7 +9,9 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/strings/string16.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/views/widget/widget.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "url/gurl.h"
@@ -25,6 +27,10 @@
 
 class SystemWebDialogDelegate : public ui::WebDialogDelegate {
  public:
+  // Default margin (in pixels) used when sizing a dialog to an internal screen;
+  // see ComputeDialogSizeForInternalScreen().
+  static const size_t kDialogMarginForInternalScreenPx;
+
   // Returns the instance whose Id() matches |id|. If more than one instance
   // matches, the first matching instance created is returned.
   static SystemWebDialogDelegate* FindInstance(const std::string& id);
@@ -32,6 +38,14 @@
   // Returns true if there is a system dialog with |url| loaded.
   static bool HasInstance(const GURL& url);
 
+  // Generates a dialog size which fits within the device's internal screen. If
+  // possible, this function simply returns |preferred_size|, but if that size
+  // does not fit within the screen's bounds with a margin of
+  // |kDialogMarginForInternalScreenPx| pixels on all sides, a smaller size is
+  // returned.
+  static gfx::Size ComputeDialogSizeForInternalScreen(
+      const gfx::Size& preferred_size);
+
   // |gurl| is the HTML file path for the dialog content and must be set.
   // |title| may be empty in which case ShouldShowDialogTitle() returns false.
   SystemWebDialogDelegate(const GURL& gurl, const base::string16& title);
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
index 4aa42978..dab3013 100644
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
+++ b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
@@ -28,15 +28,13 @@
   source->SetDefaultResource(IDR_FEED_INTERNALS_HTML);
 
   content::WebUIDataSource::Add(profile_, source);
-  // This class is the caller of the callback when an observer interface is
-  // triggered. So this base::Unretained is safe.
-  AddHandlerToRegistry(base::BindRepeating(
-      &FeedInternalsUI::BindFeedInternalsPageHandler, base::Unretained(this)));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(FeedInternalsUI)
+
 FeedInternalsUI::~FeedInternalsUI() = default;
 
-void FeedInternalsUI::BindFeedInternalsPageHandler(
+void FeedInternalsUI::BindInterface(
     mojo::PendingReceiver<feed_internals::mojom::PageHandler> receiver) {
   page_handler_ = std::make_unique<FeedInternalsPageHandler>(
       std::move(receiver),
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
index 662b9bb..ee87ead 100644
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
+++ b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
@@ -27,14 +27,18 @@
   explicit FeedInternalsUI(content::WebUI* web_ui);
   ~FeedInternalsUI() override;
 
- private:
-  void BindFeedInternalsPageHandler(
+  // Instantiates the implementor of the feed_internals::mojom::PageHandler mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(
       mojo::PendingReceiver<feed_internals::mojom::PageHandler> receiver);
 
+ private:
   Profile* profile_;
 
   std::unique_ptr<FeedInternalsPageHandler> page_handler_;
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(FeedInternalsUI);
 };
 
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 162be20..b6496808 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -85,14 +85,13 @@
   content::URLDataSource::Add(
       profile_, std::make_unique<FaviconSource>(
                     profile_, chrome::FaviconUrlFormat::kFavicon2));
-
-  AddHandlerToRegistry(base::BindRepeating(
-      &NewTabPageUI::BindPageHandlerFactory, base::Unretained(this)));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(NewTabPageUI)
+
 NewTabPageUI::~NewTabPageUI() = default;
 
-void NewTabPageUI::BindPageHandlerFactory(
+void NewTabPageUI::BindInterface(
     mojo::PendingReceiver<new_tab_page::mojom::PageHandlerFactory>
         pending_receiver) {
   if (page_factory_receiver_.is_bound()) {
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h
index af22ce9..a99acc7 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h
@@ -27,11 +27,13 @@
 
   static bool IsNewTabPageOrigin(const GURL& url);
 
- private:
-  void BindPageHandlerFactory(
+  // Instantiates the implementor of the mojom::PageHandlerFactory mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(
       mojo::PendingReceiver<new_tab_page::mojom::PageHandlerFactory>
           pending_receiver);
 
+ private:
   // new_tab_page::mojom::PageHandlerFactory:
   void CreatePageHandler(
       mojo::PendingRemote<new_tab_page::mojom::Page> pending_page,
@@ -45,6 +47,8 @@
 
   Profile* profile_;
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(NewTabPageUI);
 };
 
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
index 0b5b49c..1f6badd 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
@@ -43,14 +43,14 @@
   source->SetDefaultResource(IDR_OMNIBOX_HTML);
 
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
-  AddHandlerToRegistry(base::BindRepeating(&OmniboxUI::BindOmniboxPageHandler,
-                                           base::Unretained(this)));
   web_ui->AddMessageHandler(std::make_unique<VersionHandler>());
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(OmniboxUI)
+
 OmniboxUI::~OmniboxUI() {}
 
-void OmniboxUI::BindOmniboxPageHandler(
+void OmniboxUI::BindInterface(
     mojo::PendingReceiver<mojom::OmniboxPageHandler> receiver) {
   omnibox_handler_ = std::make_unique<OmniboxPageHandler>(
       Profile::FromWebUI(web_ui()), std::move(receiver));
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.h b/chrome/browser/ui/webui/omnibox/omnibox_ui.h
index 81f3ad0e..efee9cd 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.h
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.h
@@ -18,12 +18,15 @@
   explicit OmniboxUI(content::WebUI* contents);
   ~OmniboxUI() override;
 
- private:
-  void BindOmniboxPageHandler(
-      mojo::PendingReceiver<mojom::OmniboxPageHandler> receiver);
+  // Instantiates the implementor of the mojom::OmniboxPageHandler mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(mojo::PendingReceiver<mojom::OmniboxPageHandler> receiver);
 
+ private:
   std::unique_ptr<OmniboxPageHandler> omnibox_handler_;
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(OmniboxUI);
 };
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 76f8589a..b32270a 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <set>
 #include <string>
 #include <utility>
 #include <vector>
@@ -16,6 +17,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/feature_list.h"
 #include "base/i18n/number_formatting.h"
 #include "base/json/json_reader.h"
@@ -340,9 +342,24 @@
 
   base::Optional<int> color_mode_opt = print_settings.FindIntKey(kSettingColor);
   if (color_mode_opt.has_value()) {
-    base::Optional<bool> is_color =
-        IsColorModelSelected(color_mode_opt.value());
-    ReportPrintSettingHistogram(is_color.value() ? COLOR : BLACK_AND_WHITE);
+    if (color_mode_opt.value() != UNKNOWN_COLOR_MODEL) {
+      base::Optional<bool> is_color =
+          IsColorModelSelected(color_mode_opt.value());
+      ReportPrintSettingHistogram(is_color.value() ? COLOR : BLACK_AND_WHITE);
+    } else {
+      // Getting to this block means the printing backend does not understand
+      // the printer's color capabilities. Record a non-fatal crash dump for
+      // this once per device.
+      // TODO(thestig): Make sure the crash dump has sufficient information so
+      // developers can take action and fix the parsing of the printer's color
+      // capabilities.
+      static base::NoDestructor<std::set<std::string>> seen_devices;
+      auto result = seen_devices->insert(
+          *print_settings.FindStringKey(kSettingDeviceName));
+      bool inserted = result.second;
+      if (inserted)
+        base::debug::DumpWithoutCrashing();
+    }
   }
 
   if (preview_settings.FindIntKey(kSettingMarginsType).value_or(0) != 0)
diff --git a/chrome/browser/ui/webui/reset_password/reset_password_ui.cc b/chrome/browser/ui/webui/reset_password/reset_password_ui.cc
index e6293d9e..82980ec 100644
--- a/chrome/browser/ui/webui/reset_password/reset_password_ui.cc
+++ b/chrome/browser/ui/webui/reset_password/reset_password_ui.cc
@@ -121,14 +121,13 @@
 
   content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
                                 html_source.release());
-
-  AddHandlerToRegistry(base::BindRepeating(
-      &ResetPasswordUI::BindResetPasswordHandler, base::Unretained(this)));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(ResetPasswordUI)
+
 ResetPasswordUI::~ResetPasswordUI() {}
 
-void ResetPasswordUI::BindResetPasswordHandler(
+void ResetPasswordUI::BindInterface(
     mojo::PendingReceiver<mojom::ResetPasswordHandler> receiver) {
   ui_handler_ = std::make_unique<ResetPasswordHandlerImpl>(
       web_ui()->GetWebContents(), std::move(receiver));
diff --git a/chrome/browser/ui/webui/reset_password/reset_password_ui.h b/chrome/browser/ui/webui/reset_password/reset_password_ui.h
index 3bd3946..901a026b 100644
--- a/chrome/browser/ui/webui/reset_password/reset_password_ui.h
+++ b/chrome/browser/ui/webui/reset_password/reset_password_ui.h
@@ -24,15 +24,19 @@
   explicit ResetPasswordUI(content::WebUI* web_ui);
   ~ResetPasswordUI() override;
 
- private:
-  void BindResetPasswordHandler(
+  // Instantiates the implementor of the mojom::ResetPasswordHandler mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(
       mojo::PendingReceiver<mojom::ResetPasswordHandler> receiver);
 
+ private:
   base::DictionaryValue PopulateStrings() const;
 
   std::unique_ptr<mojom::ResetPasswordHandler> ui_handler_;
   const PasswordType password_type_;
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(ResetPasswordUI);
 };
 
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index 21c3de5..802b528 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -340,9 +340,10 @@
                          os_with_linux_license);
   html_source->AddBoolean("aboutEnterpriseManaged", IsEnterpriseManaged());
 
-  html_source->AddString("endOfLifeMessage", l10n_util::GetStringFUTF16(
-                                                 IDS_EOL_NOTIFICATION_EOL,
-                                                 ui::GetChromeOSDeviceName()));
+  html_source->AddString(
+      "endOfLifeMessage",
+      l10n_util::GetStringFUTF16(IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE,
+                                 ui::GetChromeOSDeviceName()));
   html_source->AddString("endOfLifeLearnMoreURL",
                          base::ASCIIToUTF16(chrome::kEolNotificationURL));
 #endif
@@ -675,7 +676,8 @@
     response.SetStringKey("aboutPageEndOfLifeMessage",
                           l10n_util::GetStringFUTF16(
                               IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE,
-                              base::TimeFormatMonthAndYear(eol_info.eol_date)));
+                              base::TimeFormatMonthAndYear(eol_info.eol_date),
+                              base::ASCIIToUTF16(chrome::kEolNotificationURL)));
   } else {
     response.SetBoolKey("hasEndOfLife", false);
     response.SetStringKey("aboutPageEndOfLifeMessage", "");
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
index 6c36ec0..eccb758 100644
--- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/crostini/crostini_installer.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
 #include "chrome/browser/chromeos/guest_os/guest_os_share_path.h"
@@ -137,8 +138,8 @@
 void CrostiniHandler::HandleRequestCrostiniInstallerView(
     const base::ListValue* args) {
   AllowJavascript();
-  ShowCrostiniInstallerView(Profile::FromWebUI(web_ui()),
-                            crostini::CrostiniUISurface::kSettings);
+  crostini::CrostiniInstaller::GetForProfile(Profile::FromWebUI(web_ui()))
+      ->ShowDialog(crostini::CrostiniUISurface::kSettings);
 }
 
 void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index ebab9b0..f76b09e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -39,10 +39,10 @@
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/common/webui_url_constants.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
 #include "chromeos/printing/ppd_line_reader.h"
-#include "chromeos/printing/ppd_provider.h"
 #include "chromeos/printing/printer_configuration.h"
 #include "chromeos/printing/printer_translator.h"
 #include "chromeos/printing/printing_constants.h"
@@ -1192,18 +1192,51 @@
 }
 
 void CupsPrintersHandler::HandleGetEulaUrl(const base::ListValue* args) {
-  std::string callback_id;
-  std::string ppdManufacturer;
-  std::string ppdModel;
   CHECK_EQ(3U, args->GetSize());
-  CHECK(args->GetString(0, &callback_id));
-  CHECK(args->GetString(1, &ppdManufacturer));
-  CHECK(args->GetString(2, &ppdModel));
+  const std::string callback_id = args->GetList()[0].GetString();
+  const std::string ppd_manufacturer = args->GetList()[1].GetString();
+  const std::string ppd_model = args->GetList()[2].GetString();
 
-  // TODO(crbug/958272): Implement this function to check if a |ppdModel| has an
-  // EULA.
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value("" /* eulaUrl */));
+  auto resolved_printers_it = resolved_printers_.find(ppd_manufacturer);
+  if (resolved_printers_it == resolved_printers_.end()) {
+    // Exit early if lookup for printers fails for |ppd_manufacturer|.
+    OnGetEulaUrl(callback_id, PpdProvider::CallbackResultCode::NOT_FOUND,
+                 /*license=*/std::string());
+    return;
+  }
+
+  const PpdProvider::ResolvedPrintersList& printers_for_manufacturer =
+      resolved_printers_it->second;
+
+  auto printer_it = std::find_if(
+      printers_for_manufacturer.begin(), printers_for_manufacturer.end(),
+      [&ppd_model](const auto& elem) { return elem.name == ppd_model; });
+
+  if (printer_it == printers_for_manufacturer.end()) {
+    // Unable to find the PpdReference, resolve promise with empty string.
+    OnGetEulaUrl(callback_id, PpdProvider::CallbackResultCode::NOT_FOUND,
+                 /*license=*/std::string());
+    return;
+  }
+
+  ppd_provider_->ResolvePpdLicense(
+      printer_it->ppd_ref.effective_make_and_model,
+      base::BindOnce(&CupsPrintersHandler::OnGetEulaUrl,
+                     weak_factory_.GetWeakPtr(), callback_id));
+}
+
+void CupsPrintersHandler::OnGetEulaUrl(const std::string& callback_id,
+                                       PpdProvider::CallbackResultCode result,
+                                       const std::string& license) {
+  if (result != PpdProvider::SUCCESS || license.empty()) {
+    ResolveJavascriptCallback(base::Value(callback_id), base::Value());
+    return;
+  }
+
+  GURL eula_url(chrome::kChromeUIOSCreditsURL + license);
+  ResolveJavascriptCallback(
+      base::Value(callback_id),
+      eula_url.is_valid() ? base::Value(eula_url.spec()) : base::Value());
 }
 
 void CupsPrintersHandler::OnIpResolved(const std::string& callback_id,
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
index 3ecb134..6e80a91 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/chromeos/printing/printer_configurer.h"
 #include "chrome/browser/chromeos/printing/printer_event_tracker.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/printing/ppd_provider.h"
 #include "chromeos/printing/printer_configuration.h"
 #include "printing/printer_query_result_chromeos.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
@@ -34,7 +35,6 @@
 
 namespace chromeos {
 
-class PpdProvider;
 class ServerPrintersFetcher;
 
 namespace settings {
@@ -188,6 +188,11 @@
   // Handles getting the EULA URL if available.
   void HandleGetEulaUrl(const base::ListValue* args);
 
+  // Post EULA URL callback.
+  void OnGetEulaUrl(const std::string& callback_id,
+                    PpdProvider::CallbackResultCode result,
+                    const std::string& eula_url);
+
   // ui::SelectFileDialog::Listener override:
   void FileSelected(const base::FilePath& path,
                     int index,
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index 49740b0..a80bb8f 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -432,7 +432,7 @@
 }
 
 syncer::SyncService* PeopleHandler::GetSyncService() const {
-  return profile_->IsSyncAllowed()
+  return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
              ? ProfileSyncServiceFactory::GetForProfile(profile_)
              : nullptr;
 }
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index 60c758ab..a85fd36 100644
--- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -265,7 +265,7 @@
   // Setup the expectations for calls made when displaying the config page.
   void SetDefaultExpectationsForConfigPage() {
     ON_CALL(*mock_sync_service_, GetDisableReasons())
-        .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+        .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
     ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
         .WillByDefault(Return(true));
     ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -389,7 +389,7 @@
 
 TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
   ON_CALL(*mock_sync_service_, GetDisableReasons())
-      .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+      .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
       .WillByDefault(Return(true));
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
@@ -425,7 +425,7 @@
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
       .WillByDefault(Return(false));
   ON_CALL(*mock_sync_service_, GetDisableReasons())
-      .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+      .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
       .WillByDefault(Return(true));
   // Sync engine is stopped initially, and will start up.
@@ -464,7 +464,7 @@
 TEST_F(PeopleHandlerTest,
        DisplayConfigureWithEngineDisabledAndCancelAfterSigninSuccess) {
   ON_CALL(*mock_sync_service_, GetDisableReasons())
-      .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+      .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
       .WillByDefault(Return(true));
   ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
@@ -507,7 +507,7 @@
         // SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
         // immediately starts initializing the engine.
         ON_CALL(*mock_sync_service_, GetDisableReasons())
-            .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+            .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
         ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
             .WillByDefault(Return(true));
         ON_CALL(*mock_sync_service_, GetTransportState())
@@ -538,7 +538,7 @@
         // SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE. Since the
         // engine is already running, it just gets reconfigured.
         ON_CALL(*mock_sync_service_, GetDisableReasons())
-            .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+            .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
         ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
             .WillByDefault(Return(true));
         ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1062,7 +1062,7 @@
         // SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
         // immediately starts initializing the engine.
         ON_CALL(*mock_sync_service_, GetDisableReasons())
-            .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+            .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
         ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
             .WillByDefault(Return(true));
         ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1128,7 +1128,7 @@
         // SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
         // immediately starts initializing the engine.
         ON_CALL(*mock_sync_service_, GetDisableReasons())
-            .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+            .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
         ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
             .WillByDefault(Return(true));
         ON_CALL(*mock_sync_service_, GetTransportState())
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index a2e47ca1..191ece0 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -60,6 +60,7 @@
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_utils.h"
 #include "components/sync/driver/sync_user_settings.h"
+#include "components/zoom/page_zoom_constants.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/content_features.h"
@@ -772,6 +773,9 @@
 #endif
   };
   AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+  html_source->AddString("presetZoomFactors",
+                         zoom::GetPresetZoomFactorsAsJSON());
 }
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
index 7f36b09..a3bb91a2 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -418,7 +418,7 @@
 }
 
 syncer::SyncService* DiceTurnSyncOnHelper::GetSyncService() {
-  return profile_->IsSyncAllowed()
+  return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
              ? ProfileSyncServiceFactory::GetForProfile(profile_)
              : nullptr;
 }
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
index cb32b23..9da827e 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
@@ -274,7 +274,7 @@
     syncer::MockSyncService* mock_sync_service = GetMockSyncService();
     EXPECT_CALL(*mock_sync_service, GetSetupInProgressHandle()).Times(1);
     ON_CALL(*mock_sync_service, GetDisableReasons())
-        .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+        .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
     ON_CALL(*mock_sync_service, GetTransportState())
         .WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE));
   }
@@ -283,7 +283,7 @@
     syncer::MockSyncService* mock_sync_service = GetMockSyncService();
     EXPECT_CALL(*mock_sync_service, GetSetupInProgressHandle()).Times(1);
     ON_CALL(*mock_sync_service, GetDisableReasons())
-        .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+        .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
     ON_CALL(*mock_sync_service, GetTransportState())
         .WillByDefault(
             Return(syncer::SyncService::TransportState::INITIALIZING));
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc
index f370580..05ada48d 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -71,8 +71,7 @@
   AllowJavascript();
   content::WebContents* contents = web_ui()->GetWebContents();
   content::StoragePartition* partition =
-      content::BrowserContext::GetStoragePartitionForSite(
-          contents->GetBrowserContext(), signin::GetSigninPartitionURL());
+      signin::GetSigninPartition(contents->GetBrowserContext());
   if (partition) {
     const GURL& current_url = web_ui()->GetWebContents()->GetURL();
 
@@ -160,8 +159,7 @@
   // CookieManager.
   content::WebContents* contents = web_ui()->GetWebContents();
   content::StoragePartition* partition =
-      content::BrowserContext::GetStoragePartitionForSite(
-          contents->GetBrowserContext(), signin::GetSigninPartitionURL());
+      signin::GetSigninPartition(contents->GetBrowserContext());
 
   partition->GetCookieManagerForBrowserProcess()->GetCookieList(
       GaiaUrls::GetInstance()->gaia_url(),
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index 2b8e201ce..7614485 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -597,8 +597,7 @@
   DCHECK(!auth_code.empty());
 
   content::StoragePartition* partition =
-      content::BrowserContext::GetStoragePartitionForSite(
-          contents->GetBrowserContext(), signin::GetSigninPartitionURL());
+      signin::GetSigninPartition(contents->GetBrowserContext());
 
   // If this was called from the user manager to reauthenticate the profile,
   // the current profile is the system profile.  In this case, use the email to
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
index f98fd1b..797d318 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/signin_view_controller_delegate.h"
@@ -89,7 +90,7 @@
 }
 
 void SyncConfirmationHandler::HandleGoToSettings(const base::ListValue* args) {
-  DCHECK(profile_->IsSyncAllowed());
+  DCHECK(ProfileSyncServiceFactory::IsSyncAllowed(profile_));
   did_user_explicitly_interact_ = true;
   RecordConsent(args);
   CloseModalSigninWindow(LoginUIService::CONFIGURE_SYNC_FIRST);
@@ -102,7 +103,7 @@
 
 void SyncConfirmationHandler::HandleAccountImageRequest(
     const base::ListValue* args) {
-  DCHECK(profile_->IsSyncAllowed());
+  DCHECK(ProfileSyncServiceFactory::IsSyncAllowed(profile_));
   base::Optional<AccountInfo> primary_account_info =
       identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken(
           identity_manager_->GetPrimaryAccountInfo());
@@ -152,7 +153,7 @@
 }
 
 void SyncConfirmationHandler::SetUserImageURL(const std::string& picture_url) {
-  if (!profile_->IsSyncAllowed()) {
+  if (!ProfileSyncServiceFactory::IsSyncAllowed(profile_)) {
     // The sync disabled confirmation handler does not present the user image.
     // Avoid updating the image URL in this case.
     return;
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index 51e035b6..738c558cd 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -28,7 +28,8 @@
 SyncConfirmationUI::SyncConfirmationUI(content::WebUI* web_ui)
     : SigninWebDialogUI(web_ui) {
   Profile* profile = Profile::FromWebUI(web_ui);
-  bool is_sync_allowed = profile->IsSyncAllowed();
+  const bool is_sync_allowed =
+      ProfileSyncServiceFactory::IsSyncAllowed(profile);
 
   content::WebUIDataSource* source =
       content::WebUIDataSource::Create(chrome::kChromeUISyncConfirmationHost);
diff --git a/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.cc b/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.cc
index 7fa844b..a2af880 100644
--- a/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.cc
+++ b/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.cc
@@ -38,14 +38,13 @@
       ContentSuggestionsServiceFactory::GetInstance()->GetForProfile(profile);
   pref_service_ = profile->GetPrefs();
   content::WebUIDataSource::Add(profile, source);
-  AddHandlerToRegistry(base::BindRepeating(
-      &SnippetsInternalsUI::BindSnippetsInternalsPageHandlerFactory,
-      base::Unretained(this)));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(SnippetsInternalsUI)
+
 SnippetsInternalsUI::~SnippetsInternalsUI() {}
 
-void SnippetsInternalsUI::BindSnippetsInternalsPageHandlerFactory(
+void SnippetsInternalsUI::BindInterface(
     mojo::PendingReceiver<snippets_internals::mojom::PageHandlerFactory>
         receiver) {
   receiver_.reset();
diff --git a/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h b/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h
index 524b74f..2852762 100644
--- a/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h
+++ b/chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h
@@ -29,11 +29,13 @@
       mojo::PendingRemote<snippets_internals::mojom::Page> page,
       CreatePageHandlerCallback callback) override;
 
- private:
-  void BindSnippetsInternalsPageHandlerFactory(
+  // Instantiates the implementor of the mojom::PageHandlerFactory mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(
       mojo::PendingReceiver<snippets_internals::mojom::PageHandlerFactory>
           receiver);
 
+ private:
   std::unique_ptr<SnippetsInternalsPageHandler> page_handler_;
   ntp_snippets::ContentSuggestionsService* content_suggestions_service_;
   PrefService* pref_service_;
@@ -41,6 +43,8 @@
   // Receiver from the mojo interface to concrete impl.
   mojo::Receiver<snippets_internals::mojom::PageHandlerFactory> receiver_{this};
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(SnippetsInternalsUI);
 };
 
diff --git a/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc b/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc
index 39656343..582e633 100644
--- a/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc
+++ b/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc
@@ -39,13 +39,13 @@
   source->SetDefaultResource(IDR_USB_INTERNALS_HTML);
 
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
-  AddHandlerToRegistry(base::BindRepeating(
-      &UsbInternalsUI::BindUsbInternalsPageHandler, base::Unretained(this)));
 }
 
+WEB_UI_CONTROLLER_TYPE_IMPL(UsbInternalsUI)
+
 UsbInternalsUI::~UsbInternalsUI() {}
 
-void UsbInternalsUI::BindUsbInternalsPageHandler(
+void UsbInternalsUI::BindInterface(
     mojo::PendingReceiver<mojom::UsbInternalsPageHandler> receiver) {
   page_handler_ =
       std::make_unique<UsbInternalsPageHandler>(std::move(receiver));
diff --git a/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h b/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h
index 249d3762..3208b02 100644
--- a/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h
+++ b/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h
@@ -18,12 +18,16 @@
   explicit UsbInternalsUI(content::WebUI* web_ui);
   ~UsbInternalsUI() override;
 
- private:
-  void BindUsbInternalsPageHandler(
+  // Instantiates the implementor of the mojom::UsbInternalsPageHandler mojo
+  // interface passing the pending receiver that will be internally bound.
+  void BindInterface(
       mojo::PendingReceiver<mojom::UsbInternalsPageHandler> receiver);
 
+ private:
   std::unique_ptr<UsbInternalsPageHandler> page_handler_;
 
+  WEB_UI_CONTROLLER_TYPE_DECL();
+
   DISALLOW_COPY_AND_ASSIGN(UsbInternalsUI);
 };
 
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index 8e99a921..62d1ce387 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -23,6 +23,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/app_modal/javascript_app_modal_dialog.h"
 #include "components/app_modal/native_app_modal_dialog.h"
+#include "components/embedder_support/switches.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
@@ -132,7 +133,7 @@
         testing::UnitTest::GetInstance()->current_test_info();
     if (strstr(test_info->name(), "BrowserCloseTabWhenOtherTabHasListener") !=
         nullptr) {
-      command_line->AppendSwitch(switches::kDisablePopupBlocking);
+      command_line->AppendSwitch(embedder_support::kDisablePopupBlocking);
     } else if (strstr(test_info->name(), "BrowserTerminateBeforeUnload") !=
                nullptr) {
 #if defined(OS_POSIX)
diff --git a/chrome/browser/usb/usb_tab_helper.cc b/chrome/browser/usb/usb_tab_helper.cc
index 046c20c..2243dcd 100644
--- a/chrome/browser/usb/usb_tab_helper.cc
+++ b/chrome/browser/usb/usb_tab_helper.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "chrome/browser/usb/web_usb_service_impl.h"
+#include "components/performance_manager/public/decorators/page_live_state_decorator.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/common/content_features.h"
@@ -71,19 +72,23 @@
 
 void UsbTabHelper::IncrementConnectionCount(
     RenderFrameHost* render_frame_host) {
+  const bool was_device_connected = IsDeviceConnected();
   auto it = frame_usb_services_.find(render_frame_host);
   DCHECK(it != frame_usb_services_.end());
   it->second->device_connection_count_++;
-  NotifyTabStateChanged();
+  if (!was_device_connected)
+    NotifyIsDeviceConnectedChanged(/*is_device_connected=*/true);
 }
 
 void UsbTabHelper::DecrementConnectionCount(
     RenderFrameHost* render_frame_host) {
+  DCHECK(IsDeviceConnected());
   auto it = frame_usb_services_.find(render_frame_host);
   DCHECK(it != frame_usb_services_.end());
   DCHECK_GT(it->second->device_connection_count_, 0);
   it->second->device_connection_count_--;
-  NotifyTabStateChanged();
+  if (!IsDeviceConnected())
+    NotifyIsDeviceConnectedChanged(/*is_device_connected=*/false);
 }
 
 bool UsbTabHelper::IsDeviceConnected() const {
@@ -131,8 +136,10 @@
 }
 
 void UsbTabHelper::DeleteFrameServices(RenderFrameHost* render_frame_host) {
+  const bool was_device_connected = IsDeviceConnected();
   frame_usb_services_.erase(render_frame_host);
-  NotifyTabStateChanged();
+  if (was_device_connected && !IsDeviceConnected())
+    NotifyIsDeviceConnectedChanged(/*is_device_connected=*/false);
 }
 
 base::WeakPtr<WebUsbChooser> UsbTabHelper::GetUsbChooser(
@@ -149,7 +156,11 @@
   return frame_usb_services->usb_chooser->GetWeakPtr();
 }
 
-void UsbTabHelper::NotifyTabStateChanged() const {
+void UsbTabHelper::NotifyIsDeviceConnectedChanged(
+    bool is_device_connected) const {
+  performance_manager::PageLiveStateDecorator::OnIsConnectedToUSBDeviceChanged(
+      web_contents(), is_device_connected);
+
   // TODO(https://crbug.com/601627): Implement tab indicator for Android.
 #if !defined(OS_ANDROID)
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
diff --git a/chrome/browser/usb/usb_tab_helper.h b/chrome/browser/usb/usb_tab_helper.h
index 94c3aef..2c93067 100644
--- a/chrome/browser/usb/usb_tab_helper.h
+++ b/chrome/browser/usb/usb_tab_helper.h
@@ -60,7 +60,7 @@
   base::WeakPtr<WebUsbChooser> GetUsbChooser(
       content::RenderFrameHost* render_frame_host);
 
-  void NotifyTabStateChanged() const;
+  void NotifyIsDeviceConnectedChanged(bool is_device_connected) const;
 
   bool AllowedByFeaturePolicy(
       content::RenderFrameHost* render_frame_host) const;
diff --git a/chrome/browser/usb/usb_tab_helper_unittest.cc b/chrome/browser/usb/usb_tab_helper_unittest.cc
new file mode 100644
index 0000000..07e54f5
--- /dev/null
+++ b/chrome/browser/usb/usb_tab_helper_unittest.cc
@@ -0,0 +1,131 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/usb/usb_tab_helper.h"
+
+#include "chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h"
+#include "chrome/browser/usb/usb_chooser_context.h"
+#include "chrome/browser/usb/usb_chooser_context_factory.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/performance_manager/embedder/performance_manager_registry.h"
+#include "components/performance_manager/test_support/page_live_state_decorator.h"
+#include "content/public/test/web_contents_tester.h"
+#include "services/device/public/cpp/test/fake_usb_device_manager.h"
+#include "services/service_manager/public/cpp/test/test_service.h"
+#include "services/service_manager/public/cpp/test/test_service_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/usb/web_usb_service.mojom.h"
+#include "url/url_constants.h"
+
+class UsbTabHelperTest
+    : public resource_coordinator::testing::ChromeTestHarnessWithLocalDB {
+ protected:
+  UsbTabHelperTest() = default;
+  ~UsbTabHelperTest() override = default;
+
+  void SetUp() override {
+    resource_coordinator::testing::ChromeTestHarnessWithLocalDB::SetUp();
+
+    auto* chooser_context = UsbChooserContextFactory::GetForProfile(profile());
+    mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager;
+    device_manager_.AddReceiver(
+        device_manager.InitWithNewPipeAndPassReceiver());
+    chooser_context->SetDeviceManagerForTesting(std::move(device_manager));
+
+    performance_manager::PerformanceManagerRegistry::GetInstance()
+        ->CreatePageNodeForWebContents(web_contents());
+  }
+
+ private:
+  device::FakeUsbDeviceManager device_manager_;
+};
+
+TEST_F(UsbTabHelperTest, IncrementDecrementConnectionCount) {
+  mojo::Remote<blink::mojom::WebUsbService> remote;
+
+  UsbTabHelper* helper =
+      UsbTabHelper::GetOrCreateForWebContents(web_contents());
+  helper->CreateWebUsbService(main_rfh(), remote.BindNewPipeAndPassReceiver());
+  EXPECT_FALSE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      false);
+
+  // Increment the USB connection count. Expect USBTabHelper and
+  // PerformanceManager to indicate that the tab is attached to USB.
+  helper->IncrementConnectionCount(main_rfh());
+  EXPECT_TRUE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      true);
+
+  // Increment the USB connection count again. State shouldn't change in
+  // USBTabHelper and in the PerformanceManager.
+  helper->IncrementConnectionCount(main_rfh());
+  EXPECT_TRUE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      true);
+
+  // Decrement the USB connection count. State shouldn't change in USBTabHelper
+  // and in the PerformanceManager as one connection remains.
+  helper->DecrementConnectionCount(main_rfh());
+  EXPECT_TRUE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      true);
+
+  // Decrement the USB connection count again. Expect USBTabHelper and
+  // PerformanceManager to indicate that the tab is *not* attached to USB.
+  helper->DecrementConnectionCount(main_rfh());
+  EXPECT_FALSE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      false);
+}
+
+TEST_F(UsbTabHelperTest, Navigate) {
+  mojo::Remote<blink::mojom::WebUsbService> remote;
+
+  UsbTabHelper* helper =
+      UsbTabHelper::GetOrCreateForWebContents(web_contents());
+  helper->CreateWebUsbService(main_rfh(), remote.BindNewPipeAndPassReceiver());
+  EXPECT_FALSE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      false);
+
+  // Increment the USB connection count. Expect USBTabHelper and
+  // PerformanceManager to indicate that the tab is attached to USB.
+  helper->IncrementConnectionCount(main_rfh());
+  EXPECT_TRUE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      true);
+
+  // Navigate away. Expect USBTabHelper and PerformanceManager to indicate that
+  // the tab is no longer attached to USB.
+  content::WebContentsTester::For(web_contents())
+      ->NavigateAndCommit(GURL(url::kAboutBlankURL));
+  EXPECT_FALSE(helper->IsDeviceConnected());
+  performance_manager::TestPageLiveStatePropertyOnPMSequence(
+      web_contents(),
+      &performance_manager::PageLiveStateDecorator::Data::
+          IsConnectedToUSBDevice,
+      false);
+}
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 767ce88..3b8b908 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -69,6 +69,10 @@
       "//components/arc:arc_base",
       "//components/arc/mojom",
     ]
+
+    if (!is_official_build) {
+      deps += [ "//chromeos/components/sample_system_web_app_ui" ]
+    }
   }
 
   public_deps = [
@@ -99,6 +103,8 @@
     "test/test_pending_app_manager.h",
     "test/test_system_web_app_manager.cc",
     "test/test_system_web_app_manager.h",
+    "test/test_system_web_app_web_ui_controller_factory.cc",
+    "test/test_system_web_app_web_ui_controller_factory.h",
     "test/test_web_app_database_factory.cc",
     "test/test_web_app_database_factory.h",
     "test/test_web_app_registry_controller.cc",
@@ -120,6 +126,7 @@
     ":web_app_test_group",
     ":web_applications",
     "//base/test:test_support",
+    "//chrome/app/theme:chrome_unscaled_resources_grit",
     "//chrome/browser",
     "//chrome/browser/web_applications/components",
     "//components/crx_file:crx_file",
@@ -217,6 +224,8 @@
   testonly = true
 
   sources = [
+    "test/test_system_web_app_installation.cc",
+    "test/test_system_web_app_installation.h",
     "test/test_web_app_provider.cc",
     "test/test_web_app_provider.h",
   ]
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn
index 9dd348c..2b1d5923 100644
--- a/chrome/browser/web_applications/components/BUILD.gn
+++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -4,7 +4,6 @@
 
 source_set("components") {
   sources = [
-    "app_icon_manager.cc",
     "app_icon_manager.h",
     "app_registrar.cc",
     "app_registrar.h",
diff --git a/chrome/browser/web_applications/components/app_icon_manager.cc b/chrome/browser/web_applications/components/app_icon_manager.cc
deleted file mode 100644
index 5e45b50..0000000
--- a/chrome/browser/web_applications/components/app_icon_manager.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/web_applications/components/app_icon_manager.h"
-
-namespace web_app {
-
-AppIconManager::AppIconManager() = default;
-
-AppIconManager::~AppIconManager() = default;
-
-}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/app_icon_manager.h b/chrome/browser/web_applications/components/app_icon_manager.h
index f2a0c0b..91d7790 100644
--- a/chrome/browser/web_applications/components/app_icon_manager.h
+++ b/chrome/browser/web_applications/components/app_icon_manager.h
@@ -20,8 +20,8 @@
 // Exclusively used from the UI thread.
 class AppIconManager {
  public:
-  AppIconManager();
-  virtual ~AppIconManager();
+  AppIconManager() = default;
+  virtual ~AppIconManager() = default;
 
   // Returns false if no downloaded icon with precise |icon_size_in_px|.
   virtual bool HasIcon(const AppId& app_id, int icon_size_in_px) const = 0;
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn
index bcebc31..e73d5757 100644
--- a/chrome/browser/web_applications/extensions/BUILD.gn
+++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -92,7 +92,6 @@
   deps = [
     ":extensions",
     "//base/test:test_support",
-    "//chrome/app/theme:chrome_unscaled_resources_grit",
     "//chrome/browser",
     "//chrome/browser/ui",
     "//chrome/browser/web_applications",
diff --git a/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.cc
index e3dbb7e8..4f965fa 100644
--- a/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
@@ -20,18 +19,13 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/test/test_system_web_app_manager.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/manifest_handlers/app_theme_color_info.h"
 #include "chrome/common/webui_url_constants.h"
-#include "chrome/grit/browser_resources.h"
-#include "chrome/grit/chrome_unscaled_resources.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_controller.h"
 #include "content/public/browser/web_ui_controller_factory.h"
-#include "content/public/browser/web_ui_data_source.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
@@ -42,100 +36,6 @@
 
 namespace web_app {
 
-namespace {
-
-constexpr char kSystemAppManifestText[] =
-    R"({
-      "name": "Test System App",
-      "display": "standalone",
-      "icons": [
-        {
-          "src": "icon-256.png",
-          "sizes": "256x256",
-          "type": "image/png"
-        }
-      ],
-      "start_url": "/pwa.html",
-      "theme_color": "#00FF00"
-    })";
-
-constexpr char kPwaHtml[] =
-    R"(
-<html>
-<head>
-  <link rel="manifest" href="manifest.json">
-</head>
-</html>
-)";
-
-// WebUIController that serves a System PWA.
-class TestWebUIController : public content::WebUIController {
- public:
-  explicit TestWebUIController(content::WebUI* web_ui)
-      : WebUIController(web_ui) {
-    content::WebUIDataSource* data_source =
-        content::WebUIDataSource::Create("test-system-app");
-    data_source->AddResourcePath("icon-256.png", IDR_PRODUCT_LOGO_256);
-    data_source->SetRequestFilter(
-        base::BindRepeating([](const std::string& path) {
-          return path == "manifest.json" || path == "pwa.html";
-        }),
-        base::BindRepeating(
-            [](const std::string& id,
-               content::WebUIDataSource::GotDataCallback callback) {
-              scoped_refptr<base::RefCountedString> ref_contents(
-                  new base::RefCountedString);
-              if (id == "manifest.json")
-                ref_contents->data() = kSystemAppManifestText;
-              else if (id == "pwa.html")
-                ref_contents->data() = kPwaHtml;
-              else
-                NOTREACHED();
-
-              std::move(callback).Run(ref_contents);
-            }));
-    content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                  data_source);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestWebUIController);
-};
-
-}  // namespace
-
-// WebUIControllerFactory that serves our TestWebUIController.
-class TestWebUIControllerFactory : public content::WebUIControllerFactory {
- public:
-  TestWebUIControllerFactory() {}
-
-  std::unique_ptr<content::WebUIController> CreateWebUIControllerForURL(
-      content::WebUI* web_ui,
-      const GURL& url) override {
-    return std::make_unique<TestWebUIController>(web_ui);
-  }
-
-  content::WebUI::TypeID GetWebUIType(content::BrowserContext* browser_context,
-                                      const GURL& url) override {
-    if (url.SchemeIs(content::kChromeUIScheme))
-      return reinterpret_cast<content::WebUI::TypeID>(1);
-
-    return content::WebUI::kNoWebUI;
-  }
-
-  bool UseWebUIForURL(content::BrowserContext* browser_context,
-                      const GURL& url) override {
-    return url.SchemeIs(content::kChromeUIScheme);
-  }
-  bool UseWebUIBindingsForURL(content::BrowserContext* browser_context,
-                              const GURL& url) override {
-    return url.SchemeIs(content::kChromeUIScheme);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestWebUIControllerFactory);
-};
-
 SystemWebAppManagerBrowserTest::SystemWebAppManagerBrowserTest(
     bool install_mock) {
   scoped_feature_list_.InitWithFeatures(
@@ -143,21 +43,12 @@
        blink::features::kFileHandlingAPI},
       {});
   if (install_mock) {
-    factory_ = std::make_unique<TestWebUIControllerFactory>();
-    test_web_app_provider_creator_ =
-        std::make_unique<TestWebAppProviderCreator>(base::BindOnce(
-            &SystemWebAppManagerBrowserTest::CreateWebAppProvider,
-            base::Unretained(this)));
-    content::WebUIControllerFactory::RegisterFactory(factory_.get());
+    maybe_installation_ =
+        TestSystemWebAppInstallation::SetUpStandaloneSingleWindowApp();
   }
 }
 
-SystemWebAppManagerBrowserTest::~SystemWebAppManagerBrowserTest() {
-  if (factory_) {
-    content::WebUIControllerFactory::UnregisterFactoryForTesting(
-        factory_.get());
-  }
-}
+SystemWebAppManagerBrowserTest::~SystemWebAppManagerBrowserTest() = default;
 
 // static
 const extensions::Extension*
@@ -171,38 +62,15 @@
   return WebAppProvider::Get(browser()->profile())->system_web_app_manager();
 }
 
-std::unique_ptr<KeyedService>
-SystemWebAppManagerBrowserTest::CreateWebAppProvider(Profile* profile) {
-  DCHECK(SystemWebAppManager::IsEnabled());
-
-  auto provider = std::make_unique<TestWebAppProvider>(profile);
-
-  // Override SystemWebAppManager with TestSystemWebAppManager:
-  DCHECK(!test_system_web_app_manager_);
-  auto test_system_web_app_manager =
-      std::make_unique<TestSystemWebAppManager>(profile);
-  test_system_web_app_manager_ = test_system_web_app_manager.get();
-  provider->SetSystemWebAppManager(std::move(test_system_web_app_manager));
-
-  base::flat_map<SystemAppType, SystemAppInfo> system_apps;
-  system_apps.emplace(
-      SystemAppType::SETTINGS,
-      SystemAppInfo("OSSettings",
-                    content::GetWebUIURL("test-system-app/pwa.html")));
-  test_system_web_app_manager_->SetSystemApps(std::move(system_apps));
-
-  // Start registry and all dependent subsystems:
-  provider->Start();
-
-  return provider;
+SystemAppType SystemWebAppManagerBrowserTest::GetMockAppType() {
+  DCHECK(maybe_installation_);
+  return maybe_installation_->GetType();
 }
 
 void SystemWebAppManagerBrowserTest::WaitForTestSystemAppInstall() {
   // Wait for the System Web Apps to install.
-  if (factory_) {
-    base::RunLoop run_loop;
-    GetManager().on_apps_synchronized().Post(FROM_HERE, run_loop.QuitClosure());
-    run_loop.Run();
+  if (maybe_installation_) {
+    maybe_installation_->WaitForAppInstall();
   } else {
     GetManager().InstallSystemAppsForTesting();
   }
@@ -258,7 +126,7 @@
 // Test that System Apps install correctly with a manifest.
 IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest, Install) {
   const extensions::Extension* app = GetExtensionForAppBrowser(
-      WaitForSystemAppInstallAndLaunch(SystemAppType::SETTINGS));
+      WaitForSystemAppInstallAndLaunch(GetMockAppType()));
   EXPECT_EQ("Test System App", app->name());
   EXPECT_EQ(SkColorSetRGB(0, 0xFF, 0),
             extensions::AppThemeColorInfo::GetThemeColor(app));
@@ -276,8 +144,7 @@
 // scheme but is shown off the chrome:// scheme.
 IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest,
                        ToolbarVisibilityForSystemWebApp) {
-  Browser* app_browser =
-      WaitForSystemAppInstallAndLaunch(SystemAppType::SETTINGS);
+  Browser* app_browser = WaitForSystemAppInstallAndLaunch(GetMockAppType());
   // In scope, the toolbar should not be visible.
   EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar());
 
@@ -305,7 +172,7 @@
 IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest,
                        LaunchFilesForSystemWebApp) {
   WaitForTestSystemAppInstall();
-  apps::AppLaunchParams params = LaunchParamsForApp(SystemAppType::SETTINGS);
+  apps::AppLaunchParams params = LaunchParamsForApp(GetMockAppType());
   params.source = apps::mojom::AppLaunchSource::kSourceChromeInternal;
 
   base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.h b/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.h
index 0e3f602..aa13a7d94 100644
--- a/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.h
+++ b/chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.h
@@ -9,6 +9,7 @@
 
 #include "base/macros.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
 #include "chrome/test/base/in_process_browser_test.h"
 
@@ -29,8 +30,6 @@
 
 namespace web_app {
 
-class TestSystemWebAppManager;
-class TestWebUIControllerFactory;
 enum class SystemAppType;
 
 class SystemWebAppManagerBrowserTest : public InProcessBrowserTest {
@@ -52,6 +51,9 @@
   // TestSystemWebAppManager if initialized with |install_mock| true.
   SystemWebAppManager& GetManager();
 
+  // Return SystemAppType of mocked app, only valid if |install_mock| is true.
+  SystemAppType GetMockAppType();
+
   void WaitForTestSystemAppInstall();
 
   // Wait for system apps to install, then launch one. Returns the browser that
@@ -69,9 +71,7 @@
   std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile);
 
   base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<TestWebUIControllerFactory> factory_;
-  std::unique_ptr<TestWebAppProviderCreator> test_web_app_provider_creator_;
-  TestSystemWebAppManager* test_system_web_app_manager_ = nullptr;
+  std::unique_ptr<TestSystemWebAppInstallation> maybe_installation_;
 
   DISALLOW_COPY_AND_ASSIGN(SystemWebAppManagerBrowserTest);
 };
diff --git a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
index 4acfcae..9aebe661 100644
--- a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
@@ -135,7 +135,7 @@
       SystemAppType::SETTINGS,
       SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
 
-  system_web_app_manager()->SetSystemApps(std::move(system_apps));
+  system_web_app_manager()->SetSystemAppsForTesting(std::move(system_apps));
   system_web_app_manager()->Start();
 
   base::RunLoop().RunUntilIdle();
@@ -158,7 +158,7 @@
       SystemAppType::DISCOVER,
       SystemAppInfo(kDiscoverAppNameForLogging, GURL(kAppUrl2)));
 
-  system_web_app_manager()->SetSystemApps(std::move(system_apps));
+  system_web_app_manager()->SetSystemAppsForTesting(std::move(system_apps));
   system_web_app_manager()->Start();
   base::RunLoop().RunUntilIdle();
 
@@ -181,7 +181,7 @@
       SystemAppType::SETTINGS,
       SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
 
-  system_web_app_manager()->SetSystemApps(std::move(system_apps));
+  system_web_app_manager()->SetSystemAppsForTesting(std::move(system_apps));
   system_web_app_manager()->Start();
 
   base::RunLoop().RunUntilIdle();
@@ -206,7 +206,7 @@
   system_apps.emplace(
       SystemAppType::SETTINGS,
       SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
 
   system_web_app_manager()->set_current_version(base::Version("1.0.0.0"));
   system_web_app_manager()->Start();
@@ -219,7 +219,7 @@
   system_apps.emplace(
       SystemAppType::DISCOVER,
       SystemAppInfo(kDiscoverAppNameForLogging, GURL(kAppUrl2)));
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
   system_web_app_manager()->Start();
 
   base::RunLoop().RunUntilIdle();
@@ -254,7 +254,7 @@
   system_apps.emplace(
       SystemAppType::SETTINGS,
       SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
 
   system_web_app_manager()->set_current_version(base::Version("1.0.0.0"));
   system_web_app_manager()->Start();
@@ -270,7 +270,7 @@
   system_apps.emplace(
       SystemAppType::DISCOVER,
       SystemAppInfo(kDiscoverAppNameForLogging, GURL(kAppUrl2)));
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
   system_web_app_manager()->Start();
   base::RunLoop().RunUntilIdle();
 
@@ -318,7 +318,7 @@
   // Changing the install URL of a system app propagates even without a version
   // change.
   system_apps.find(SystemAppType::SETTINGS)->second.install_url = kAppUrl3;
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
   system_web_app_manager()->Start();
   base::RunLoop().RunUntilIdle();
 
@@ -341,7 +341,7 @@
   system_apps.emplace(
       SystemAppType::SETTINGS,
       SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
-  system_web_app_manager()->SetSystemApps(system_apps);
+  system_web_app_manager()->SetSystemAppsForTesting(system_apps);
 
   // Simulate first execution.
   pending_app_manager()->SetInstallResultCode(
@@ -389,7 +389,7 @@
     system_apps.emplace(
         SystemAppType::SETTINGS,
         SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
-    system_web_app_manager()->SetSystemApps(system_apps);
+    system_web_app_manager()->SetSystemAppsForTesting(system_apps);
 
     histograms.ExpectTotalCount(
         SystemWebAppManager::kInstallResultHistogramName, 0);
@@ -424,7 +424,7 @@
         SystemAppType::DISCOVER,
         SystemAppInfo(kDiscoverAppNameForLogging, GURL(kAppUrl2)));
 
-    system_web_app_manager()->SetSystemApps(system_apps);
+    system_web_app_manager()->SetSystemAppsForTesting(system_apps);
     pending_app_manager()->SetInstallResultCode(
         InstallResultCode::kProfileDestroyed);
 
@@ -447,7 +447,7 @@
     system_apps.emplace(
         SystemAppType::SETTINGS,
         SystemAppInfo(kSettingsAppNameForLogging, GURL(kAppUrl1)));
-    system_web_app_manager()->SetSystemApps(system_apps);
+    system_web_app_manager()->SetSystemAppsForTesting(system_apps);
     pending_app_manager()->SetInstallResultCode(
         InstallResultCode::kProfileDestroyed);
 
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc
index fffa2644..d0c0c71 100644
--- a/chrome/browser/web_applications/system_web_app_manager.cc
+++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -36,6 +36,7 @@
 #include "chromeos/components/help_app_ui/url_constants.h"
 #include "chromeos/components/media_app_ui/url_constants.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "extensions/common/constants.h"
 #endif  // defined(OS_CHROMEOS)
 
 namespace web_app {
@@ -60,7 +61,7 @@
     infos.emplace(SystemAppType::CAMERA,
                   SystemAppInfo("Camera", GURL("chrome://camera/pwa.html")));
     infos.at(SystemAppType::CAMERA).uninstall_and_replace = {
-        ash::kInternalAppIdCamera};
+        extension_misc::kCameraAppId};
   }
 
   if (base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)) {
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h
index fb87077..2d53297 100644
--- a/chrome/browser/web_applications/system_web_app_manager.h
+++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -134,6 +134,8 @@
     return *on_apps_synchronized_;
   }
 
+  // This call will override default System Apps configuration. You should call
+  // Start() after this call to install |system_apps|.
   void SetSystemAppsForTesting(
       base::flat_map<SystemAppType, SystemAppInfo> system_apps);
 
diff --git a/chrome/browser/web_applications/test/test_system_web_app_installation.cc b/chrome/browser/web_applications/test/test_system_web_app_installation.cc
new file mode 100644
index 0000000..0626f37c1
--- /dev/null
+++ b/chrome/browser/web_applications/test/test_system_web_app_installation.cc
@@ -0,0 +1,113 @@
+// 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 <memory>
+#include <string>
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "content/public/common/url_constants.h"
+
+namespace web_app {
+
+namespace {
+
+// Assumes url is like "chrome://web-app/index.html". Returns "web-app";
+// This function is needed because at the time TestSystemWebInstallation is
+// initialized, chrome scheme is not yet registered with GURL, so it will be
+// parsed as PathURL, resulting in an empty host.
+std::string GetDataSourceNameFromSystemAppInstallUrl(const GURL& url) {
+  DCHECK(url.SchemeIs(content::kChromeUIScheme));
+
+  const std::string& spec = url.spec();
+  size_t p = strlen(content::kChromeUIScheme);
+
+  DCHECK_EQ("://", spec.substr(p, 3));
+  p += 3;
+
+  size_t pos_after_host = spec.find("/", p);
+  DCHECK(pos_after_host != std::string::npos);
+
+  return spec.substr(p, pos_after_host - p);
+}
+}  // namespace
+
+TestSystemWebAppInstallation::TestSystemWebAppInstallation(SystemAppType type,
+                                                           SystemAppInfo info)
+    : type_(type),
+      web_ui_controller_factory_(
+          GetDataSourceNameFromSystemAppInstallUrl(info.install_url)) {
+  test_web_app_provider_creator_ = std::make_unique<TestWebAppProviderCreator>(
+      base::BindOnce(&TestSystemWebAppInstallation::CreateWebAppProvider,
+                     // base::Unretained is safe here. This callback is called
+                     // at TestingProfile::Init, which is at test startup.
+                     // TestSystemWebAppInstallation is intended to have the
+                     // same lifecycle as the test, it won't be destroyed before
+                     // the test finishes.
+                     base::Unretained(this), info));
+  content::WebUIControllerFactory::RegisterFactory(&web_ui_controller_factory_);
+}
+
+TestSystemWebAppInstallation::~TestSystemWebAppInstallation() {
+  content::WebUIControllerFactory::UnregisterFactoryForTesting(
+      &web_ui_controller_factory_);
+}
+
+// static
+std::unique_ptr<TestSystemWebAppInstallation>
+TestSystemWebAppInstallation::SetUpTabbedMultiWindowApp() {
+  SystemAppInfo terminal_system_app_info(
+      "Terminal", GURL("chrome://test-system-app/pwa.html"));
+  terminal_system_app_info.single_window = false;
+  return base::WrapUnique(new TestSystemWebAppInstallation(
+      SystemAppType::TERMINAL, terminal_system_app_info));
+}
+
+// static
+std::unique_ptr<TestSystemWebAppInstallation>
+TestSystemWebAppInstallation::SetUpStandaloneSingleWindowApp() {
+  return base::WrapUnique(new TestSystemWebAppInstallation(
+      SystemAppType::SETTINGS,
+      SystemAppInfo("OSSettings", GURL("chrome://test-system-app/pwa.html"))));
+}
+
+std::unique_ptr<KeyedService>
+TestSystemWebAppInstallation::CreateWebAppProvider(SystemAppInfo info,
+                                                   Profile* profile) {
+  profile_ = profile;
+  auto provider = std::make_unique<TestWebAppProvider>(profile);
+  auto system_web_app_manager = std::make_unique<SystemWebAppManager>(profile);
+  system_web_app_manager->SetSystemAppsForTesting({{type_, info}});
+  provider->SetSystemWebAppManager(std::move(system_web_app_manager));
+  provider->Start();
+  return provider;
+}
+
+void TestSystemWebAppInstallation::WaitForAppInstall() {
+  base::RunLoop run_loop;
+  WebAppProvider::Get(profile_)
+      ->system_web_app_manager()
+      .on_apps_synchronized()
+      .Post(FROM_HERE, run_loop.QuitClosure());
+  run_loop.Run();
+}
+
+AppId TestSystemWebAppInstallation::GetAppId() {
+  return WebAppProvider::Get(profile_)
+      ->system_web_app_manager()
+      .GetAppIdForSystemApp(type_)
+      .value();
+}
+
+const GURL& TestSystemWebAppInstallation::GetAppUrl() {
+  return WebAppProvider::Get(profile_)->registrar().GetAppLaunchURL(GetAppId());
+}
+
+SystemAppType TestSystemWebAppInstallation::GetType() {
+  return type_;
+}
+
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/test/test_system_web_app_installation.h b/chrome/browser/web_applications/test/test_system_web_app_installation.h
new file mode 100644
index 0000000..1e998cb
--- /dev/null
+++ b/chrome/browser/web_applications/test/test_system_web_app_installation.h
@@ -0,0 +1,50 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_INSTALLATION_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_INSTALLATION_H_
+
+#include <memory>
+
+#include "chrome/browser/web_applications/system_web_app_manager.h"
+#include "chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h"
+#include "chrome/browser/web_applications/test/test_web_app_provider.h"
+#include "chrome/common/web_application_info.h"
+
+namespace web_app {
+
+// Class to setup the installation of a test System Web App.
+//
+// Use SetUp*() methods to create a instance of this class in test suite's
+// constructor, before the profile is fully created. In tests, call
+// WaitForAppInstall() to finish the installation.
+class TestSystemWebAppInstallation {
+ public:
+  static std::unique_ptr<TestSystemWebAppInstallation>
+  SetUpTabbedMultiWindowApp();
+  static std::unique_ptr<TestSystemWebAppInstallation>
+  SetUpStandaloneSingleWindowApp();
+
+  ~TestSystemWebAppInstallation();
+
+  void WaitForAppInstall();
+
+  AppId GetAppId();
+  const GURL& GetAppUrl();
+  SystemAppType GetType();
+
+ private:
+  TestSystemWebAppInstallation(SystemAppType type, SystemAppInfo info);
+
+  Profile* profile_;
+  std::unique_ptr<KeyedService> CreateWebAppProvider(SystemAppInfo info,
+                                                     Profile* profile);
+  std::unique_ptr<TestWebAppProviderCreator> test_web_app_provider_creator_;
+  SystemAppType type_;
+  TestSystemWebAppWebUIControllerFactory web_ui_controller_factory_;
+};
+
+}  // namespace web_app
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_INSTALLATION_H_
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.cc b/chrome/browser/web_applications/test/test_system_web_app_manager.cc
index 382eeb61..d53742f 100644
--- a/chrome/browser/web_applications/test/test_system_web_app_manager.cc
+++ b/chrome/browser/web_applications/test/test_system_web_app_manager.cc
@@ -11,16 +11,11 @@
 
 TestSystemWebAppManager::TestSystemWebAppManager(Profile* profile)
     : SystemWebAppManager(profile) {
-  SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo>());
+  SetSystemAppsForTesting(base::flat_map<SystemAppType, SystemAppInfo>());
 }
 
 TestSystemWebAppManager::~TestSystemWebAppManager() = default;
 
-void TestSystemWebAppManager::SetSystemApps(
-    base::flat_map<SystemAppType, SystemAppInfo> system_apps) {
-  SetSystemAppsForTesting(std::move(system_apps));
-}
-
 void TestSystemWebAppManager::SetUpdatePolicy(
     SystemWebAppManager::UpdatePolicy policy) {
   SetUpdatePolicyForTesting(policy);
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.h b/chrome/browser/web_applications/test/test_system_web_app_manager.h
index 323884e..1b72df2 100644
--- a/chrome/browser/web_applications/test/test_system_web_app_manager.h
+++ b/chrome/browser/web_applications/test/test_system_web_app_manager.h
@@ -22,8 +22,6 @@
   explicit TestSystemWebAppManager(Profile* profile);
   ~TestSystemWebAppManager() override;
 
-  void SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo> system_apps);
-
   void SetUpdatePolicy(SystemWebAppManager::UpdatePolicy policy);
 
   void set_current_version(const base::Version& version) {
diff --git a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc
new file mode 100644
index 0000000..1ecde514
--- /dev/null
+++ b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc
@@ -0,0 +1,104 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h"
+
+#include "base/memory/ref_counted_memory.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/browser_resources.h"
+#include "chrome/grit/chrome_unscaled_resources.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace {
+
+constexpr char kSystemAppManifestText[] =
+    R"({
+      "name": "Test System App",
+      "display": "standalone",
+      "icons": [
+        {
+          "src": "icon-256.png",
+          "sizes": "256x256",
+          "type": "image/png"
+        }
+      ],
+      "start_url": "/pwa.html",
+      "theme_color": "#00FF00"
+    })";
+
+constexpr char kPwaHtml[] =
+    R"(
+<html>
+<head>
+  <link rel="manifest" href="manifest.json">
+</head>
+</html>
+)";
+
+// WebUIController that serves a System PWA.
+class TestSystemWebAppWebUIController : public content::WebUIController {
+ public:
+  explicit TestSystemWebAppWebUIController(std::string source_name,
+                                           content::WebUI* web_ui)
+      : WebUIController(web_ui) {
+    content::WebUIDataSource* data_source =
+        content::WebUIDataSource::Create(source_name);
+    data_source->AddResourcePath("icon-256.png", IDR_PRODUCT_LOGO_256);
+    data_source->SetRequestFilter(
+        base::BindRepeating([](const std::string& path) {
+          return path == "manifest.json" || path == "pwa.html";
+        }),
+        base::BindRepeating(
+            [](const std::string& id,
+               content::WebUIDataSource::GotDataCallback callback) {
+              scoped_refptr<base::RefCountedString> ref_contents(
+                  new base::RefCountedString);
+              if (id == "manifest.json")
+                ref_contents->data() = kSystemAppManifestText;
+              else if (id == "pwa.html")
+                ref_contents->data() = kPwaHtml;
+              else
+                NOTREACHED();
+
+              std::move(callback).Run(ref_contents);
+            }));
+    content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
+                                  data_source);
+  }
+  TestSystemWebAppWebUIController(const TestSystemWebAppWebUIController&) =
+      delete;
+  TestSystemWebAppWebUIController& operator=(
+      const TestSystemWebAppWebUIController&) = delete;
+};
+
+}  // namespace
+
+std::unique_ptr<content::WebUIController>
+TestSystemWebAppWebUIControllerFactory::CreateWebUIControllerForURL(
+    content::WebUI* web_ui,
+    const GURL& url) {
+  return std::make_unique<TestSystemWebAppWebUIController>(source_name_,
+                                                           web_ui);
+}
+
+content::WebUI::TypeID TestSystemWebAppWebUIControllerFactory::GetWebUIType(
+    content::BrowserContext* browser_context,
+    const GURL& url) {
+  if (url.SchemeIs(content::kChromeUIScheme))
+    return reinterpret_cast<content::WebUI::TypeID>(1);
+
+  return content::WebUI::kNoWebUI;
+}
+
+bool TestSystemWebAppWebUIControllerFactory::UseWebUIForURL(
+    content::BrowserContext* browser_context,
+    const GURL& url) {
+  return url.SchemeIs(content::kChromeUIScheme);
+}
+
+bool TestSystemWebAppWebUIControllerFactory::UseWebUIBindingsForURL(
+    content::BrowserContext* browser_context,
+    const GURL& url) {
+  return url.SchemeIs(content::kChromeUIScheme);
+}
diff --git a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h
new file mode 100644
index 0000000..c2489c1
--- /dev/null
+++ b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_WEB_UI_CONTROLLER_FACTORY_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_WEB_UI_CONTROLLER_FACTORY_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_controller_factory.h"
+#include "content/public/test/test_utils.h"
+
+// WebUIControllerFactory that creates a TestWebUIController, which serves the
+// resources needed for a minimal System Web App (a page with a web manifest and
+// an icon).
+class TestSystemWebAppWebUIControllerFactory
+    : public content::WebUIControllerFactory {
+ public:
+  explicit TestSystemWebAppWebUIControllerFactory(const std::string source_name)
+      : source_name_(source_name) {}
+  TestSystemWebAppWebUIControllerFactory(
+      const TestSystemWebAppWebUIControllerFactory&) = delete;
+  TestSystemWebAppWebUIControllerFactory& operator=(
+      const TestSystemWebAppWebUIControllerFactory&) = delete;
+
+  // content::WebUIControllerFactory
+  std::unique_ptr<content::WebUIController> CreateWebUIControllerForURL(
+      content::WebUI* web_ui,
+      const GURL& url) override;
+
+  content::WebUI::TypeID GetWebUIType(content::BrowserContext* browser_context,
+                                      const GURL& url) override;
+
+  bool UseWebUIForURL(content::BrowserContext* browser_context,
+                      const GURL& url) override;
+  bool UseWebUIBindingsForURL(content::BrowserContext* browser_context,
+                              const GURL& url) override;
+
+ private:
+  std::string source_name_;
+};
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_SYSTEM_WEB_APP_WEB_UI_CONTROLLER_FACTORY_H_
diff --git a/chrome/chrome_cleaner/README.md b/chrome/chrome_cleaner/README.md
index 5d3b1844..6e16a5c 100644
--- a/chrome/chrome_cleaner/README.md
+++ b/chrome/chrome_cleaner/README.md
@@ -38,11 +38,20 @@
 
 ## Targets
 
-The main build targets for this application are:
+To build all targets for this project, use:
 
-*   //chrome/chrome_cleaner:software_reporter_tool
-*   //chrome/chrome_cleaner:chrome_cleanup_tool
-*   //chrome/chrome_cleaner:chrome_cleaner_unittests
+//chrome/chrome_cleaner:chrome_cleaner
+
+The main build targets are:
+
+ *   //chrome/chrome_cleaner:software_reporter_tool
+ *   //chrome/chrome_cleaner:chrome_cleanup_tool
+ *   //chrome/chrome_cleaner:chrome_cleaner_unittests
+
+There is also a tool, `generate_test_uws`, which will create some harmless text
+files that the tool will detect as UwS:
+
+*   //chrome/chrome_cleaner/tools:generate_test_uws
 
 ## Internal resources
 
diff --git a/chrome/chrome_cleaner/docs/security.md b/chrome/chrome_cleaner/docs/security.md
new file mode 100644
index 0000000..d124d3b
--- /dev/null
+++ b/chrome/chrome_cleaner/docs/security.md
@@ -0,0 +1,213 @@
+# Chrome Cleaner Security Model
+
+[TOC]
+
+## Security Model
+
+The purpose of the Chrome Cleanup Tool and Software Reporter Tool is to scan
+files that are found on users' machines for the presence of Unwanted Software
+(UwS) that could effect chrome. These files are untrusted inputs so, according
+to the [Rule of
+2](https://chromium.googlesource.com/chromium/src/+/master/docs/security/rule-of-2.md)
+all code that parses them must run in a sandbox.
+
+Sandboxes are implemented using the [chromium sandbox
+library.](https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md)
+
+*** note
+**TL;DR:** each sandbox runs in a separate process with severely reduced
+privileges, called a "sandbox target" process. The main process has higher
+privileges and is called the "broker" process.
+***
+
+The tool has separate sandboxes for each type of parsing that's done on
+untrusted files:
+
+*  [Engine
+   Sandbox](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/engines/):
+   The main scanning engine that detects UwS runs entirely in this sandbox.
+*  [Parser Sandbox](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/parsers/):
+   Parses various file formats such as JSON (mainly for Chrome extension settings) and Windows LNK files.
+*  [Zip Archiver
+   Sandbox](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/zip_archiver/):
+   Compresses files into a .zip archive. Used when quarantining detected UwS
+   files.
+
+## Sandbox Infrastructure
+
+The code for each sandbox is split into two subdirectories, `broker` and
+`target`, for easier auditing.
+
+*  `broker` contains code that runs in the broker process.
+   *  This code has all the privileges of the user running the app.
+   *  Code can tell that it's running in the broker process because
+      [SandboxFactory::GetBrokerServices](https://source.chromium.org/chromium/chromium/src/+/master:sandbox/win/src/sandbox_factory.h)
+      will return non-null.
+*  `target` contains code that runs in the target process.
+   *  This process is considered untrusted because malicious files could gain
+      control of it by exploiting bugs in the parser.
+   * This code has highly restricted privileges, including:
+     *  Cannot access any files or registry keys that aren't explicitly shared
+        by the broker process.
+     *  Cannot access the network to exfiltrate data.
+   *  Code can tell that it's running in the broker process because
+      [SandboxFactory::GetTargetServices](https://source.chromium.org/chromium/chromium/src/+/master:sandbox/win/src/sandbox_factory.h)
+      will return non-null.
+
+The target process communicates with the broker process using
+[Mojo](https://chromium.googlesource.com/chromium/src/+/master/mojo/README.md).
+
+*  Mojo interfaces are found in the
+   [mojom](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/mojom)
+   directory.
+*  A Mojo interface is a security boundary since it allows the untrusted target
+   process to communicate with the broker process. This means:
+   *  The interface should follow the Chromium security [Mojo Style
+      Guide](https://chromium.googlesource.com/chromium/src/+/master/docs/security/mojo.md).
+      Note that the style guide calls the "broker" process the "browser"
+      process.
+   *  All changes to the interface must be reviewed by an IPC security
+      reviewer. This is enforced by the [OWNERS
+      file](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/mojom/OWNERS).
+
+### Spawning a sandbox (broker process)
+
+The main entry point to create a sandbox is `SpawnSandbox` in
+[ipc/sandbox.cc](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/sandbox.cc).
+Call this with a `SandboxSetupHooks` subclass.
+
+*  Override methods of `SandboxSetupHooks` to provide custom behaviour for each
+   sandbox type, such as instantiating an IPC channel or adding custom flags to
+   the sandbox command-line.
+*  Each `SandboxSetupHooks` subclass is paired with a `SandboxTargetHooks`
+   subclass that knows how to deal with the custom behaviour, eg. connect to
+   the IPC channel.
+*  The `MojoSandboxSetupHooks` and `MojoSandboxTargetHooks` subclasses contain
+   common code to set up a Mojo IPC connection. Override them to provide
+   details of the Mojo interface to use with the connection. See below for more
+   details.
+
+`SpawnSandbox` will:
+
+1.  Fill in a default sandbox policy, the most restrictive possible.
+1.  Add `--sandboxed-process-id=<sandbox type>` to the command-line that will
+    be used for the target process.
+1.  Call `hooks->UpdateSandboxPolicy`. You can override this to alter the
+    policy and command-line.
+1.  Spawn another copy of the **current process** to be the target process.
+    *  The sandbox library's magic will cause the new process to be sandboxed
+       (`GetTargetServices` returns non-null).
+    *  The target process will start off suspended.
+1.  Call `hooks->TargetSpawned` with handles to the new process and to its main thread.
+1.  Resume the target process's main thread. It's now running.
+1.  Call `hooks->TargetResumed`.
+
+If any step fails the function calls `hooks->SetupFailed`.
+
+#### Mojo
+
+You will probably want to set up a Mojo IPC channel to your target process. To do this:
+
+1.  Subclass
+    [MojoSandboxSetupHooks](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/mojo_sandbox_hooks.h)
+    instead of `SandboxSetupHooks`.
+    *  [ZipArchiverSandboxSetupHooks](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/zip_archiver/broker/sandbox_setup.h)
+       is a good example.
+1.  The hooks class should own a `mojo::Remote<SomeMojoInterface>`. This acts
+    like a pointer-to-SomeMojoInterface. Methods called through this "pointer"
+    will be marshalled over Mojo IPC to the target process, where
+    SomeMojoInterface is implemented.
+    *  For the Zip Archiver, this is a `mojo::Remote<mojom::ZipArchiver>`
+       defined in
+       [zip_archiver.mojom](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/mojom/zip_archiver.mojom).
+1.  Override `UpdateSandboxPolicy` to:
+    1.  Call `MojoSandboxSetupHooks::SetupSandboxMessagePipe`, which returns a
+        handle to the Mojo pipe.
+    1.  Create a `mojo::PendingRemote<SomeMojoInterface>` that wraps the pipe
+        handle.
+    1.  Pass the `PendingRemote` to `mojo::Remote<SomeMojoInterface>::Bind`.
+        Now the remote is bound to the Mojo pipe.
+1.  You will want a method to take ownership of the remote so that it can be
+    saved after the sandbox starts, and passed to whatever code needs to call
+    methods on it.
+    *  For the Zip Archiver, this is
+       `ZipArchiverSandboxSetupHooks::TakeZipArchiverRemote`.
+
+*** note
+**Note:** All methods on a `mojo::Remote`, including the destructor, need to be
+called from the same sequence. For legacy reasons chrome_cleaner uses an object
+called
+[MojoTaskRunner](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/mojo_task_runner.h)
+for all remotes.
+
+The easy way to ensure that all methods are called on the same sequence would
+be to use
+[SequenceBound](https://source.chromium.org/chromium/chromium/src/+/master:base/threading/sequence_bound.h)
+but this code predates it, so instead there are lots of explicit calls to
+`PostTask` and `OnTaskRunnerDeleter`.
+***
+
+### Running a sandbox (target process)
+
+Near the start of main, the app checks if `GetTargetServices` returns non-null.
+If so, it's running in the sandbox. (The "Resume the target process's main
+thread" step of `SpawnSandbox` has just finished.) At this point the sandboxed
+process still has many privileges.
+
+The app then:
+
+1.  Checks the `--sandboxed-process-id` command-line switch to see which type
+    of sandbox to start.
+1.  Instantiates an override of
+    [SandboxTargetHooks](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/sandbox.h)
+    based on the sandbox type.
+1.  Calls `RunSandboxTarget` in
+    [ipc/sandbox.cc](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/sandbox.cc),
+    which will:
+    1.  Initialize the sandbox `TargetService`.
+    1.  Call `hooks->TargetStartedWithHighPrivileges`. Override this to do any setup that needs privileges,
+        ***note
+        **Important:** The sandbox must not handle any **untrusted** data at this step.
+        ***
+    1.  Call `TargetService::LowerToken` to drop the remaining privileges.
+    1.  Call `hooks->TargetDroppedPrivileges`. Override this to do the main processing for the sandbox.
+
+When `RunSandboxTarget` returns, the sandboxed process exits.
+
+*** promo
+Most sandboxs enter an endless loop in `hooks->TargetDroppedPrivileges`,
+servicing requests sent over IPC from the broker process. The broker will kill
+all target processes when it exits.
+***
+
+#### Mojo
+
+To connect to a Mojo IPC channel in the target:
+
+1.  Subclass
+    [MojoSandboxTargetHooks](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/ipc/mojo_sandbox_hooks.h)
+    instead of `SandboxTargetHooks`.
+    *  This is paired with a `MojoSandboxSetupHooks` that creates a `mojo::Remote<SomeMojoInterface>`.
+    *  [ZipArchiverSandboxTargetHooks](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/zip_archiver/target/sandbox_setup.cc)
+       is a good example.
+1.  Implement the methods of `SomeMojoInterface`. Traditionally this is done in
+    a class called `SomeMojoInterfaceImpl`.
+    *  The implementation should own a `mojo::Receiver<SomeMojoInterface>`.
+    *  eg. `mojom::ZipArchiver` is implemented in
+       [ZipArchiverImpl](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_cleaner/zip_archiver/target/zip_archiver_impl.h),
+       and it owns a `mojo::Receiver<mojom::ZipArchier>`.
+    *  Note this is in the `target` subdir to enforce that the implementation
+       is only used in the target process.
+1.  Override `TargetDroppedPrivileges` to:
+    1.  Call `MojoSandboxTargetHooks::ExtractSandboxMessagePipe`, which returns
+        a handle to the Mojo pipe that was created in
+        `MojoSandboxSetupHooks::UpdateSandboxPolicy`.
+    1.  Create a `mojo::PendingReceiver<SomeMojoInterface>` that wraps the pipe
+        handle.
+    1.  Instantiate `SomeMojoInterfaceImpl`, assigning the `PendingReceiver` to the `Receiver`.
+        *  This binds the `SomeMojoInterfaceImpl` to the IPC pipe, so all calls
+           to methods on the `mojo::Remote<SomeMojoInterface>` in the broker
+           process are marshalled across the pipe and invoke the corresponding
+           method on the `SomeMojoInterfaceImpl`.
+    1.  Call `RunLoop::Run` to loop until the process is killed. Mojo will do the rest.
+
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 6469473..0e0d5831 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -177,6 +177,13 @@
         "//third_party/ink:ink_resources",
         "//ui/file_manager:resources",
       ]
+
+      if (!is_official_build) {
+        sources += [
+          "$root_gen_dir/chromeos/chromeos_sample_system_web_app_resources.pak",
+        ]
+        deps += [ "//chromeos/resources:sample_system_web_app_resources" ]
+      }
     }
     if (!is_android && !is_chromeos) {
       sources += [ "$root_gen_dir/chrome/welcome_resources.pak" ]
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 59d42241..347cee8 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -214,9 +214,6 @@
 const char kDisableExtensionsFileAccessCheck[] =
     "disable-extensions-file-access-check";
 
-// Disable pop-up blocking.
-const char kDisablePopupBlocking[]          = "disable-popup-blocking";
-
 // Disables print preview (For testing, and for users who don't like us. :[ )
 const char kDisablePrintPreview[]           = "disable-print-preview";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index bab9c5e..493012a 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -75,7 +75,6 @@
 extern const char kDisableExtensions[];
 extern const char kDisableExtensionsExcept[];
 extern const char kDisableExtensionsFileAccessCheck[];
-extern const char kDisablePopupBlocking[];
 extern const char kDisablePrintPreview[];
 extern const char kDisablePromptOnRepost[];
 extern const char kDisableSearchGeolocationDisclosure[];
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 74964ce..72633ec 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -82,8 +82,6 @@
     kGoogleSpeechSynthesisExtensionId,
     kWallpaperManagerId,
     kZipArchiverExtensionId,
-    kChromeCameraAppId,
-    kChromeCameraAppDevId,
 #endif        // defined(OS_CHROMEOS)
     nullptr,  // Null-terminated array.
 };
@@ -117,10 +115,7 @@
 const char kWallpaperManagerId[] = "obklkkbkpaoaejdabbfldmcfplpdgolj";
 const char kZipArchiverExtensionId[] = "dmboannefpncccogfdikhmhpmdnddgoe";
 const char kZipArchiverExtensionPath[] = "chromeos/zip_archiver";
-const char kChromeCameraAppId[] = "hfhhnacclhffhdffklopdkcgdhifgngh";
-const char kChromeCameraAppDevId[] = "flgnmkgjffmkephdokeeliiopbjaafpm";
-const char kChromeCameraAppPath[] = "chromeos/camera";
-
+const char kCameraAppPath[] = "chromeos/camera";
 #endif  // defined(CHROME_OS)
 
 const char kAppStateNotInstalled[] = "not_installed";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 32220cd..151327b 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -237,12 +237,8 @@
 extern const char kZipArchiverExtensionId[];
 // Path to preinstalled zip archiver extension.
 extern const char kZipArchiverExtensionPath[];
-// The app ID of Chrome camera app.
-extern const char kChromeCameraAppId[];
-// The dev app ID of Chrome camera app.
-extern const char kChromeCameraAppDevId[];
 // Path to preinstalled Chrome camera app.
-extern const char kChromeCameraAppPath[];
+extern const char kCameraAppPath[];
 #endif
 
 // What causes an extension to be installed? Used in histograms, so don't
diff --git a/chrome/common/prerender.mojom b/chrome/common/prerender.mojom
index 7d97602..a85ea0ad 100644
--- a/chrome/common/prerender.mojom
+++ b/chrome/common/prerender.mojom
@@ -7,11 +7,6 @@
 import "url/mojom/url.mojom";
 
 interface PrerenderCanceler {
-  // Message sent from the renderer to the browser to notify it of a
-  // window.print() call which should cancel the prerender. The message is sent
-  // only when the renderer is prerendering.
-  CancelPrerenderForPrinting();
-
   // Cancels prerendering because of an unsupported method.
   CancelPrerenderForUnsupportedMethod();
 
diff --git a/chrome/credential_provider/gaiacp/strings/gaia_resources_eu.xtb b/chrome/credential_provider/gaiacp/strings/gaia_resources_eu.xtb
index ad9a9fc..955f5481 100644
--- a/chrome/credential_provider/gaiacp/strings/gaia_resources_eu.xtb
+++ b/chrome/credential_provider/gaiacp/strings/gaia_resources_eu.xtb
@@ -25,6 +25,7 @@
 <translation id="7209941495304122410">Idatzi Windows pasahitza</translation>
 <translation id="7357241217513796177">Ziurtatu sarera konektatuta zaudela eta saiatu berriro.</translation>
 <translation id="7536769223115622137">Gehitu laneko kontua</translation>
+<translation id="7811865856574012727">Gailuan saioa hasteko aukera domeinu hauetara mugatu du administratzaileak: <ph name="EMAIL_DOMAINS" />. Erabili baliozko laneko kontu bat.</translation>
 <translation id="7856245195110636219">Ezin da egin aurrera, uneko Windows pasahitza idatzi ezean. Jarri sistemaren administratzailearekin harremanetan.</translation>
 <translation id="8639729688781680518">Ahaztu Windows pasahitza</translation>
 <translation id="866458870819756755">Ezin izan da sortu erabiltzailea.</translation>
diff --git a/chrome/credential_provider/gaiacp/strings/gaia_resources_fr.xtb b/chrome/credential_provider/gaiacp/strings/gaia_resources_fr.xtb
index b1d3d308..9c9c4eca 100644
--- a/chrome/credential_provider/gaiacp/strings/gaia_resources_fr.xtb
+++ b/chrome/credential_provider/gaiacp/strings/gaia_resources_fr.xtb
@@ -25,7 +25,7 @@
 <translation id="7209941495304122410">Saisissez votre mot de passe Windows</translation>
 <translation id="7357241217513796177">Vérifiez que vous disposez bien d'une connexion réseau, puis réessayez.</translation>
 <translation id="7536769223115622137">Ajouter un compte professionnel</translation>
-<translation id="7811865856574012727">Votre administrateur n'a autorisé la connexion à l'appareil qu'avec les domaines suivants : <ph name="EMAIL_DOMAINS" />. Réessayez à l'aide d'un compte professionnel valide.</translation>
+<translation id="7811865856574012727">Votre administrateur n'a autorisé votre appareil à se connecter qu'aux domaines suivants : <ph name="EMAIL_DOMAINS" />. Réessayez à l'aide d'un compte professionnel valide.</translation>
 <translation id="7856245195110636219">Impossible de continuer sans saisir le mot de passe Windows actuel. Veuillez contacter un administrateur système.</translation>
 <translation id="8639729688781680518">Vous avez oublié votre mot de passe Windows ?</translation>
 <translation id="866458870819756755">Impossible de créer le compte utilisateur.</translation>
diff --git a/chrome/credential_provider/gaiacp/strings/gaia_resources_km.xtb b/chrome/credential_provider/gaiacp/strings/gaia_resources_km.xtb
index acb996ba..6972dc0 100644
--- a/chrome/credential_provider/gaiacp/strings/gaia_resources_km.xtb
+++ b/chrome/credential_provider/gaiacp/strings/gaia_resources_km.xtb
@@ -25,6 +25,7 @@
 <translation id="7209941495304122410">បញ្ចូល​ពាក្យសម្ងាត់ Windows</translation>
 <translation id="7357241217513796177">សូមប្រាកដថា អ្នកមានការ​តភ្ជាប់បណ្តាញ រួចព្យាយាម​ម្តងទៀត។</translation>
 <translation id="7536769223115622137">បញ្ចូល​គណនីការងារ</translation>
+<translation id="7811865856574012727">អ្នកគ្រប់គ្រង​របស់អ្នក​បានដាក់​កំហិត​លើ​ការចូល​គណនី​នៅលើ​ឧបករណ៍​ចំពោះ​ដែន​ដូចជា៖ <ph name="EMAIL_DOMAINS" />​។ សូម​ព្យាយាម​ម្ដងទៀត ដោយប្រើ​គណនី​ការងារ​ដែល​ត្រឹមត្រូវ​។</translation>
 <translation id="7856245195110636219">មិនអាចបន្ត​ដោយមិន​បញ្ចូល​ពាក្យសម្ងាត់ Windows បច្ចុប្បន្នបានទេ។ សូមទាក់ទង​អ្នកគ្រប់គ្រង​ប្រព័ន្ធ។</translation>
 <translation id="8639729688781680518">ភ្លេចពាក្យសម្ងាត់ Windows</translation>
 <translation id="866458870819756755">មិន​អាច​បង្កើត​អ្នក​ប្រើប្រាស់បាន​ទេ។</translation>
diff --git a/chrome/installer/linux/debian/update_dist_package_versions.py b/chrome/installer/linux/debian/update_dist_package_versions.py
index c8cd87c..5ee9cb68 100755
--- a/chrome/installer/linux/debian/update_dist_package_versions.py
+++ b/chrome/installer/linux/debian/update_dist_package_versions.py
@@ -153,6 +153,16 @@
             package_versions[package] = version
   distro_package_versions[distro] = package_versions
 
+missing_any_package = False
+for distro in distro_package_versions:
+  missing_packages = PACKAGE_FILTER.difference(distro_package_versions[distro])
+  if missing_packages:
+    missing_any_package = True
+    print >> sys.stderr, "Packages are not avilable on %s: %s" % (
+        distro, ', '.join(missing_packages))
+if missing_any_package:
+  sys.exit(1)
+
 with open(os.path.join(SCRIPT_DIR, 'dist_package_versions.json'), 'w') as f:
   f.write(json.dumps(distro_package_versions, sort_keys=True, indent=4,
                      separators=(',', ': ')))
diff --git a/chrome/installer/linux/rpm/update_package_provides.py b/chrome/installer/linux/rpm/update_package_provides.py
index ade8563..615292c 100755
--- a/chrome/installer/linux/rpm/update_package_provides.py
+++ b/chrome/installer/linux/rpm/update_package_provides.py
@@ -9,10 +9,11 @@
 import hashlib
 import json
 import os
+import sys
 import urllib2
 import xml.etree.ElementTree
 
-PACKAGE_FILTER = [
+LIBRARY_FILTER = set([
     "ld-linux-x86-64.so",
     "libX11-xcb.so",
     "libX11.so",
@@ -61,7 +62,7 @@
     "libxcb.so",
     "libxcb-dri3.so.0",
     "rtld(GNU_HASH)",
-]
+])
 
 SUPPORTED_FEDORA_RELEASES = ['30', '31']
 SUPPORTED_OPENSUSE_LEAP_RELEASES = ['15.1', '15.2']
@@ -79,16 +80,18 @@
       "https://download.fedoraproject.org/pub/fedora/linux/updates/%s/Everything/x86_64/" % version,
   ]
 for version in SUPPORTED_OPENSUSE_LEAP_RELEASES:
-    rpm_sources['openSUSE Leap ' + version] = [
-        "https://download.opensuse.org/distribution/leap/%s/repo/oss/" % version,
-        # 'update' must appear after 'distribution' since its entries
-        # overwrite the originals.
-        "https://download.opensuse.org/update/leap/%s/oss/" % version,
+  rpm_sources['openSUSE Leap ' + version] = [
+      "https://download.opensuse.org/distribution/leap/%s/repo/oss/" % version,
+      # 'update' must appear after 'distribution' since its entries
+      # overwrite the originals.
+      "https://download.opensuse.org/update/leap/%s/oss/" % version,
   ]
 
 provides = {}
+missing_any_library = False
 for distro in rpm_sources:
   distro_provides = {}
+  provided_prefixes = set()
   for source in rpm_sources[distro]:
     # |source| may redirect to a real download mirror.  However, these
     # mirrors may be out-of-sync with each other.  Follow the redirect
@@ -124,14 +127,23 @@
       for entry in package.findall('./{%s}format/{%s}provides/{%s}entry' %
                                    (COMMON_NS, RPM_NS, RPM_NS)):
         name = entry.attrib['name']
-        for prefix in PACKAGE_FILTER:
+        for prefix in LIBRARY_FILTER:
           if name.startswith(prefix):
             package_provides.append(name)
+            provided_prefixes.add(prefix)
       distro_provides[package_name] = package_provides
   provides[distro] = sorted(list(set(
       [package_provides for package in distro_provides
        for package_provides in distro_provides[package]])))
 
+  missing_libraries = LIBRARY_FILTER.difference(provided_prefixes)
+  if missing_libraries:
+    missing_any_library = True
+    print >> sys.stderr, "Libraries are not avilable on %s: %s" % (
+        distro, ', '.join(missing_libraries))
+
+if missing_any_library:
+  sys.exit(1)
 
 script_dir = os.path.dirname(os.path.realpath(__file__))
 with open(os.path.join(script_dir, 'dist_package_provides.json'), 'w') as f:
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 06218f7..dd4e530 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -1890,8 +1890,8 @@
       // Append a shortened version of this component. Cut in the middle to try
       // to avoid losing the unique parts of this component (which are usually
       // at the beginning or end for things like usernames and paths).
-      app_id.append(component.c_str(), 0, max_component_length / 2);
-      app_id.append(component.c_str(),
+      app_id.append(component, 0, max_component_length / 2);
+      app_id.append(component,
                     component.length() - ((max_component_length + 1) / 2),
                     base::string16::npos);
     } else {
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc
index 268ffcd..70f368b 100644
--- a/chrome/installer/util/shell_util_unittest.cc
+++ b/chrome/installer/util/shell_util_unittest.cc
@@ -967,6 +967,19 @@
             ShellUtil::BuildAppModelId(components));
 }
 
+TEST(ShellUtilTest, BuildAppModelIdNullTerminatorInTheMiddle) {
+  std::vector<base::string16> components;
+  base::string16 appname_with_nullTerminator(
+      L"I_have_null_terminator_in_middle");
+  appname_with_nullTerminator[5] = '\0';
+  components.push_back(appname_with_nullTerminator);
+  components.push_back(L"Default");
+  components.push_back(L"Test");
+  base::string16 expected_string(L"I_have_nul_in_middle.Default.Test");
+  expected_string[5] = '\0';
+  ASSERT_EQ(expected_string, ShellUtil::BuildAppModelId(components));
+}
+
 TEST(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) {
   std::vector<base::string16> components;
   const base::string16 long_appname(
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc
index 0feaef8..5abbaaa 100644
--- a/chrome/renderer/net/net_error_helper.cc
+++ b/chrome/renderer/net/net_error_helper.cc
@@ -278,6 +278,7 @@
   resource_request->method = "POST";
   resource_request->fetch_request_context_type =
       static_cast<int>(blink::mojom::RequestContextType::INTERNAL);
+  resource_request->destination = network::mojom::RequestDestination::kEmpty;
   resource_request->resource_type =
       static_cast<int>(content::ResourceType::kSubResource);
 
diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.cc b/chrome/renderer/plugins/chrome_plugin_placeholder.cc
index b86b8838..5e49b66 100644
--- a/chrome/renderer/plugins/chrome_plugin_placeholder.cc
+++ b/chrome/renderer/plugins/chrome_plugin_placeholder.cc
@@ -322,7 +322,8 @@
   hide_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_HIDE);
   params.custom_items.push_back(hide_item);
 
-  blink::WebPoint point(event.PositionInWidget().x, event.PositionInWidget().y);
+  blink::WebPoint point(event.PositionInWidget().x(),
+                        event.PositionInWidget().y());
   if (plugin() && plugin()->Container())
     point = plugin()->Container()->LocalToRootFramePoint(point);
 
diff --git a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
index 0a58483..9f2ba70c 100644
--- a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
+++ b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
@@ -9,9 +9,7 @@
 #include "base/command_line.h"
 #include "base/strings/string_util.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/prerender.mojom.h"
 #include "chrome/common/url_constants.h"
-#include "chrome/renderer/prerender/prerender_helper.h"
 #include "content/public/renderer/render_frame.h"
 #include "extensions/buildflags/buildflags.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -32,18 +30,6 @@
 ChromePrintRenderFrameHelperDelegate::~ChromePrintRenderFrameHelperDelegate() =
     default;
 
-bool ChromePrintRenderFrameHelperDelegate::CancelPrerender(
-    content::RenderFrame* render_frame) {
-  if (!prerender::PrerenderHelper::IsPrerendering(render_frame))
-    return false;
-
-  mojo::Remote<chrome::mojom::PrerenderCanceler> canceler;
-  render_frame->GetBrowserInterfaceBroker()->GetInterface(
-      canceler.BindNewPipeAndPassReceiver());
-  canceler->CancelPrerenderForPrinting();
-  return true;
-}
-
 // Return the PDF object element if |frame| is the out of process PDF extension.
 blink::WebElement ChromePrintRenderFrameHelperDelegate::GetPdfElement(
     blink::WebLocalFrame* frame) {
diff --git a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h
index 581d9f5..fa370be 100644
--- a/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h
+++ b/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h
@@ -16,7 +16,6 @@
 
  private:
   // printing::PrintRenderFrameHelper::Delegate:
-  bool CancelPrerender(content::RenderFrame* render_frame) override;
   blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override;
   bool IsPrintPreviewEnabled() override;
   bool OverridePrint(blink::WebLocalFrame* frame) override;
diff --git a/chrome/services/app_service/DEPS b/chrome/services/app_service/DEPS
index 44eda79..c8e261d 100644
--- a/chrome/services/app_service/DEPS
+++ b/chrome/services/app_service/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+components/prefs",
   "+components/services/app_service/public/cpp",
+  "+content/public",
 ]
diff --git a/chrome/services/app_service/public/cpp/BUILD.gn b/chrome/services/app_service/public/cpp/BUILD.gn
index 1a7a6e5..2f26d2c5 100644
--- a/chrome/services/app_service/public/cpp/BUILD.gn
+++ b/chrome/services/app_service/public/cpp/BUILD.gn
@@ -26,6 +26,7 @@
       "instance_update.h",
     ]
     deps = [
+      "//content/public/browser",
       "//skia",
       "//ui/aura",
       "//ui/compositor",
@@ -106,6 +107,7 @@
   deps = [
     ":app_update",
     ":icon_loader",
+    "//content/test:test_support",
     "//testing/gtest",
   ]
 
diff --git a/chrome/services/app_service/public/cpp/instance.cc b/chrome/services/app_service/public/cpp/instance.cc
index bb5f60ea..e307705 100644
--- a/chrome/services/app_service/public/cpp/instance.cc
+++ b/chrome/services/app_service/public/cpp/instance.cc
@@ -19,6 +19,7 @@
   auto instance = std::make_unique<Instance>(this->AppId(), this->Window());
   instance->SetLaunchId(this->LaunchId());
   instance->UpdateState(this->State(), this->LastUpdatedTime());
+  instance->SetBrowserContext(this->BrowserContext());
   return instance;
 }
 
@@ -28,4 +29,8 @@
   last_updated_time_ = last_updated_time;
 }
 
+void Instance::SetBrowserContext(content::BrowserContext* browser_context) {
+  browser_context_ = browser_context;
+}
+
 }  // namespace apps
diff --git a/chrome/services/app_service/public/cpp/instance.h b/chrome/services/app_service/public/cpp/instance.h
index 0438dd9..0228dd43 100644
--- a/chrome/services/app_service/public/cpp/instance.h
+++ b/chrome/services/app_service/public/cpp/instance.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/time/time.h"
+#include "content/public/browser/browser_context.h"
 #include "ui/aura/window.h"
 
 namespace apps {
@@ -35,12 +36,14 @@
 
   void SetLaunchId(const std::string& launch_id) { launch_id_ = launch_id; }
   void UpdateState(InstanceState state, const base::Time& last_updated_time);
+  void SetBrowserContext(content::BrowserContext* browser_context);
 
   const std::string& AppId() const { return app_id_; }
   aura::Window* Window() const { return window_; }
   const std::string& LaunchId() const { return launch_id_; }
   InstanceState State() const { return state_; }
   const base::Time& LastUpdatedTime() const { return last_updated_time_; }
+  content::BrowserContext* BrowserContext() const { return browser_context_; }
 
  private:
   std::string app_id_;
@@ -53,6 +56,7 @@
   std::string launch_id_;
   InstanceState state_;
   base::Time last_updated_time_;
+  content::BrowserContext* browser_context_ = nullptr;
 };
 
 }  // namespace apps
diff --git a/chrome/services/app_service/public/cpp/instance_registry_unittest.cc b/chrome/services/app_service/public/cpp/instance_registry_unittest.cc
index c700939..7329258 100644
--- a/chrome/services/app_service/public/cpp/instance_registry_unittest.cc
+++ b/chrome/services/app_service/public/cpp/instance_registry_unittest.cc
@@ -146,6 +146,7 @@
     EXPECT_EQ(outer.LaunchId(), inner.LaunchId());
     EXPECT_EQ(outer.State(), inner.State());
     EXPECT_EQ(outer.LastUpdatedTime(), inner.LastUpdatedTime());
+    EXPECT_EQ(outer.BrowserContext(), inner.BrowserContext());
   }
 
   apps::InstanceRegistry* instance_registry_;
diff --git a/chrome/services/app_service/public/cpp/instance_update.cc b/chrome/services/app_service/public/cpp/instance_update.cc
index 1b6a147..29f9491 100644
--- a/chrome/services/app_service/public/cpp/instance_update.cc
+++ b/chrome/services/app_service/public/cpp/instance_update.cc
@@ -29,6 +29,9 @@
   if (delta->State() != InstanceState::kUnknown) {
     state->UpdateState(delta->State(), delta->LastUpdatedTime());
   }
+  if (delta->BrowserContext()) {
+    state->SetBrowserContext(delta->BrowserContext());
+  }
   // When adding new fields to the Instance class, this function should also be
   // updated.
 }
@@ -63,6 +66,10 @@
        delta->LastUpdatedTime() != state->LastUpdatedTime())) {
     return false;
   }
+  if (delta->BrowserContext() &&
+      delta->BrowserContext() != state->BrowserContext()) {
+    return false;
+  }
   return true;
   // When adding new fields to the Instance class, this function should also be
   // updated.
@@ -135,4 +142,19 @@
          (!state_ || (delta_->LastUpdatedTime() != state_->LastUpdatedTime()));
 }
 
+content::BrowserContext* InstanceUpdate::BrowserContext() const {
+  if (delta_ && delta_->BrowserContext()) {
+    return delta_->BrowserContext();
+  }
+  if (state_ && state_->BrowserContext()) {
+    return state_->BrowserContext();
+  }
+  return nullptr;
+}
+
+bool InstanceUpdate::BrowserContextChanged() const {
+  return delta_ && delta_->BrowserContext() &&
+         (!state_ || (delta_->BrowserContext() != state_->BrowserContext()));
+}
+
 }  // namespace apps
diff --git a/chrome/services/app_service/public/cpp/instance_update.h b/chrome/services/app_service/public/cpp/instance_update.h
index 6bbf8386..34a082d 100644
--- a/chrome/services/app_service/public/cpp/instance_update.h
+++ b/chrome/services/app_service/public/cpp/instance_update.h
@@ -66,6 +66,9 @@
   base::Time LastUpdatedTime() const;
   bool LastUpdatedTimeChanged() const;
 
+  content::BrowserContext* BrowserContext() const;
+  bool BrowserContextChanged() const;
+
  private:
   Instance* state_;
   Instance* delta_;
diff --git a/chrome/services/app_service/public/cpp/instance_update_unittest.cc b/chrome/services/app_service/public/cpp/instance_update_unittest.cc
index 1264d78a..b746973d 100644
--- a/chrome/services/app_service/public/cpp/instance_update_unittest.cc
+++ b/chrome/services/app_service/public/cpp/instance_update_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/services/app_service/public/cpp/instance_update.h"
 #include "chrome/services/app_service/public/cpp/instance.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -98,6 +100,9 @@
   bool expect_state_changed_;
   base::Time expect_last_updated_time_;
   bool expect_last_updated_time_changed_;
+
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
 };
 
 TEST_F(InstanceUpdateTest, StateIsNonNull) {
@@ -186,3 +191,25 @@
   delta->UpdateState(apps::InstanceState::kRunning, base::Time::Now());
   EXPECT_FALSE(apps::InstanceUpdate::Equals(state.get(), delta.get()));
 }
+
+TEST_F(InstanceUpdateTest, BrowserContextIsUpdated) {
+  aura::Window window(nullptr);
+  window.Init(ui::LAYER_NOT_DRAWN);
+  std::unique_ptr<apps::Instance> state =
+      std::make_unique<apps::Instance>(app_id, &window);
+  std::unique_ptr<apps::Instance> delta =
+      std::make_unique<apps::Instance>(app_id, &window);
+  delta->SetBrowserContext(&profile_);
+  EXPECT_FALSE(apps::InstanceUpdate::Equals(state.get(), delta.get()));
+}
+
+TEST_F(InstanceUpdateTest, BrowserContextIsNotUpdated) {
+  aura::Window window(nullptr);
+  window.Init(ui::LAYER_NOT_DRAWN);
+  std::unique_ptr<apps::Instance> state =
+      std::make_unique<apps::Instance>(app_id, &window);
+  state->SetBrowserContext(&profile_);
+  std::unique_ptr<apps::Instance> delta =
+      std::make_unique<apps::Instance>(app_id, &window);
+  EXPECT_TRUE(apps::InstanceUpdate::Equals(state.get(), delta.get()));
+}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 4df17f1..4bf6084 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -694,6 +694,7 @@
       "//components/dom_distiller/content/browser",
       "//components/dom_distiller/content/renderer",
       "//components/dom_distiller/core:test_support",
+      "//components/embedder_support:switches",
       "//components/feature_engagement/test:test_support",
       "//components/nacl/common:buildflags",
       "//components/offline_items_collection/core/test_support",
@@ -882,6 +883,8 @@
       "../browser/chrome_security_exploit_browsertest.cc",
       "../browser/chrome_service_worker_browsertest.cc",
       "../browser/chrome_worker_browsertest.cc",
+      "../browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.cc",
+      "../browser/chromeos/certificate_provider/test_certificate_provider_extension_login_screen_mixin.h",
       "../browser/client_hints/client_hints_browsertest.cc",
       "../browser/component_updater/component_patcher_operation_browsertest.cc",
       "../browser/content_index/content_index_browsertest.cc",
@@ -1504,6 +1507,12 @@
           "//chromeos/components/help_app_ui:browser_tests_js",
           "//chromeos/components/media_app_ui:browser_tests_js",
         ]
+
+        if (!is_official_build) {
+          deps += [
+            "//chromeos/components/sample_system_web_app_ui:browser_tests_js",
+          ]
+        }
       }
     }
 
@@ -1912,6 +1921,7 @@
         "../browser/ui/views/autofill/payments/card_unmask_prompt_view_tester_views.h",
         "../browser/ui/views/autofill/payments/local_card_migration_browsertest.cc",
         "../browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc",
+        "../browser/ui/views/autofill/payments/virtual_card_selection_dialog_browsertest.cc",
         "../browser/ui/views/autofill/payments/webauthn_dialog_browsertest.cc",
         "../browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc",
         "../browser/ui/views/bookmarks/bookmark_editor_view_browsertest.cc",
@@ -2303,6 +2313,7 @@
         "../browser/chromeos/policy/device_cloud_external_data_policy_observer_browsertest.cc",
         "../browser/chromeos/policy/device_cloud_policy_browsertest.cc",
         "../browser/chromeos/policy/device_local_account_browsertest.cc",
+        "../browser/chromeos/policy/device_login_screen_policy_browsertest.cc",
         "../browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc",
         "../browser/chromeos/policy/device_policy_cros_browser_test.cc",
         "../browser/chromeos/policy/device_policy_cros_browser_test.h",
@@ -2392,7 +2403,6 @@
         "../browser/ui/views/crostini/crostini_browser_test_util.cc",
         "../browser/ui/views/crostini/crostini_browser_test_util.h",
         "../browser/ui/views/crostini/crostini_force_close_view_browsertest.cc",
-        "../browser/ui/views/crostini/crostini_installer_view_browsertest.cc",
         "../browser/ui/views/crostini/crostini_package_install_failure_view_browsertest.cc",
         "../browser/ui/views/crostini/crostini_uninstaller_view_browsertest.cc",
         "../browser/ui/views/crostini/crostini_update_component_view_browsertest.cc",
@@ -2504,7 +2514,6 @@
         "../browser/safe_browsing/certificate_reporting_service_browsertest.cc",
         "../browser/safe_browsing/chrome_password_protection_service_browsertest.cc",
         "../browser/safe_browsing/chrome_password_protection_service_sync_browsertest.cc",
-        "../browser/safe_browsing/client_side_detection_host_browsertest.cc",
         "../browser/safe_browsing/safe_browsing_blocking_page_test.cc",
         "../browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc",
         "../browser/safe_browsing/safe_browsing_service_browsertest.cc",
@@ -2833,6 +2842,7 @@
   ]
 
   data_deps = [
+    "//components/subresource_filter/tools:index_ruleset",
     "//testing:run_perf_test",
   ]
 }
@@ -2970,6 +2980,8 @@
     "../browser/android/metrics/background_task_memory_metrics_emitter_unittest.cc",
     "../browser/android/mock_location_settings.cc",
     "../browser/android/mock_location_settings.h",
+    "../browser/android/mock_nfc_system_level_setting.cc",
+    "../browser/android/mock_nfc_system_level_setting.h",
     "../browser/android/oom_intervention/near_oom_monitor_unittest.cc",
     "../browser/android/oom_intervention/oom_intervention_decider_unittest.cc",
     "../browser/android/password_edit_delegate_settings_impl_unittest.cc",
@@ -3135,6 +3147,7 @@
     "../browser/net/probe_message_unittest.cc",
     "../browser/net/referrer_policy_policy_handler_unittest.cc",
     "../browser/net/secure_dns_policy_handler_unittest.cc",
+    "../browser/nfc/nfc_permission_context_unittest.cc",
     "../browser/notifications/metrics/notification_metrics_logger_unittest.cc",
     "../browser/notifications/notification_channels_provider_android_unittest.cc",
     "../browser/notifications/notification_permission_context_unittest.cc",
@@ -4025,6 +4038,7 @@
       "../browser/usb/usb_chooser_context_unittest.cc",
       "../browser/usb/usb_chooser_controller_unittest.cc",
       "../browser/usb/usb_policy_allowed_devices_unittest.cc",
+      "../browser/usb/usb_tab_helper_unittest.cc",
       "../browser/usb/web_usb_detector_unittest.cc",
       "../browser/usb/web_usb_service_impl_unittest.cc",
       "../browser/webauthn/authenticator_request_dialog_model_unittest.cc",
@@ -4194,6 +4208,7 @@
     sources += [
       "../browser/component_updater/cros_component_installer_chromeos_unittest.cc",
       "../browser/component_updater/metadata_table_chromeos_unittest.cc",
+      "../browser/enterprise_reporting/android_app_info_generator_unittest.cc",
       "../browser/extensions/api/terminal/crostini_startup_status_unittest.cc",
       "../browser/google/google_brand_code_map_chromeos_unittest.cc",
       "../browser/media/webrtc/desktop_media_list_ash_unittest.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 37b5630..df46fa5 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -164,6 +164,7 @@
     "javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java",
     "javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java",
     "javatests/src/org/chromium/chrome/test/util/browser/TabTitleObserver.java",
+    "javatests/src/org/chromium/chrome/test/util/ChromeRenderTestRule.java",
     "javatests/src/org/chromium/chrome/test/util/ChromeRestriction.java",
     "javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java",
     "javatests/src/org/chromium/chrome/test/util/DisableInTabbedMode.java",
@@ -175,7 +176,6 @@
     "javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java",
     "javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java",
     "javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java",
-    "javatests/src/org/chromium/chrome/test/util/RenderTestRule.java",
     "javatests/src/org/chromium/chrome/test/util/SadTabRule.java",
     "javatests/src/org/chromium/chrome/test/util/TabStripUtils.java",
     "javatests/src/org/chromium/chrome/test/util/TranslateUtil.java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeRenderTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeRenderTestRule.java
new file mode 100644
index 0000000..c13180e4
--- /dev/null
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeRenderTestRule.java
@@ -0,0 +1,69 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.test.util;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.RenderTestRule;
+
+/**
+ * A TestRule for creating Render Tests for Chrome.
+ *
+ * <pre>
+ * {@code
+ *
+ * @RunWith(ChromeJUnit4ClassRunner.class)
+ * @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+ * public class MyTest {
+ *     // Provide RenderTestRule with the path from src/ to the golden directory.
+ *     @Rule
+ *     public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
+ *
+ *     @Test
+ *     // The test must have the feature "RenderTest" for the bots to display renders.
+ *     @Feature({"RenderTest"})
+ *     public void testViewAppearance() {
+ *         // Setup the UI.
+ *         ...
+ *
+ *         // Render UI Elements.
+ *         mRenderTestRule.render(bigWidgetView, "big_widget");
+ *         mRenderTestRule.render(smallWidgetView, "small_widget");
+ *     }
+ * }
+ *
+ * }
+ * </pre>
+ */
+public class ChromeRenderTestRule extends RenderTestRule {
+    /**
+     * Constructor using {@code "chrome/test/data/android/render_tests"} as default golden folder.
+     */
+    public ChromeRenderTestRule() {
+        super("chrome/test/data/android/render_tests");
+    }
+
+    /**
+     * Searches the View hierarchy and modifies the Views to provide better stability in tests. For
+     * example it will disable the blinking cursor in EditTexts.
+     */
+    public static void sanitize(View view) {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            // Add more sanitizations as we discover more flaky attributes.
+            if (view instanceof ViewGroup) {
+                ViewGroup viewGroup = (ViewGroup) view;
+                for (int i = 0; i < viewGroup.getChildCount(); i++) {
+                    sanitize(viewGroup.getChildAt(i));
+                }
+            } else if (view instanceof EditText) {
+                EditText editText = (EditText) view;
+                editText.setCursorVisible(false);
+            }
+        });
+    }
+}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
index 1b7107b..4e1eb239 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -284,7 +284,7 @@
         }
 
         @Override
-        public void onInteractabilityChanged(boolean interactable) {
+        public void onInteractabilityChanged(Tab tab, boolean interactable) {
             if (interactable) {
                 mCallback.notifyCalled();
                 mTab.removeObserver(this);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OWNERS b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OWNERS
index 6a75f4c..77d8ac5 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OWNERS
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OWNERS
@@ -1,2 +1 @@
 per-file RenderTestRule.java=peconn@chromium.org
-per-file RENDER_TESTS.md=peconn@chromium.org
\ No newline at end of file
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
index ae3a1da..21bbc55 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
@@ -112,7 +112,7 @@
             accountNames[i] = accounts[i].name;
             accountIds[i] = accountIdProvider.getAccountId(accounts[i].name);
         }
-        IdentityServicesProvider.getAccountTrackerService().syncForceRefreshForTest(
+        IdentityServicesProvider.get().getAccountTrackerService().syncForceRefreshForTest(
                 accountIds, accountNames);
     }
 
diff --git a/chrome/test/chromedriver/BUILD.gn b/chrome/test/chromedriver/BUILD.gn
index 2caa79d..cc839593 100644
--- a/chrome/test/chromedriver/BUILD.gn
+++ b/chrome/test/chromedriver/BUILD.gn
@@ -283,6 +283,7 @@
     "//chrome/common:version_header",
     "//chrome/test/chromedriver/constants:version_header",
     "//components/crx_file",
+    "//components/embedder_support:switches",
     "//components/version_info:generate_version_info",
     "//crypto",
     "//net",
diff --git a/chrome/test/chromedriver/chrome/device_manager.cc b/chrome/test/chromedriver/chrome/device_manager.cc
index 8334100..e6eb221a 100644
--- a/chrome/test/chromedriver/chrome/device_manager.cc
+++ b/chrome/test/chromedriver/chrome/device_manager.cc
@@ -80,6 +80,8 @@
     command_line_file = base::StringPrintf("/data/local/tmp/%s_devtools_remote",
                                            exec_name.c_str());
     use_debug_flag = true;
+  } else if (package.find("weblayer") != std::string::npos) {
+    command_line_file = "/data/local/tmp/weblayer-command-line";
   }
 
   if (!use_running_app) {
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index bbe6dcaf..0da80ce 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -54,6 +54,7 @@
 #include "chrome/test/chromedriver/log_replay/replay_http_client.h"
 #include "chrome/test/chromedriver/net/net_util.h"
 #include "components/crx_file/crx_verifier.h"
+#include "components/embedder_support/switches.h"
 #include "crypto/rsa_private_key.h"
 #include "crypto/sha2.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -71,7 +72,7 @@
 namespace {
 
 const char* const kCommonSwitches[] = {
-    "disable-popup-blocking",
+    embedder_support::kDisablePopupBlocking,
     "enable-automation",
 };
 
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 8850b42f..d2ee1e5 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -97,6 +97,8 @@
     'MobileEmulationCapabilityTest.testTapElement',
     # https://bugs.chromium.org/p/chromium/issues/detail?id=946023
     'ChromeDriverTest.testWindowFullScreen',
+    # https://bugs.chromium.org/p/chromium/issues/detail?id=1011225
+    'ChromeDriverTest.testActionsMultiTouchPoint',
 ]
 
 _DESKTOP_NEGATIVE_FILTER = [
@@ -880,6 +882,7 @@
       ],
       'parameters': {'pointerType': 'mouse'},
       'id': 'pointer1'}]})
+    time.sleep(1)
     self._driver.PerformActions(actions)
     rect = target.GetRect()
     self.assertEquals(150, rect['x'])
@@ -897,6 +900,7 @@
       ],
       'parameters': {'pointerType': 'mouse'},
       'id': 'pointer1'}]})
+    time.sleep(1)
     self._driver.PerformActions(actions)
     rect = target.GetRect()
     self.assertEquals(180, rect['x'])
@@ -916,6 +920,7 @@
       ],
       'parameters': {'pointerType': 'mouse'},
       'id': 'pointer1'}]})
+    time.sleep(1)
     self._driver.PerformActions(actions)
     rect = target.GetRect()
     self.assertEquals(180, rect['x'])
diff --git a/chrome/test/data/android/render_tests/ModalDialogViewRenderTest.NightModeEnabled-title_and_title_icon.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/ModalDialogViewRenderTest.NightModeEnabled-title_and_title_icon.Nexus_5X-23.png.sha1
index 5375aac..40b5054 100644
--- a/chrome/test/data/android/render_tests/ModalDialogViewRenderTest.NightModeEnabled-title_and_title_icon.Nexus_5X-23.png.sha1
+++ b/chrome/test/data/android/render_tests/ModalDialogViewRenderTest.NightModeEnabled-title_and_title_icon.Nexus_5X-23.png.sha1
@@ -1 +1 @@
-ab9b7cc343922f223821c1c98a48ebf7254352f8
\ No newline at end of file
+ab9b7cc343922f223821c1c98a48ebf7254352f8
diff --git a/chrome/test/data/extensions/api_test/input_ime_nonchromeos/background.js b/chrome/test/data/extensions/api_test/input_ime_nonchromeos/background.js
index d989fb94..1dbe77c 100644
--- a/chrome/test/data/extensions/api_test/input_ime_nonchromeos/background.js
+++ b/chrome/test/data/extensions/api_test/input_ime_nonchromeos/background.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-var failToSendKeyEvents = `Could not send key events.
+var failToSendKeyEvents = `Could not send key events. ENTER et al. keys are allowed only on http:, https: etc.
 Thrown by input.ime.sendKeyEvents`;
 
 chrome.test.runTests([
diff --git a/chrome/test/data/pdf/accessibility/directional-text-runs-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/directional-text-runs-expected-uia-win.txt
index d3ba4454..710fdd7 100644
--- a/chrome/test/data/pdf/accessibility/directional-text-runs-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/directional-text-runs-expected-uia-win.txt
@@ -1,7 +1,7 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Hello,<newline> world!<newline><newline>Goodbye,<newline> world!<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='This is some text abc<newline>def'
diff --git a/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt
index 2a6ee924..a78adb4 100644
--- a/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt
@@ -1,5 +1,5 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Hello, world!'
diff --git a/chrome/test/data/pdf/accessibility/highlights-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/highlights-expected-uia-win.txt
index 26b8820..023877f 100644
--- a/chrome/test/data/pdf/accessibility/highlights-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/highlights-expected-uia-win.txt
@@ -1,7 +1,7 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Hello'
 ++++++++++description Name='Hello'
 ++++++++description Name=', nice '
diff --git a/chrome/test/data/pdf/accessibility/image_alt_text-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/image_alt_text-expected-uia-win.txt
index 8d03b4b5..ca8c7255 100644
--- a/chrome/test/data/pdf/accessibility/image_alt_text-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/image_alt_text-expected-uia-win.txt
@@ -1,7 +1,7 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++img Name='Image 1'
 ++++++++img Name='Image 2'
 ++++++++img Name='Image 3'
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt
index b6d20fa..21bd808 100644
--- a/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt
@@ -1,8 +1,8 @@
 group
 ++document Name='PDF document containing 2 pages'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Page 1'
 ++++region Name='Page 2'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Page 2'
diff --git a/chrome/test/data/pdf/accessibility/overlapping-links-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/overlapping-links-expected-uia-win.txt
index 7eb90e6d..17a5570b 100644
--- a/chrome/test/data/pdf/accessibility/overlapping-links-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/overlapping-links-expected-uia-win.txt
@@ -1,10 +1,10 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++link Name='start first link start second link end second link end first link<newline>'
 ++++++++++description Name='start first link start second link end second link end first link<newline>' IsControlElement=false
-++++++group
+++++++group IsControlElement=false
 ++++++++link Name=' start second link end second link'
 ++++++++++description Name=' start second link end second link' IsControlElement=false
 ++++++++link Name='START FIRST LINK START SECOND LINK END FIRST LINK'
diff --git a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt
index 0222980..133962a 100644
--- a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt
@@ -1,13 +1,13 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++heading
+++++++heading IsControlElement=false
 ++++++++description Name='Heading<newline>' IsControlElement=false
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='This is a small pdf file:<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Lorem Ipsum is simply dummy text of the printing and typesetting industry.<newline>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='It has survived not only five centuries, but also the leap into electronic typesetting,<newline>remaining essentially unchanged. It was popularised in the 1960s with the release of<newline>Letraset sheets containing Lorem Ipsum passages, and more recently with desktop<newline>publishing software like Aldus PageMaker including versions of Lorem Ipsum.<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots<newline>in a piece of classical Latin literature from 45 BC, making it over 2000 years old.'
diff --git a/chrome/test/data/pdf/accessibility/text-image-link-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/text-image-link-expected-uia-win.txt
index 73fddcb..2dfda340 100644
--- a/chrome/test/data/pdf/accessibility/text-image-link-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/text-image-link-expected-uia-win.txt
@@ -1,12 +1,12 @@
 group
 ++document Name='PDF document containing 2 pages'
 ++++region Name='Page 1'
-++++++heading
+++++++heading IsControlElement=false
 ++++++++description Name='Link Annotations - Page 1<newline>' IsControlElement=false
-++++++heading
+++++++heading IsControlElement=false
 ++++++++link Name='Link with destination to second page<newline>'
 ++++++++++description Name='Link with destination to second page<newline>' IsControlElement=false
-++++++group
+++++++group IsControlElement=false
 ++++++++link Name='PDF Reference, Version 1.7,'
 ++++++++++description Name='PDF Reference, Version 1.7,' IsControlElement=false
 ++++++++description Name=' Section 8.4.5 defines Annotations<newline>3. Hello World<newline>'
@@ -21,5 +21,5 @@
 ++++++++img Name='Unlabeled graphic'
 ++++++++img Name='Unlabeled graphic'
 ++++region Name='Page 2'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Second Page'
diff --git a/chrome/test/data/pdf/accessibility/text-run-style-heuristic-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/text-run-style-heuristic-expected-uia-win.txt
index e2bdbb86..56a02f5 100644
--- a/chrome/test/data/pdf/accessibility/text-run-style-heuristic-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/text-run-style-heuristic-expected-uia-win.txt
@@ -1,5 +1,5 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Hello world! One word equals to one text run.'
diff --git a/chrome/test/data/pdf/accessibility/text-style-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/text-style-expected-uia-win.txt
index 25884fc..51645161 100644
--- a/chrome/test/data/pdf/accessibility/text-style-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/text-style-expected-uia-win.txt
@@ -1,11 +1,11 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Case 1<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Case 2<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Case 3<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Case 4'
diff --git a/chrome/test/data/pdf/accessibility/weblinks-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/weblinks-expected-uia-win.txt
index 353beeef..311e300c 100644
--- a/chrome/test/data/pdf/accessibility/weblinks-expected-uia-win.txt
+++ b/chrome/test/data/pdf/accessibility/weblinks-expected-uia-win.txt
@@ -1,17 +1,17 @@
 group
 ++document Name='PDF document containing 1 page'
 ++++region Name='Page 1'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Hello, '
 ++++++++link Name='http://yahoo.com'
 ++++++++++description Name='http://yahoo.com' IsControlElement=false
 ++++++++description Name='! nice meeting you<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Goodbye, '
 ++++++++link Name='http://bing.com'
 ++++++++++description Name='http://bing.com' IsControlElement=false
 ++++++++description Name='! nice meeting you<newline>'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Bye, '
 ++++++++link Name='http://google.com'
 ++++++++++description Name='http://google.com' IsControlElement=false
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js
index e700d34..f0d525a 100644
--- a/chrome/test/data/pdf/navigator_test.js
+++ b/chrome/test/data/pdf/navigator_test.js
@@ -5,9 +5,8 @@
 import {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 {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js';
 
-import {MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js';
+import {getZoomableViewport, MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js';
 
 class MockNavigatorDelegate {
   constructor() {
@@ -82,7 +81,7 @@
   const mockWindow = new MockWindow(100, 100);
   const mockSizer = new MockSizer();
   const mockViewportChangedCallback = new MockViewportChangedCallback();
-  const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+  const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
   viewport.setViewportChangedCallback(mockViewportChangedCallback.callback);
 
   const paramsParser = new OpenPdfParamsParser(function(name) {
@@ -113,7 +112,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
 
     const paramsParser = new OpenPdfParamsParser(function(destination) {
diff --git a/chrome/test/data/pdf/test_util.js b/chrome/test/data/pdf/test_util.js
index ed32e4ca..912689c1 100644
--- a/chrome/test/data/pdf/test_util.js
+++ b/chrome/test/data/pdf/test_util.js
@@ -4,6 +4,7 @@
 
 // Utilities that are used in multiple tests.
 
+import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 export function MockWindow(width, height, sizer) {
@@ -137,3 +138,22 @@
   });
   return document.createElement('test-bookmarks');
 }
+
+/**
+ * Create a viewport with basic default zoom values.
+ * @param {!Window} window
+ * @param {!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
+ *     be left blank above the document for the toolbar.
+ * @return {!Viewport} The viewport object with zoom values set.
+ */
+export function getZoomableViewport(
+    window, sizer, scrollbarWidth, defaultZoom, topToolbarHeight) {
+  const viewport = new Viewport(
+      window, sizer, scrollbarWidth, defaultZoom, topToolbarHeight);
+  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 ed14ea0..1cd7bae 100644
--- a/chrome/test/data/pdf/viewport_test.js
+++ b/chrome/test/data/pdf/viewport_test.js
@@ -5,12 +5,12 @@
 import {FittingType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_fitting_type.js';
 import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/viewport.js';
 
-import {MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js';
+import {getZoomableViewport, MockDocumentDimensions, MockSizer, MockViewportChangedCallback, MockWindow} from './test_util.js';
 
 const tests = [
   function testDocumentNeedsScrollbars() {
-    let viewport =
-        new Viewport(new MockWindow(100, 100), new MockSizer(), 10, 1, 0);
+    let viewport = getZoomableViewport(
+        new MockWindow(100, 100), new MockSizer(), 10, 1, 0);
     let scrollbars;
 
     viewport.setDocumentDimensions(new MockDocumentDimensions(90, 90));
@@ -66,7 +66,7 @@
 
     // Test the case when there is a toolbar at the top.
     const toolbarHeight = 10;
-    viewport = new Viewport(
+    viewport = getZoomableViewport(
         new MockWindow(100, 100), new MockSizer(), 10, 1, toolbarHeight);
 
     viewport.setDocumentDimensions(new MockDocumentDimensions(90, 90));
@@ -104,7 +104,7 @@
     const mockSizer = new MockSizer();
     const mockWindow = new MockWindow(100, 100, mockSizer);
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
 
     // Test setting the zoom without the document dimensions set. The sizer
@@ -179,7 +179,7 @@
 
   function testGetMostVisiblePage() {
     const mockWindow = new MockWindow(100, 100);
-    const viewport = new Viewport(mockWindow, new MockSizer(), 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, new MockSizer(), 0, 1, 0);
 
     const documentDimensions = new MockDocumentDimensions(100, 100);
     documentDimensions.addPage(50, 100);
@@ -239,7 +239,7 @@
 
   function testGetMostVisiblePageForTwoUpView() {
     const mockWindow = new MockWindow(400, 500);
-    const viewport = new Viewport(mockWindow, new MockSizer(), 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, new MockSizer(), 0, 1, 0);
     viewport.setTwoUpView(true);
 
     const documentDimensions = new MockDocumentDimensions(100, 100);
@@ -278,7 +278,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    let viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    let viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -335,7 +335,7 @@
     // Test fitting works with scrollbars. The page will need to be zoomed to
     // fit to width, which will cause the page height to span outside of the
     // viewport, triggering 15px scrollbars to be shown.
-    viewport = new Viewport(mockWindow, mockSizer, 15, 1, 0);
+    viewport = getZoomableViewport(mockWindow, mockSizer, 15, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     documentDimensions.reset();
     documentDimensions.addPage(50, 100);
@@ -353,7 +353,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -455,7 +455,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -557,7 +557,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -599,7 +599,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     viewport.setTwoUpView(true);
 
@@ -662,7 +662,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -704,7 +704,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     viewport.setTwoUpView(true);
 
@@ -768,7 +768,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -809,7 +809,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -862,7 +862,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -916,7 +916,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
 
@@ -964,7 +964,7 @@
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
     const mockCallback = new MockViewportChangedCallback();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
     viewport.setViewportChangedCallback(mockCallback.callback);
     const documentDimensions = new MockDocumentDimensions();
     documentDimensions.addPage(100, 100);
@@ -1010,7 +1010,7 @@
   function testBeforeZoomAfterZoom() {
     const mockWindow = new MockWindow(100, 100);
     const mockSizer = new MockSizer();
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 0);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 0);
 
     let afterZoomCalled = false;
     let beforeZoomCalled = false;
@@ -1032,8 +1032,8 @@
   },
 
   function testInitialSetDocumentDimensionsZoomConstrained() {
-    const viewport =
-        new Viewport(new MockWindow(100, 100), new MockSizer(), 0, 1.2, 0);
+    const viewport = getZoomableViewport(
+        new MockWindow(100, 100), new MockSizer(), 0, 1.2, 0);
     viewport.setDocumentDimensions(new MockDocumentDimensions(50, 50));
     chrome.test.assertEq(1.2, viewport.getZoom());
     chrome.test.succeed();
@@ -1041,7 +1041,7 @@
 
   function testInitialSetDocumentDimensionsZoomUnconstrained() {
     const viewport =
-        new Viewport(new MockWindow(100, 100), new MockSizer(), 0, 3, 0);
+        getZoomableViewport(new MockWindow(100, 100), new MockSizer(), 0, 3, 0);
     viewport.setDocumentDimensions(new MockDocumentDimensions(50, 50));
     chrome.test.assertEq(2, viewport.getZoom());
     chrome.test.succeed();
@@ -1049,7 +1049,7 @@
 
   function testLayoutOptions() {
     const viewport =
-        new Viewport(new MockWindow(100, 100), new MockSizer(), 0, 1, 0);
+        getZoomableViewport(new MockWindow(100, 100), new MockSizer(), 0, 1, 0);
 
     chrome.test.assertEq(undefined, viewport.getLayoutOptions());
 
@@ -1067,7 +1067,7 @@
   function testToolbarHeightOffset() {
     const mockSizer = new MockSizer();
     const mockWindow = new MockWindow(100, 100);
-    const viewport = new Viewport(mockWindow, mockSizer, 0, 1, 50);
+    const viewport = getZoomableViewport(mockWindow, mockSizer, 0, 1, 50);
     const documentDimensions = new MockDocumentDimensions(0, 0);
     documentDimensions.addPage(50, 500);
     viewport.setDocumentDimensions(documentDimensions);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 0b0b569..d34a60b1 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4906,6 +4906,8 @@
 
   "DeviceLoginScreenDefaultSpokenFeedbackEnabled" : {},
 
+  "DeviceLoginScreenPrimaryMouseButtonSwitch" : {},
+
   "DeviceLoginScreenSpokenFeedbackEnabled": {},
 
   "DeviceLoginScreenDefaultHighContrastEnabled": {},
diff --git a/chrome/test/data/prerender/prerender_print.html b/chrome/test/data/prerender/prerender_print.html
deleted file mode 100644
index 41b9498..0000000
--- a/chrome/test/data/prerender/prerender_print.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-  <head>
-    <title>Prerender Print</title>
-    <script>
-      window.print();
-    </script>
-  </head>
-  <body></body>
-</html>
-
diff --git a/chrome/test/data/webui/cr_elements/cr_radio_group_test.js b/chrome/test/data/webui/cr_elements/cr_radio_group_test.js
index 3029123..600a69e 100644
--- a/chrome/test/data/webui/cr_elements/cr_radio_group_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_radio_group_test.js
@@ -44,9 +44,28 @@
   /**
    * @param {string} name
    */
-  function noneSelectedOneFocusable(name) {
-    checkLength(1, `:not([checked])[tabindex="0"][name="${name}"]`);
-    checkLength(2, ':not([checked])[tabindex="-1"]');
+  function verifyNoneSelectedOneFocusable(name) {
+    const uncheckedRows = Array.from(
+        radioGroup.querySelectorAll(`cr-radio-button:not([checked])`));
+    assertEquals(3, uncheckedRows.length);
+
+    const focusableRow = uncheckedRows.filter(
+        radioButton =>
+            radioButton.name == name && radioButton.$.button.tabIndex == 0);
+    assertEquals(1, focusableRow.length);
+
+    const unfocusableRows = uncheckedRows.filter(
+        radioButton => radioButton.$.button.tabIndex == -1);
+    assertEquals(2, unfocusableRows.length);
+  }
+
+  function checkNoneFocusable() {
+    const allRows = Array.from(radioGroup.querySelectorAll(`cr-radio-button`));
+    assertEquals(3, allRows.length);
+
+    const unfocusableRows =
+        allRows.filter(radioButton => radioButton.$.button.tabIndex == -1);
+    assertEquals(3, unfocusableRows.length);
   }
 
   /**
@@ -76,8 +95,18 @@
    */
   function checkSelected(name) {
     assertEquals(`${name}`, radioGroup.selected);
-    checkLength(1, `[name="${name}"][checked][tabindex="0"]`);
-    checkLength(2, `:not([name="${name}"]):not([checked])[tabindex="-1"]`);
+
+    const selectedRows = Array.from(radioGroup.querySelectorAll(
+        `cr-radio-button[name="${name}"][checked]`));
+    const focusableRows =
+        selectedRows.filter(radioButton => radioButton.$.button.tabIndex == 0);
+    assertEquals(1, focusableRows.length);
+
+    const unselectedRows = Array.from(radioGroup.querySelectorAll(
+        `cr-radio-button:not([name="${name}"]):not([checked])`));
+    const filteredUnselected = unselectedRows.filter(
+        radioButton => radioButton.$.button.tabIndex == -1);
+    assertEquals(2, filteredUnselected.length);
   }
 
   test('selected-changed bubbles', () => {
@@ -91,11 +120,11 @@
     press('Enter');
     checkSelected(1);
     radioGroup.selected = '';
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     press(' ');
     checkSelected(1);
     radioGroup.selected = '';
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     press('ArrowRight');
     checkSelected(2);
   });
@@ -124,8 +153,7 @@
   });
 
   test('key events skip over disabled radios', () => {
-    checkLength(1, '[tabindex="0"][name="1"]');
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     radioGroup.querySelector('[name="2"]').disabled = true;
     press('PageDown');
     checkSelected(3);
@@ -135,19 +163,20 @@
     radioGroup.selected = '1';
     checkSelected(1);
     radioGroup.disabled = true;
-    checkLength(3, '[tabindex="-1"]');
+    checkNoneFocusable();
     radioGroup.disabled = false;
     checkSelected(1);
     const firstRadio = radioGroup.querySelector('[name="1"]');
     firstRadio.disabled = true;
-    checkLength(2, '[tabindex="-1"]');
-    checkLength(1, '[tabindex="0"][name="2"]');
+    assertEquals(-1, firstRadio.$.button.tabIndex);
+    const secondRadio = radioGroup.querySelector('[name="2"]');
+    assertEquals(0, secondRadio.$.button.tabIndex);
     firstRadio.disabled = false;
     checkSelected(1);
     radioGroup.selected = '';
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     firstRadio.disabled = true;
-    noneSelectedOneFocusable(2);
+    verifyNoneSelectedOneFocusable(2);
   });
 
   test('when group is disabled, button aria-disabled is updated', () => {
@@ -178,38 +207,43 @@
   test('radios name change updates selection and tabindex', () => {
     radioGroup.selected = '1';
     checkSelected(1);
-    radioGroup.querySelector('[name="1"]').name = 'A';
-    checkLength(1, ':not([checked])[tabindex="0"][name="A"]');
-    checkLength(2, '[tabindex="-1"]');
+    const firstRadio = radioGroup.querySelector('[name="1"]');
+    firstRadio.name = 'A';
+    assertEquals(0, firstRadio.$.button.tabIndex);
+    assertFalse(firstRadio.checked);
+    verifyNoneSelectedOneFocusable('A');
     const secondRadio = radioGroup.querySelector('[name="2"]');
     radioGroup.querySelector('[name="2"]').name = '1';
-    checkLength(1, '[checked][tabindex="0"][name="1"]');
-    checkLength(2, '[tabindex="-1"]');
+    checkSelected('1');
   });
 
   test('radios with links', () => {
     const a = radioGroup.querySelector('a');
     assertTrue(!!a);
-    noneSelectedOneFocusable(1);
+    assertEquals(-1, a.tabIndex);
+    verifyNoneSelectedOneFocusable(1);
     press('Enter', a);
     press(' ', a);
     a.click();
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     radioGroup.querySelector('[name="1"]').click();
     checkSelected(1);
     press('Enter', a);
     press(' ', a);
     a.click();
     checkSelected(1);
+    radioGroup.querySelector('[name="3"]').click();
+    checkSelected(3);
+    assertEquals(0, a.tabIndex);
   });
 
   test('radios with input', () => {
     const input = radioGroup.querySelector('input');
     assertTrue(!!input);
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     press('Enter', input);
     press(' ', input);
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     input.click();
     checkSelected(2);
     radioGroup.querySelector('[name="1"]').click();
@@ -221,7 +255,7 @@
   });
 
   test('select the radio that has focus when space or enter pressed', () => {
-    noneSelectedOneFocusable(1);
+    verifyNoneSelectedOneFocusable(1);
     press('Enter', radioGroup.querySelector('[name="3"]'));
     checkSelected(3);
     press(' ', radioGroup.querySelector('[name="2"]'));
diff --git a/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js b/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js
index aa8f60a7..eb369a3 100644
--- a/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js
+++ b/chrome/test/data/webui/settings/a11y/edit_dictionary_a11y_test.js
@@ -6,7 +6,8 @@
 
 // Disable since the EDIT_DICTIONARY route does not exist on Mac.
 // TODO(crbug.com/1012370) flaky on Linux b/c assertTrue(!!languagesPage);
-GEN('#if !defined(OS_MACOSX) && !defined(OS_LINUX)');
+// TODO(crbug.com/1012370) flaky on Win the same way
+GEN('#if !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_WIN)');
 
 // SettingsAccessibilityTest fixture.
 GEN_INCLUDE([
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js
index fa2cfa6..f2ce35149 100644
--- a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js
@@ -564,7 +564,8 @@
     addDialog.$$('.action-button').click();
     Polymer.dom.flush();
 
-    const eulaLink = 'google.com';
+    const eulaLink = 'google';
+    const expectedEulaLink = 'chrome://os-settings/' + eulaLink;
     const expectedManufacturer = 'Google';
     const expectedModel = 'printer';
     const expectedModel2 = 'newPrinter';
@@ -595,6 +596,7 @@
         .then(function(args) {
           // Check that the EULA text is shown.
           assertFalse(urlElement.hidden);
+          assertEquals(expectedEulaLink, urlElement.querySelector('a').href);
 
           resetGetEulaUrl(cupsPrintersBrowserProxy, '' /* eulaUrl */);
 
@@ -616,6 +618,7 @@
         })
         .then(function(args) {
           assertFalse(urlElement.hidden);
+          assertEquals(expectedEulaLink, urlElement.querySelector('a').href);
         });
   });
 
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 529b89fb..fded1f6a 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -910,12 +910,6 @@
   mocha.grep('PersonalizationOptionsTests_AllBuilds').run();
 });
 
-TEST_F(
-    'CrSettingsPersonalizationOptionsTest', 'PrivacySettingsRedesignTests',
-    function() {
-      mocha.grep('PrivacySettingsRedesignTests').run();
-    });
-
 GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)');
 TEST_F('CrSettingsPersonalizationOptionsTest', 'OfficialBuild', function() {
   mocha.grep('PersonalizationOptionsTests_OfficialBuild').run();
@@ -962,11 +956,6 @@
   mocha.run();
 });
 
-TEST_F('CrSettingsPrivacyPageTest', 'PrivacySettingsRedesignTests', function() {
-  settings_privacy_page.registerPrivacySettingsRedesignTests();
-  mocha.run();
-});
-
 TEST_F('CrSettingsPrivacyPageTest', 'UMALoggingTests', function() {
   settings_privacy_page.registerUMALoggingTests();
   mocha.run();
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js
index ec24a42..c294a32ca 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -20,6 +20,10 @@
       // We don't perform tests on them.
       syncPage.prefs = {
         profile: {password_manager_leak_detection: {value: true}},
+        signin: {
+          allowed_on_next_startup:
+              {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true}
+        },
         safebrowsing:
             {enabled: {value: true}, scout_reporting_enabled: {value: true}},
       };
@@ -314,8 +318,8 @@
 
           // Assert that the radio boxes are disabled after encryption enabled.
           assertTrue(syncPage.$$('#encryptionRadioGroup').disabled);
-          assertEquals('-1', encryptWithGoogle.getAttribute('tabindex'));
-          assertEquals('-1', encryptWithPassphrase.getAttribute('tabindex'));
+          assertEquals(-1, encryptWithGoogle.$.button.tabIndex);
+          assertEquals(-1, encryptWithPassphrase.$.button.tabIndex);
         });
       }
       return browserProxy.whenCalled('setSyncEncryption').then(verifyPrefs);
@@ -417,8 +421,8 @@
 
         // Verify that the encryption radio boxes are shown but disabled.
         assertTrue(syncPage.$$('#encryptionRadioGroup').disabled);
-        assertEquals('-1', encryptWithGoogle.getAttribute('tabindex'));
-        assertEquals('-1', encryptWithPassphrase.getAttribute('tabindex'));
+        assertEquals(-1, encryptWithGoogle.$.button.tabIndex);
+        assertEquals(-1, encryptWithPassphrase.$.button.tabIndex);
       });
     });
 
diff --git a/chrome/test/data/webui/settings/personalization_options_test.js b/chrome/test/data/webui/settings/personalization_options_test.js
index 0c0e06f..7c1b475 100644
--- a/chrome/test/data/webui/settings/personalization_options_test.js
+++ b/chrome/test/data/webui/settings/personalization_options_test.js
@@ -26,6 +26,7 @@
       loadTimeData.overrideValues({
         driveSuggestAvailable: true,
         passwordsLeakDetectionEnabled: true,
+        privacySettingsRedesign: false,
       });
     });
 
@@ -37,6 +38,10 @@
       PolymerTest.clearBody();
       testElement = document.createElement('settings-personalization-options');
       testElement.prefs = {
+        signin: {
+          allowed_on_next_startup:
+              {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true},
+        },
         profile: {password_manager_leak_detection: {value: true}},
         safebrowsing:
             {enabled: {value: true}, scout_reporting_enabled: {value: true}},
@@ -67,124 +72,50 @@
       assertFalse(!!testElement.$$('#driveSuggestControl'));
     });
 
-    test('PrivacySettingsRedesignEnabled_False', function() {
-      // Ensure that elements hidden by the updated privacy settings
-      // flag remain visible when the flag is in the default state
-      assertFalse(loadTimeData.getBoolean('privacySettingsRedesignEnabled'));
-      assertVisible(testElement.$$('#safeBrowsingToggle'), true);
-      assertVisible(testElement.$$('#passwordsLeakDetectionToggle'), true);
-      assertVisible(testElement.$$('#safeBrowsingReportingToggle'), true);
-      assertFalse(!!testElement.$$('#signinAllowedToggle'));
-    });
-
-    test('safeBrowsingReportingToggle', function() {
-      const safeBrowsingToggle = testElement.$$('#safeBrowsingToggle');
-      const safeBrowsingReportingToggle =
-          testElement.$$('#safeBrowsingReportingToggle');
-      assertTrue(safeBrowsingToggle.checked);
-      assertFalse(safeBrowsingReportingToggle.disabled);
-      assertTrue(safeBrowsingReportingToggle.checked);
-      safeBrowsingToggle.click();
-      Polymer.dom.flush();
-
-      assertFalse(safeBrowsingToggle.checked);
-      assertTrue(safeBrowsingReportingToggle.disabled);
-      assertFalse(safeBrowsingReportingToggle.checked);
-      assertTrue(testElement.prefs.safebrowsing.scout_reporting_enabled.value);
-      safeBrowsingToggle.click();
-      Polymer.dom.flush();
-
-      assertTrue(safeBrowsingToggle.checked);
-      assertFalse(safeBrowsingReportingToggle.disabled);
-      assertTrue(safeBrowsingReportingToggle.checked);
-    });
-  });
-
-  suite('PrivacySettingsRedesignTests', function() {
-    /** @type {SettingsPrivacyPageElement} */
-    let page;
-
-    suiteSetup(function() {
-      loadTimeData.overrideValues({
-        privacySettingsRedesignEnabled: true,
-      });
-    });
-
-    setup(function() {
-      const testBrowserProxy = new TestPrivacyPageBrowserProxy();
-      settings.PrivacyPageBrowserProxyImpl.instance_ = testBrowserProxy;
-      const syncBrowserProxy = new TestSyncBrowserProxy();
-      settings.SyncBrowserProxyImpl.instance_ = syncBrowserProxy;
-      PolymerTest.clearBody();
-
-      page = document.createElement('settings-personalization-options');
-      page.prefs = {
-        profile: {password_manager_leak_detection: {value: true}},
-        safebrowsing:
-            {enabled: {value: true}, scout_reporting_enabled: {value: true}},
-        signin: {
-          allowed_on_next_startup:
-              {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true},
-        },
-      };
-      document.body.appendChild(page);
-      Polymer.dom.flush();
-    });
-
-    teardown(function() {
-      page.remove();
-    });
-
-    test('PrivacySettingsRedesignEnabled_True', function() {
-      Polymer.dom.flush();
-      assertFalse(!!page.$$('#safeBrowsingToggle'));
-      assertFalse(!!page.$$('#passwordsLeakDetectionToggle'));
-      assertFalse(!!page.$$('#safeBrowsingReportingToggle'));
-    });
-
     if (!cr.isChromeOS) {
       test('signinAllowedToggle', function() {
-        const toggle = page.$$('#signinAllowedToggle');
+        const toggle = testElement.$.signinAllowedToggle;
         assertVisible(toggle, true);
 
-        page.syncStatus = {signedIn: false};
+        testElement.syncStatus = {signedIn: false};
         // Check initial setup.
         assertTrue(toggle.checked);
-        assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-        assertFalse(!!page.$.toast.open);
+        assertTrue(testElement.prefs.signin.allowed_on_next_startup.value);
+        assertFalse(!!testElement.$.toast.open);
 
         // When the user is signed out, clicking the toggle should work
         // normally and the restart toast should be opened.
         toggle.click();
         assertFalse(toggle.checked);
-        assertFalse(page.prefs.signin.allowed_on_next_startup.value);
-        assertTrue(page.$.toast.open);
+        assertFalse(testElement.prefs.signin.allowed_on_next_startup.value);
+        assertTrue(testElement.$.toast.open);
 
         // Clicking it again, turns the toggle back on. The toast remains
         // open.
         toggle.click();
         assertTrue(toggle.checked);
-        assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-        assertTrue(page.$.toast.open);
+        assertTrue(testElement.prefs.signin.allowed_on_next_startup.value);
+        assertTrue(testElement.$.toast.open);
 
         // Reset toast.
-        page.showRestartToast_ = false;
-        assertFalse(page.$.toast.open);
+        testElement.showRestartToast_ = false;
+        assertFalse(testElement.$.toast.open);
 
-        page.syncStatus = {signedIn: true};
+        testElement.syncStatus = {signedIn: true};
         // When the user is signed in, clicking the toggle should open the
         // sign-out dialog.
-        assertFalse(!!page.$$('settings-signout-dialog'));
+        assertFalse(!!testElement.$$('settings-signout-dialog'));
         toggle.click();
-        return test_util.eventToPromise('cr-dialog-open', page)
+        return test_util.eventToPromise('cr-dialog-open', testElement)
             .then(function() {
               Polymer.dom.flush();
               // The toggle remains on.
               assertTrue(toggle.checked);
-              assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-              assertFalse(page.$.toast.open);
+              assertTrue(
+                  testElement.prefs.signin.allowed_on_next_startup.value);
+              assertFalse(testElement.$.toast.open);
 
-              const signoutDialog = page.$$('settings-signout-dialog');
+              const signoutDialog = testElement.$$('settings-signout-dialog');
               assertTrue(!!signoutDialog);
               assertTrue(signoutDialog.$$('#dialog').open);
 
@@ -196,20 +127,21 @@
             })
             .then(function() {
               Polymer.dom.flush();
-              assertFalse(!!page.$$('settings-signout-dialog'));
+              assertFalse(!!testElement.$$('settings-signout-dialog'));
 
               // After the dialog is closed, the toggle remains turned on.
               assertTrue(toggle.checked);
-              assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-              assertFalse(page.$.toast.open);
+              assertTrue(
+                  testElement.prefs.signin.allowed_on_next_startup.value);
+              assertFalse(testElement.$.toast.open);
 
               // The user clicks the toggle again.
               toggle.click();
-              return test_util.eventToPromise('cr-dialog-open', page);
+              return test_util.eventToPromise('cr-dialog-open', testElement);
             })
             .then(function() {
               Polymer.dom.flush();
-              const signoutDialog = page.$$('settings-signout-dialog');
+              const signoutDialog = testElement.$$('settings-signout-dialog');
               assertTrue(!!signoutDialog);
               assertTrue(signoutDialog.$$('#dialog').open);
 
@@ -224,8 +156,9 @@
               // After the dialog is closed, the toggle is turned off and the
               // toast is shown.
               assertFalse(toggle.checked);
-              assertFalse(page.prefs.signin.allowed_on_next_startup.value);
-              assertTrue(page.$.toast.open);
+              assertFalse(
+                  testElement.prefs.signin.allowed_on_next_startup.value);
+              assertTrue(testElement.$.toast.open);
             });
       });
     }
diff --git a/chrome/test/data/webui/settings/privacy_page_test.js b/chrome/test/data/webui/settings/privacy_page_test.js
index 63de556..6e41be6 100644
--- a/chrome/test/data/webui/settings/privacy_page_test.js
+++ b/chrome/test/data/webui/settings/privacy_page_test.js
@@ -223,6 +223,7 @@
 
         page = document.createElement('settings-privacy-page');
         page.prefs = {
+          profile: {password_manager_leak_detection: {value: true}},
           signin: {
             allowed_on_next_startup:
                 {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true}
@@ -253,153 +254,9 @@
             dialog.$$('#clearBrowsingDataDialog'), 'open', '');
       });
 
-      test('defaultPrivacySettings', function() {
-        Polymer.dom.flush();
-
-        assertFalse(loadTimeData.getBoolean('privacySettingsRedesignEnabled'));
-        assertVisible(page.$$('#syncLinkRow'), true);
-
-        // These elements should not even be present in the DOM
-        assertFalse(!!page.$$('#safeBrowsingToggle'));
-        assertFalse(!!page.$$('#passwordsLeakDetectionToggle'));
-        assertFalse(!!page.$$('#safeBrowsingReportingToggle'));
-      });
-
-      if (!cr.isChromeOS) {
-        test('signinAllowedToggle', function() {
-          const toggle = page.$$('#signinAllowedToggle');
-          assertVisible(toggle, true);
-
-          page.syncStatus = {signedIn: false};
-          // Check initial setup.
-          assertTrue(toggle.checked);
-          assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-          assertFalse(page.$.toast.open);
-
-          // When the user is signed out, clicking the toggle should work
-          // normally and the restart toast should be opened.
-          toggle.click();
-          assertFalse(toggle.checked);
-          assertFalse(page.prefs.signin.allowed_on_next_startup.value);
-          assertTrue(page.$.toast.open);
-
-          // Clicking it again, turns the toggle back on. The toast remains
-          // open.
-          toggle.click();
-          assertTrue(toggle.checked);
-          assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-          assertTrue(page.$.toast.open);
-
-          // Reset toast.
-          page.showRestart_ = false;
-          assertFalse(page.$.toast.open);
-
-          page.syncStatus = {signedIn: true};
-          // When the user is signed in, clicking the toggle should open the
-          // sign-out dialog.
-          assertFalse(!!page.$$('settings-signout-dialog'));
-          toggle.click();
-          return test_util.eventToPromise('cr-dialog-open', page)
-              .then(function() {
-                Polymer.dom.flush();
-                // The toggle remains on.
-                assertTrue(toggle.checked);
-                assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-                assertFalse(page.$.toast.open);
-
-                const signoutDialog = page.$$('settings-signout-dialog');
-                assertTrue(!!signoutDialog);
-                assertTrue(signoutDialog.$$('#dialog').open);
-
-                // The user clicks cancel.
-                const cancel = signoutDialog.$$('#disconnectCancel');
-                cancel.click();
-
-                return test_util.eventToPromise('close', signoutDialog);
-              })
-              .then(function() {
-                Polymer.dom.flush();
-                assertFalse(!!page.$$('settings-signout-dialog'));
-
-                // After the dialog is closed, the toggle remains turned on.
-                assertTrue(toggle.checked);
-                assertTrue(page.prefs.signin.allowed_on_next_startup.value);
-                assertFalse(page.$.toast.open);
-
-                // The user clicks the toggle again.
-                toggle.click();
-                return test_util.eventToPromise('cr-dialog-open', page);
-              })
-              .then(function() {
-                Polymer.dom.flush();
-                const signoutDialog = page.$$('settings-signout-dialog');
-                assertTrue(!!signoutDialog);
-                assertTrue(signoutDialog.$$('#dialog').open);
-
-                // The user clicks confirm, which signs them out.
-                const disconnectConfirm =
-                    signoutDialog.$$('#disconnectConfirm');
-                disconnectConfirm.click();
-
-                return test_util.eventToPromise('close', signoutDialog);
-              })
-              .then(function() {
-                Polymer.dom.flush();
-                // After the dialog is closed, the toggle is turned off and the
-                // toast is shown.
-                assertFalse(toggle.checked);
-                assertFalse(page.prefs.signin.allowed_on_next_startup.value);
-                assertTrue(page.$.toast.open);
-              });
-        });
-      }
-    });
-  }
-
-  function registerPrivacySettingsRedesignTests() {
-    suite('PrivacySettingsRedesignTests', function() {
-      /** @type {SettingsPrivacyPageElement} */
-      let page;
-
-      suiteSetup(function() {
-        loadTimeData.overrideValues({
-          privacySettingsRedesignEnabled: true,
-          passwordsLeakDetectionEnabled: true,
-        });
-      });
-
-      setup(function() {
-        PolymerTest.clearBody();
-        page = document.createElement('settings-privacy-page');
-        page.prefs = {
-          profile: {password_manager_leak_detection: {value: true}},
-          safebrowsing:
-              {enabled: {value: true}, scout_reporting_enabled: {value: true}},
-        };
-        document.body.appendChild(page);
-        Polymer.dom.flush();
-      });
-
-      teardown(function() {
-        page.remove();
-      });
-
-      test('redesignedPrivacySettings', function() {
-        Polymer.dom.flush();
-
-        // Unloaded elements will not be present in the DOM
-        assertFalse(!!page.$$('#syncLinkRow'));
-        assertFalse(!!page.$$('#signinAllowedToggle'));
-
-        assertVisible(page.$$('#safeBrowsingToggle'), true);
-        assertVisible(page.$$('#passwordsLeakDetectionToggle'), true);
-        assertVisible(page.$$('#safeBrowsingReportingToggle'), true);
-      });
-
       test('safeBrowsingReportingToggle', function() {
-        const safeBrowsingToggle = page.$$('#safeBrowsingToggle');
-        const safeBrowsingReportingToggle =
-            page.$$('#safeBrowsingReportingToggle');
+        const safeBrowsingToggle = page.$.safeBrowsingToggle;
+        const safeBrowsingReportingToggle = page.$.safeBrowsingReportingToggle;
         assertTrue(safeBrowsingToggle.checked);
         assertFalse(safeBrowsingReportingToggle.disabled);
         assertTrue(safeBrowsingReportingToggle.checked);
@@ -987,7 +844,6 @@
     registerInstalledAppsTests,
     registerPrivacyPageTests,
     registerPrivacyPageSoundTests,
-    registerPrivacySettingsRedesignTests,
     registerUMALoggingTests,
   };
 });
diff --git a/chrome/test/data/webui/settings/settings_menu_test.js b/chrome/test/data/webui/settings/settings_menu_test.js
index 3d1a933..e55cd18 100644
--- a/chrome/test/data/webui/settings/settings_menu_test.js
+++ b/chrome/test/data/webui/settings/settings_menu_test.js
@@ -130,9 +130,7 @@
             expectedHidden, settingsMenu.$$('#advancedSubmenu').hidden);
         assertEquals(expectedHidden, settingsMenu.$$('#reset').hidden);
 
-        if (cr.isChromeOS) {
-          assertEquals(expectedHidden, settingsMenu.$$('#multidevice').hidden);
-        } else {
+        if (!cr.isChromeOS) {
           assertEquals(
               expectedHidden, settingsMenu.$$('#defaultBrowser').hidden);
         }
diff --git a/chrome/test/data/webui/settings/sync_account_control_test.js b/chrome/test/data/webui/settings/sync_account_control_test.js
index a0f894c..fd2adb5c 100644
--- a/chrome/test/data/webui/settings/sync_account_control_test.js
+++ b/chrome/test/data/webui/settings/sync_account_control_test.js
@@ -36,8 +36,6 @@
     });
 
     setup(function() {
-      assertFalse(loadTimeData.getBoolean('privacySettingsRedesignEnabled'));
-
       browserProxy = new TestSyncBrowserProxy();
       settings.SyncBrowserProxyImpl.instance_ = browserProxy;
 
@@ -500,51 +498,6 @@
       assertVisible(testElement.$$('#sync-error-button'), false);
     });
 
-    test('PrivacySettingsRedesignEnabled_False', function() {
-      // Ensure that the sync button is enabled regardless of signin pref.
-      assertTrue(testElement.getPref('signin.allowed_on_next_startup').value);
-      assertFalse(testElement.$$('#sign-in').disabled);
-      testElement.setPrefValue('signin.allowed_on_next_startup', false);
-      Polymer.dom.flush();
-      assertFalse(testElement.$$('#sign-in').disabled);
-    });
-  });
-
-  suite('PrivacySettingsRedesignTests', function() {
-    const peoplePage = null;
-    let browserProxy = null;
-    let testElement = null;
-
-    suiteSetup(function() {
-      loadTimeData.overrideValues({
-        privacySettingsRedesignEnabled: true,
-      });
-    });
-
-    setup(function() {
-      browserProxy = new TestSyncBrowserProxy();
-      settings.SyncBrowserProxyImpl.instance_ = browserProxy;
-
-      PolymerTest.clearBody();
-      testElement = document.createElement('settings-sync-account-control');
-      testElement.syncStatus = {
-        signedIn: true,
-        signedInUsername: 'foo@foo.com'
-      };
-      testElement.prefs = {
-        signin: {
-          allowed_on_next_startup:
-              {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true},
-        },
-      };
-      document.body.appendChild(testElement);
-      Polymer.dom.flush();
-    });
-
-    teardown(function() {
-      testElement.remove();
-    });
-
     test('signinButtonDisabled', function() {
       // Ensure that the sync button is disabled when signin is disabled.
       assertFalse(testElement.$$('#sign-in').disabled);
diff --git a/chrome/test/data/webui/usb_internals_browsertest.js b/chrome/test/data/webui/usb_internals_browsertest.js
index b6cb8b56..4a116ba1 100644
--- a/chrome/test/data/webui/usb_internals_browsertest.js
+++ b/chrome/test/data/webui/usb_internals_browsertest.js
@@ -268,7 +268,8 @@
 
     window.setupFn = () => {
       this.pageHandlerInterceptor = new MojoInterfaceInterceptor(
-          mojom.UsbInternalsPageHandler.$interfaceName);
+          mojom.UsbInternalsPageHandler.$interfaceName, 'context',
+          /*useBrowserInterfaceBroker=*/ true);
       this.pageHandlerInterceptor.oninterfacerequest = (e) => {
         this.pageHandler = new FakePageHandlerRemote(e.handle);
       };
diff --git a/chrome/test/enterprise/e2e/.vpython b/chrome/test/enterprise/e2e/.vpython
index b68566c..7450f87 100644
--- a/chrome/test/enterprise/e2e/.vpython
+++ b/chrome/test/enterprise/e2e/.vpython
@@ -11,8 +11,8 @@
 
 wheel: <
   name: "infra/celab/celab/windows-amd64"
-  # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8900225462594660384
-  version: "Q1ebL0sPA1vX4tcIGj6d0IXxXa02M5CsBm3p0SbeGZUC"
+  # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8893872172112857632
+  version: "7tbcDKAu1KJPhKI-HMQr18oW5DTRvu-0plN8v3szwIQC"
 >
 
 # googleapiclient
diff --git a/chrome/test/enterprise/e2e/test.py b/chrome/test/enterprise/e2e/test.py
index e07c078..d07f1248 100644
--- a/chrome/test/enterprise/e2e/test.py
+++ b/chrome/test/enterprise/e2e/test.py
@@ -36,6 +36,9 @@
     'skip_before_all', False, 'True to skip @before_all methods. '
     'Like --nodeploy, this is used to skip set up steps. '
     'Useful when developing new tests.')
+flags.DEFINE_bool(
+    'no_external_access', False, 'True to skip creating RDP/SSH firewall '
+    'rules during deployment. Should be used in automated test runs.')
 flags.DEFINE_bool('cleanup', False,
                   'Clean up the host environment after the test')
 flags.DEFINE_string('error_logs_dir', None,
@@ -67,7 +70,8 @@
       FLAGS.host,
       FLAGS.cel_ctl,
       test_filter=FLAGS.test_filter,
-      skip_before_all=FLAGS.skip_before_all)
+      skip_before_all=FLAGS.skip_before_all,
+      no_external_access=FLAGS.no_external_access)
 
   # Parse test specific flags. Note that we need to use a dummy element
   # as the first element of the list since absl.flags ignores the first element
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index 9c38040..9fc9603e 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -128,18 +128,15 @@
   }
   filters += [ cast_media_unittests_filter ]
 
-  if (!is_android) {
+  if (!is_android && !is_fuchsia) {
     tests += [
       ":cast_shell_browsertests",
       ":cast_shell_unittests",
       "//ipc:ipc_tests",
+      "//jingle:jingle_unittests",
       "//url:url_unittests",
     ]
 
-    if (!is_fuchsia) {
-      tests += [ "//jingle:jingle_unittests" ]
-    }
-
     cast_shell_browsertests_filter = {
       test_name = "cast_shell_browsertests"
 
@@ -484,25 +481,6 @@
   ]
 }
 
-if (is_fuchsia) {
-  fuchsia_package("cast_shell_pkg") {
-    binary = ":cast_shell"
-    package_name_override = "cast_shell"
-    manifest = "//chromecast/cast_shell.cmx"
-
-    if (chromecast_branding != "public") {
-      deps = [
-        "//chromecast/internal:fuchsia_internal_data_deps",
-      ]
-    }
-  }
-
-  fuchsia_package_runner("cast_shell_fuchsia") {
-    package = ":cast_shell_pkg"
-    package_name_override = "cast_shell"
-  }
-}
-
 repack("cast_shell_pak") {
   sources = [
     "$root_gen_dir/chromecast/app/shell_resources.pak",
diff --git a/chromecast/browser/webview/proto/webview.proto b/chromecast/browser/webview/proto/webview.proto
index e0932c0..fc9b49d 100644
--- a/chromecast/browser/webview/proto/webview.proto
+++ b/chromecast/browser/webview/proto/webview.proto
@@ -171,8 +171,44 @@
 }
 
 message NavigationRequestEvent {
+  reserved 6;  // Was previous_url (b/146374483)
+
+  // The URL the frame is navigating to. This may change during the navigation
+  // when encountering a server redirect.
   string url = 1;
+
+  // Whether the navigation is taking place in the main frame or in a subframe.
+  // This remains constant over the navigation lifetime.
   bool is_for_main_frame = 2;
+
+  //  False for browser-initiated navigations, including:
+  //  * any navigation initiated from the omnibox
+  //  * navigations via suggestions in browser UI
+  //  * navigations via browser UI: Ctrl-R, refresh/forward/back/home buttons
+  //  * using window.history.forward() or window.history.back()
+  //  * any other "explicit" URL navigations, e.g. bookmarks
+  bool is_renderer_initiated = 3;
+
+  // Whether the navigation happened without changing document. Examples of
+  // same document navigations are:
+  // * reference fragment navigations
+  // * pushState/replaceState
+  // * same page history navigation
+  bool is_same_document = 4;
+
+  // Whether the navigation was initiated by a user gesture. Note that this
+  // will be false for browser-initiated navigations.
+  bool has_user_gesture = 5;
+
+  // true if this navigation was initiated by a link click.
+  bool was_initiated_by_link_click = 7;
+
+  // Whether the navigation has encountered a server redirect or not.
+  bool was_server_redirect = 8;
+
+  // Whether the navigation is done using HTTP POST method. This may change
+  // during the navigation (e.g. after encountering a server redirect).
+  bool is_post = 9;
 }
 
 enum NavigationDecision {
diff --git a/chromecast/browser/webview/webview_controller.cc b/chromecast/browser/webview/webview_controller.cc
index 8d83a468..62f112bb 100644
--- a/chromecast/browser/webview/webview_controller.cc
+++ b/chromecast/browser/webview/webview_controller.cc
@@ -123,14 +123,27 @@
   }
 }
 
-void WebviewController::SendNavigationEvent(WebviewNavigationThrottle* throttle,
-                                            const GURL& gurl,
-                                            bool is_in_main_frame) {
+void WebviewController::SendNavigationEvent(
+    WebviewNavigationThrottle* throttle,
+    content::NavigationHandle* navigation_handle) {
   DCHECK(!current_navigation_throttle_);
+  DCHECK(navigation_handle);
   std::unique_ptr<webview::WebviewResponse> response =
       std::make_unique<webview::WebviewResponse>();
-  response->mutable_navigation_event()->set_url(gurl.spec());
-  response->mutable_navigation_event()->set_is_for_main_frame(is_in_main_frame);
+  auto* navigation_event = response->mutable_navigation_event();
+
+  navigation_event->set_url(navigation_handle->GetURL().GetContent());
+  navigation_event->set_is_for_main_frame(navigation_handle->IsInMainFrame());
+  navigation_event->set_is_renderer_initiated(
+      navigation_handle->IsRendererInitiated());
+  navigation_event->set_is_same_document(navigation_handle->IsSameDocument());
+  navigation_event->set_has_user_gesture(navigation_handle->HasUserGesture());
+  navigation_event->set_was_server_redirect(
+      navigation_handle->WasServerRedirect());
+  navigation_event->set_is_post(navigation_handle->IsPost());
+  navigation_event->set_was_initiated_by_link_click(
+      navigation_handle->WasInitiatedByLinkClick());
+
   current_navigation_throttle_ = throttle;
   client_->EnqueueSend(std::move(response));
 }
diff --git a/chromecast/browser/webview/webview_controller.h b/chromecast/browser/webview/webview_controller.h
index daa2eda1..ccf1b4d2d 100644
--- a/chromecast/browser/webview/webview_controller.h
+++ b/chromecast/browser/webview/webview_controller.h
@@ -53,9 +53,10 @@
   // Close the page. This will cause a stopped response to eventually be sent.
   void ClosePage();
 
+  // Dispatch a navigation request event with the information supplied in the
+  // navigation handle.
   void SendNavigationEvent(WebviewNavigationThrottle* throttle,
-                           const GURL& url,
-                           bool is_in_main_frame);
+                           content::NavigationHandle* navigation_handle);
 
  protected:
   content::WebContents* GetWebContents() override;
diff --git a/chromecast/browser/webview/webview_navigation_throttle.cc b/chromecast/browser/webview/webview_navigation_throttle.cc
index 1bfaa5c..254159a 100644
--- a/chromecast/browser/webview/webview_navigation_throttle.cc
+++ b/chromecast/browser/webview/webview_navigation_throttle.cc
@@ -15,15 +15,13 @@
     content::NavigationHandle* handle,
     WebviewController* controller)
     : NavigationThrottle(handle),
-      url_(handle->GetURL()),
-      is_in_main_frame_(handle->IsInMainFrame()),
       controller_(controller) {}
 
 WebviewNavigationThrottle::~WebviewNavigationThrottle() = default;
 
 content::NavigationThrottle::ThrottleCheckResult
 WebviewNavigationThrottle::WillStartRequest() {
-  controller_->SendNavigationEvent(this, url_, is_in_main_frame_);
+  controller_->SendNavigationEvent(this, navigation_handle());
 
   return content::NavigationThrottle::DEFER;
 }
diff --git a/chromecast/browser/webview/webview_navigation_throttle.h b/chromecast/browser/webview/webview_navigation_throttle.h
index 53d9e7b2..50cf02b 100644
--- a/chromecast/browser/webview/webview_navigation_throttle.h
+++ b/chromecast/browser/webview/webview_navigation_throttle.h
@@ -34,8 +34,6 @@
  private:
   scoped_refptr<base::SequencedTaskRunner> response_task_runner_;
 
-  const GURL url_;
-  bool is_in_main_frame_;
   WebviewController* controller_;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewNavigationThrottle);
diff --git a/chromecast/cast_shell.cmx b/chromecast/cast_shell.cmx
deleted file mode 100644
index 41d79ed..0000000
--- a/chromecast/cast_shell.cmx
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "sandbox": {
-    "features": [
-      "deprecated-ambient-replace-as-executable",
-      "isolated-persistent-storage",
-      "isolated-temp",
-      "root-ssl-certificates",
-      "vulkan"
-    ],
-    "dev": [
-      "null",
-      "zero"
-    ],
-    "services": [
-      "fuchsia.accessibility.semantics.SemanticsManager",
-      "fuchsia.bluetooth.gatt.Server",
-      "fuchsia.bluetooth.le.Peripheral",
-      "fuchsia.device.NameProvider",
-      "fuchsia.fonts.Provider",
-      "fuchsia.intl.PropertyProvider",
-      "fuchsia.media.Audio",
-      "fuchsia.mediacodec.CodecFactory",
-      "fuchsia.net.NameLookup",
-      "fuchsia.netstack.Netstack",
-      "fuchsia.posix.socket.Provider",
-      "fuchsia.process.Launcher",
-      "fuchsia.sys.Launcher",
-      "fuchsia.ui.input.ImeService",
-      "fuchsia.ui.input.ImeVisibilityService",
-      "fuchsia.ui.policy.Presenter",
-      "fuchsia.ui.scenic.Scenic",
-      "fuchsia.vulkan.loader.Loader",
-      "fuchsia.wlan.service.Wlan"
-    ]
-  }
-}
diff --git a/chromeos/components/BUILD.gn b/chromeos/components/BUILD.gn
index f2f1895..cd6b4ac 100644
--- a/chromeos/components/BUILD.gn
+++ b/chromeos/components/BUILD.gn
@@ -38,4 +38,8 @@
     "//chromeos/components/media_app_ui:closure_compile",
     "//chromeos/components/multidevice/debug_webui/resources:closure_compile",
   ]
+
+  if (!is_official_build) {
+    deps += [ "//chromeos/components/sample_system_web_app_ui:closure_compile" ]
+  }
 }
diff --git a/chromeos/components/sample_system_web_app_ui/BUILD.gn b/chromeos/components/sample_system_web_app_ui/BUILD.gn
new file mode 100644
index 0000000..f540fd78
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chrome/test/base/js2gtest.gni")
+
+assert(is_chromeos, "Sample System Web App is Chrome OS only")
+assert(!is_official_build,
+       "Sample System Web App is only built for unofficial builds")
+
+static_library("sample_system_web_app_ui") {
+  sources = [
+    "sample_system_web_app_ui.cc",
+    "sample_system_web_app_ui.h",
+    "url_constants.cc",
+    "url_constants.h",
+  ]
+
+  deps = [
+    "//chromeos/constants",
+    "//chromeos/resources:sample_system_web_app_resources",
+    "//content/public/browser",
+    "//ui/webui",
+  ]
+}
+
+group("closure_compile") {
+  deps = [
+    "resources/js:closure_compile",
+  ]
+}
+
+js2gtest("browser_tests_js") {
+  test_type = "mojo_lite_webui"
+
+  sources = [
+    "test/sample_system_web_app_ui_browsertest.js",
+  ]
+
+  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+}
diff --git a/chromeos/components/sample_system_web_app_ui/DEPS b/chromeos/components/sample_system_web_app_ui/DEPS
new file mode 100644
index 0000000..cc796cc2
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+  # Do not add chrome here (use a delegate instead).
+  "+chromeos/grit/chromeos_sample_system_web_app_resources.h",
+  "+content/public/browser",
+  "+ui/webui",
+]
diff --git a/chromeos/components/sample_system_web_app_ui/OWNERS b/chromeos/components/sample_system_web_app_ui/OWNERS
new file mode 100644
index 0000000..78bdf18
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/OWNERS
@@ -0,0 +1,4 @@
+ortuno@chromium.org
+calamity@chromium.org
+
+# COMPONENT: Platform>Apps>SystemWebApps
diff --git a/chromeos/components/sample_system_web_app_ui/resources/index.html b/chromeos/components/sample_system_web_app_ui/resources/index.html
new file mode 100644
index 0000000..203da33
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/resources/index.html
@@ -0,0 +1,9 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Sample System App</title>
+<h1 id="header">Sample System Web App</h1>
+<!-- Below mojo script required to run browser tests -->
+<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
diff --git a/chromeos/components/sample_system_web_app_ui/resources/js/BUILD.gn b/chromeos/components/sample_system_web_app_ui/resources/js/BUILD.gn
new file mode 100644
index 0000000..9d29a97
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/resources/js/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":app",
+  ]
+}
+
+js_library("app") {
+}
diff --git a/chromeos/components/sample_system_web_app_ui/resources/js/app.js b/chromeos/components/sample_system_web_app_ui/resources/js/app.js
new file mode 100644
index 0000000..25e147c0
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/resources/js/app.js
@@ -0,0 +1,6 @@
+// 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.
+
+var header = document.getElementById('header');
+header.textContent = 'Sample System Web App';
diff --git a/chromeos/components/sample_system_web_app_ui/resources/sample_system_web_app_resources.grd b/chromeos/components/sample_system_web_app_ui/resources/sample_system_web_app_resources.grd
new file mode 100644
index 0000000..f3f3802
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/resources/sample_system_web_app_resources.grd
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+  <outputs>
+    <output filename="grit/chromeos_sample_system_web_app_resources.h" type="rc_header">
+      <emit emit_type='prepend'></emit>
+    </output>
+    <output filename="grit/chromeos_sample_system_web_app_resources_map.cc"
+      type="resource_file_map_source" />
+    <output filename="grit/chromeos_sample_system_web_app_resources_map.h"
+      type="resource_map_header" />
+    <output filename="chromeos_sample_system_web_app_resources.pak" type="data_package" />
+  </outputs>
+  <release seq="1">
+    <includes>
+      <!-- Privileged app host contents. -->
+      <if expr="is_official_build == false">
+        <include name="IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML" file="index.html" type="BINDATA" compress="gzip" />
+        <include name="IDR_SAMPLE_SYSTEM_WEB_APP_JS" file="js/app.js" type="BINDATA" compress="gzip" />
+      </if>
+    </includes>
+  </release>
+</grit>
\ No newline at end of file
diff --git a/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.cc b/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.cc
new file mode 100644
index 0000000..98076052
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.cc
@@ -0,0 +1,39 @@
+// 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 "chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h"
+
+#include <memory>
+
+#include "chromeos/components/sample_system_web_app_ui/url_constants.h"
+#include "chromeos/grit/chromeos_sample_system_web_app_resources.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace chromeos {
+
+SampleSystemWebAppUI::SampleSystemWebAppUI(content::WebUI* web_ui)
+    : ui::MojoWebUIController(web_ui) {
+  auto html_source = base::WrapUnique(
+      content::WebUIDataSource::Create(kChromeUISampleSystemWebAppHost));
+
+  html_source->AddResourcePath("", IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
+  html_source->AddResourcePath("app.js", IDR_SAMPLE_SYSTEM_WEB_APP_JS);
+
+#if !DCHECK_IS_ON()
+  // If a user goes to an invalid url and non-DCHECK mode (DHECK = debug mode)
+  // is set, serve a default page so the user sees your default page instead
+  // of an unexpected error. But if DCHECK is set, the user will be a
+  // developer and be able to identify an error occurred.
+  html_source->SetDefaultResource(IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
+#endif  // !DCHECK_IS_ON()
+
+  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
+                                html_source.release());
+}
+
+SampleSystemWebAppUI::~SampleSystemWebAppUI() = default;
+
+}  // namespace chromeos
\ No newline at end of file
diff --git a/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h b/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h
new file mode 100644
index 0000000..bdf3263d
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/sample_system_web_app_ui.h
@@ -0,0 +1,27 @@
+// 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 "ui/webui/mojo_web_ui_controller.h"
+
+#ifndef CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_SAMPLE_SYSTEM_WEB_APP_UI_H_
+#define CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_SAMPLE_SYSTEM_WEB_APP_UI_H_
+
+#if defined(OFFICIAL_BUILD)
+#error Sample System Web App should only be included in unofficial builds.
+#endif
+
+namespace chromeos {
+
+// The WebUI for chrome://sample-system-web-app/.
+class SampleSystemWebAppUI : public ui::MojoWebUIController {
+ public:
+  explicit SampleSystemWebAppUI(content::WebUI* web_ui);
+  SampleSystemWebAppUI(const SampleSystemWebAppUI&) = delete;
+  SampleSystemWebAppUI& operator=(const SampleSystemWebAppUI&) = delete;
+  ~SampleSystemWebAppUI() override;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_SAMPLE_SYSTEM_WEB_APP_UI_H_
diff --git a/chromeos/components/sample_system_web_app_ui/test/DEPS b/chromeos/components/sample_system_web_app_ui/test/DEPS
new file mode 100644
index 0000000..ac5677f9
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/test/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  # Tests run in browser_tests, so can access things under chrome/test/base*.
+  "+chrome/test/base",
+]
diff --git a/chromeos/components/sample_system_web_app_ui/test/sample_system_web_app_ui_browsertest.js b/chromeos/components/sample_system_web_app_ui/test/sample_system_web_app_ui_browsertest.js
new file mode 100644
index 0000000..dd3d426
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/test/sample_system_web_app_ui_browsertest.js
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Test suite for chrome://sample-system-web-app.
+ */
+
+const HOST_ORIGIN = 'chrome://sample-system-web-app';
+
+var SampleSystemWebAppUIBrowserTest = class extends testing.Test {
+  /** @override */
+  get browsePreload() {
+    return HOST_ORIGIN;
+  }
+
+  /** @override */
+  get runAccessibilityChecks() {
+    return false;
+  }
+};
+
+// Tests that chrome://sample-system-web-app runs js file and that it goes
+// somewhere instead of 404ing or crashing.
+TEST_F('SampleSystemWebAppUIBrowserTest', 'HasChromeSchemeURL', () => {
+  const header = document.querySelector('h1');
+
+  assertEquals(header.innerText, 'Sample System Web App');
+  assertEquals(document.location.origin, HOST_ORIGIN);
+});
diff --git a/chromeos/components/sample_system_web_app_ui/url_constants.cc b/chromeos/components/sample_system_web_app_ui/url_constants.cc
new file mode 100644
index 0000000..449e3cfb
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/url_constants.cc
@@ -0,0 +1,11 @@
+// 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 "chromeos/components/sample_system_web_app_ui/url_constants.h"
+
+namespace chromeos {
+
+const char kChromeUISampleSystemWebAppHost[] = "sample-system-web-app";
+
+}  // namespace chromeos
diff --git a/chromeos/components/sample_system_web_app_ui/url_constants.h b/chromeos/components/sample_system_web_app_ui/url_constants.h
new file mode 100644
index 0000000..237c3fa
--- /dev/null
+++ b/chromeos/components/sample_system_web_app_ui/url_constants.h
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_URL_CONSTANTS_H_
+#define CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_URL_CONSTANTS_H_
+
+namespace chromeos {
+
+extern const char kChromeUISampleSystemWebAppHost[];
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_SAMPLE_SYSTEM_WEB_APP_UI_URL_CONSTANTS_H_
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc
index 9a87ef4c..3fb1e14 100644
--- a/chromeos/constants/chromeos_switches.cc
+++ b/chromeos/constants/chromeos_switches.cc
@@ -557,8 +557,7 @@
 }
 
 bool ShouldShowShelfHotseat() {
-  return base::FeatureList::IsEnabled(features::kShelfHotseat) ||
-         base::CommandLine::ForCurrentProcess()->HasSwitch(kShelfHotseat);
+  return base::FeatureList::IsEnabled(features::kShelfHotseat);
 }
 
 bool ShouldShowShelfHoverPreviews() {
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc
index a6b6c36..d156054 100644
--- a/chromeos/disks/disk_mount_manager.cc
+++ b/chromeos/disks/disk_mount_manager.cc
@@ -150,20 +150,20 @@
   void FormatMountedDevice(const std::string& mount_path,
                            FormatFileSystemType filesystem,
                            const std::string& label) override {
-    if (filesystem == FormatFileSystemType::kUnknown) {
-      LOG(ERROR) << "Unknown filesystem passed to FormatMountedDevice";
-      OnFormatCompleted(FORMAT_ERROR_UNSUPPORTED_FILESYSTEM, mount_path);
-      return;
-    }
-
     MountPointMap::const_iterator mount_point = mount_points_.find(mount_path);
     if (mount_point == mount_points_.end()) {
       LOG(ERROR) << "Mount point with path \"" << mount_path << "\" not found.";
-      OnFormatCompleted(FORMAT_ERROR_UNKNOWN, mount_path);
+      // We can't call OnFormatCompleted until |pending_format_changes_| has
+      // been populated.
+      NotifyFormatStatusUpdate(FORMAT_COMPLETED, FORMAT_ERROR_UNKNOWN,
+                               mount_path, label);
       return;
     }
 
     std::string device_path = mount_point->second.source_path;
+    const std::string filesystem_str = FormatFileSystemTypeToString(filesystem);
+    pending_format_changes_[device_path] = {filesystem_str, label};
+
     DiskMap::const_iterator disk = disks_.find(device_path);
     if (disk == disks_.end()) {
       LOG(ERROR) << "Device with path \"" << device_path << "\" not found.";
@@ -171,9 +171,14 @@
       return;
     }
     if (disk->second->is_read_only()) {
-      LOG(ERROR) << "Mount point with path \"" << mount_path
-                 << "\" is read-only.";
-      OnFormatCompleted(FORMAT_ERROR_DEVICE_NOT_ALLOWED, mount_path);
+      LOG(ERROR) << "Device with path \"" << device_path << "\" is read-only.";
+      OnFormatCompleted(FORMAT_ERROR_DEVICE_NOT_ALLOWED, device_path);
+      return;
+    }
+
+    if (filesystem == FormatFileSystemType::kUnknown) {
+      LOG(ERROR) << "Unknown filesystem passed to FormatMountedDevice";
+      OnFormatCompleted(FORMAT_ERROR_UNSUPPORTED_FILESYSTEM, device_path);
       return;
     }
 
@@ -188,11 +193,16 @@
     MountPointMap::const_iterator mount_point = mount_points_.find(mount_path);
     if (mount_point == mount_points_.end()) {
       LOG(ERROR) << "Mount point with path '" << mount_path << "' not found.";
-      OnRenameCompleted(RENAME_ERROR_UNKNOWN, mount_path);
+      // We can't call OnRenameCompleted until |pending_rename_changes_| has
+      // been populated.
+      NotifyRenameStatusUpdate(RENAME_COMPLETED, RENAME_ERROR_UNKNOWN,
+                               mount_path, volume_name);
       return;
     }
 
     std::string device_path = mount_point->second.source_path;
+    pending_rename_changes_[device_path] = volume_name;
+
     DiskMap::const_iterator iter = disks_.find(device_path);
     if (iter == disks_.end()) {
       LOG(ERROR) << "Device with path '" << device_path << "' not found.";
@@ -200,9 +210,8 @@
       return;
     }
     if (iter->second->is_read_only()) {
-      LOG(ERROR) << "Mount point with path '" << mount_path
-                 << "' is read-only.";
-      OnRenameCompleted(RENAME_ERROR_DEVICE_NOT_ALLOWED, mount_path);
+      LOG(ERROR) << "Device with path '" << device_path << "' is read-only.";
+      OnRenameCompleted(RENAME_ERROR_DEVICE_NOT_ALLOWED, device_path);
       return;
     }
 
@@ -554,28 +563,34 @@
     base::UmaHistogramEnumeration("FileBrowser.FormatFileSystemType",
                                   filesystem);
 
-    const std::string filesystem_str = FormatFileSystemTypeToString(filesystem);
-    pending_format_changes_[device_path] = {filesystem_str, label};
-
     cros_disks_client_->Format(
-        device_path, filesystem_str, label,
+        device_path, FormatFileSystemTypeToString(filesystem), label,
         base::BindOnce(&DiskMountManagerImpl::OnFormatStarted,
-                       weak_ptr_factory_.GetWeakPtr(), device_path));
+                       weak_ptr_factory_.GetWeakPtr(), device_path, label));
   }
 
   // Callback for Format.
-  void OnFormatStarted(const std::string& device_path, bool success) {
+  void OnFormatStarted(const std::string& device_path,
+                       const std::string& device_label,
+                       bool success) {
     if (!success) {
       OnFormatCompleted(FORMAT_ERROR_UNKNOWN, device_path);
       return;
     }
 
-    NotifyFormatStatusUpdate(FORMAT_STARTED, FORMAT_ERROR_NONE, device_path);
+    NotifyFormatStatusUpdate(FORMAT_STARTED, FORMAT_ERROR_NONE, device_path,
+                             device_label);
   }
 
   // CrosDisksClient::Observer override.
   void OnFormatCompleted(FormatError error_code,
                          const std::string& device_path) override {
+    std::string device_label;
+    auto pending_change = pending_format_changes_.find(device_path);
+    if (pending_change != pending_format_changes_.end()) {
+      device_label = pending_change->second.volume_name;
+    }
+
     auto iter = disks_.find(device_path);
 
     // disk might have been removed by now?
@@ -583,7 +598,6 @@
       Disk* disk = iter->second.get();
       DCHECK(disk);
 
-      auto pending_change = pending_format_changes_.find(device_path);
       if (pending_change != pending_format_changes_.end() &&
           error_code == FORMAT_ERROR_NONE) {
         disk->set_device_label(pending_change->second.volume_name);
@@ -593,7 +607,8 @@
 
     pending_format_changes_.erase(device_path);
 
-    NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path);
+    NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path,
+                             device_label);
   }
 
   void OnUnmountPathForRename(const std::string& device_path,
@@ -614,26 +629,35 @@
     DiskMap::const_iterator disk = disks_.find(device_path);
     DCHECK(disk != disks_.end() && disk->second->mount_path().empty());
 
-    pending_rename_changes_[device_path] = volume_name;
     cros_disks_client_->Rename(
         device_path, volume_name,
         base::BindOnce(&DiskMountManagerImpl::OnRenameStarted,
-                       weak_ptr_factory_.GetWeakPtr(), device_path));
+                       weak_ptr_factory_.GetWeakPtr(), device_path,
+                       volume_name));
   }
 
   // Callback for Rename.
-  void OnRenameStarted(const std::string& device_path, bool success) {
+  void OnRenameStarted(const std::string& device_path,
+                       const std::string& volume_name,
+                       bool success) {
     if (!success) {
       OnRenameCompleted(RENAME_ERROR_UNKNOWN, device_path);
       return;
     }
 
-    NotifyRenameStatusUpdate(RENAME_STARTED, RENAME_ERROR_NONE, device_path);
+    NotifyRenameStatusUpdate(RENAME_STARTED, RENAME_ERROR_NONE, device_path,
+                             volume_name);
   }
 
   // CrosDisksClient::Observer override.
   void OnRenameCompleted(RenameError error_code,
                          const std::string& device_path) override {
+    std::string device_label;
+    auto pending_change = pending_rename_changes_.find(device_path);
+    if (pending_change != pending_rename_changes_.end()) {
+      device_label = pending_change->second;
+    }
+
     auto iter = disks_.find(device_path);
 
     // disk might have been removed by now?
@@ -641,7 +665,6 @@
       Disk* disk = iter->second.get();
       DCHECK(disk);
 
-      auto pending_change = pending_rename_changes_.find(device_path);
       if (pending_change != pending_rename_changes_.end() &&
           error_code == RENAME_ERROR_NONE)
         disk->set_device_label(pending_change->second);
@@ -649,7 +672,8 @@
 
     pending_rename_changes_.erase(device_path);
 
-    NotifyRenameStatusUpdate(RENAME_COMPLETED, error_code, device_path);
+    NotifyRenameStatusUpdate(RENAME_COMPLETED, error_code, device_path,
+                             device_label);
   }
 
   // Callback for GetDeviceProperties.
@@ -814,16 +838,18 @@
 
   void NotifyFormatStatusUpdate(FormatEvent event,
                                 FormatError error_code,
-                                const std::string& device_path) {
+                                const std::string& device_path,
+                                const std::string& device_label) {
     for (auto& observer : observers_)
-      observer.OnFormatEvent(event, error_code, device_path);
+      observer.OnFormatEvent(event, error_code, device_path, device_label);
   }
 
   void NotifyRenameStatusUpdate(RenameEvent event,
                                 RenameError error_code,
-                                const std::string& device_path) {
+                                const std::string& device_path,
+                                const std::string& device_label) {
     for (auto& observer : observers_)
-      observer.OnRenameEvent(event, error_code, device_path);
+      observer.OnRenameEvent(event, error_code, device_path, device_label);
   }
 
   // Mount event change observers.
diff --git a/chromeos/disks/disk_mount_manager.h b/chromeos/disks/disk_mount_manager.h
index 4b3731e3..b8a54fa7 100644
--- a/chromeos/disks/disk_mount_manager.h
+++ b/chromeos/disks/disk_mount_manager.h
@@ -124,11 +124,13 @@
     // Called on format process events.
     virtual void OnFormatEvent(FormatEvent event,
                                FormatError error_code,
-                               const std::string& device_path) {}
+                               const std::string& device_path,
+                               const std::string& device_label) {}
     // Called on rename process events.
     virtual void OnRenameEvent(RenameEvent event,
                                RenameError error_code,
-                               const std::string& device_path) {}
+                               const std::string& device_path,
+                               const std::string& device_label) {}
 
    protected:
     ~Observer() override;
diff --git a/chromeos/disks/disk_mount_manager_unittest.cc b/chromeos/disks/disk_mount_manager_unittest.cc
index adbef6c..e77af8d5 100644
--- a/chromeos/disks/disk_mount_manager_unittest.cc
+++ b/chromeos/disks/disk_mount_manager_unittest.cc
@@ -249,23 +249,29 @@
   DiskMountManager::FormatEvent event;
   chromeos::FormatError error_code;
   std::string device_path;
+  std::string device_label;
 
   FormatEvent() = default;
   FormatEvent(DiskMountManager::FormatEvent event,
               chromeos::FormatError error_code,
-              const std::string& device_path)
-      : event(event), error_code(error_code), device_path(device_path) {}
+              const std::string& device_path,
+              const std::string& device_label)
+      : event(event),
+        error_code(error_code),
+        device_path(device_path),
+        device_label(device_label) {}
 
   ObserverEventType type() const override { return FORMAT_EVENT; }
 
   bool operator==(const FormatEvent& other) const {
     return event == other.event && error_code == other.error_code &&
-           device_path == other.device_path;
+           device_path == other.device_path &&
+           device_label == other.device_label;
   }
 
   std::string DebugString() const {
-    return StringPrintf("OnFormatEvent(%d, %d, %s)", event, error_code,
-                        device_path.c_str());
+    return StringPrintf("OnFormatEvent(%d, %d, %s, %s)", event, error_code,
+                        device_path.c_str(), device_label.c_str());
   }
 };
 
@@ -274,22 +280,28 @@
   DiskMountManager::RenameEvent event;
   chromeos::RenameError error_code;
   std::string device_path;
+  std::string device_label;
 
   RenameEvent(DiskMountManager::RenameEvent event,
               chromeos::RenameError error_code,
-              const std::string& device_path)
-      : event(event), error_code(error_code), device_path(device_path) {}
+              const std::string& device_path,
+              const std::string& device_label)
+      : event(event),
+        error_code(error_code),
+        device_path(device_path),
+        device_label(device_label) {}
 
   ObserverEventType type() const override { return RENAME_EVENT; }
 
   bool operator==(const RenameEvent& other) const {
     return event == other.event && error_code == other.error_code &&
-           device_path == other.device_path;
+           device_path == other.device_path &&
+           device_label == other.device_label;
   }
 
   std::string DebugString() const {
-    return StringPrintf("OnRenameEvent(%d, %d, %s)", event, error_code,
-                        device_path.c_str());
+    return StringPrintf("OnRenameEvent(%d, %d, %s, %s)", event, error_code,
+                        device_path.c_str(), device_label.c_str());
   }
 };
 
@@ -359,16 +371,18 @@
 
   void OnFormatEvent(DiskMountManager::FormatEvent event,
                      chromeos::FormatError error_code,
-                     const std::string& device_path) override {
-    events_.push_back(
-        std::make_unique<FormatEvent>(event, error_code, device_path));
+                     const std::string& device_path,
+                     const std::string& device_label) override {
+    events_.push_back(std::make_unique<FormatEvent>(event, error_code,
+                                                    device_path, device_label));
   }
 
   void OnRenameEvent(DiskMountManager::RenameEvent event,
                      chromeos::RenameError error_code,
-                     const std::string& device_path) override {
-    events_.push_back(
-        std::make_unique<RenameEvent>(event, error_code, device_path));
+                     const std::string& device_path,
+                     const std::string& device_label) override {
+    events_.push_back(std::make_unique<RenameEvent>(event, error_code,
+                                                    device_path, device_label));
   }
 
   void OnMountEvent(
@@ -492,6 +506,11 @@
   return stream << format_event.DebugString();
 }
 
+std::ostream& operator<<(std::ostream& stream,
+                         const RenameEvent& rename_event) {
+  return stream << rename_event.DebugString();
+}
+
 class DiskMountManagerTest : public testing::Test {
  public:
   DiskMountManagerTest()
@@ -598,7 +617,8 @@
       "/mount/non_existent", kFormatFileSystemType1, kFormatLabel1);
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, "/mount/non_existent"),
+                        chromeos::FORMAT_ERROR_UNKNOWN, "/mount/non_existent",
+                        kFormatLabel1),
             observer_->GetFormatEvent(0));
 }
 
@@ -610,7 +630,7 @@
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
                         chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED,
-                        kReadOnlyDeviceMountPath),
+                        kReadOnlyDeviceSourcePath, kFormatLabel1),
             observer_->GetFormatEvent(0));
 }
 
@@ -620,7 +640,8 @@
       "/archive/mount_path", kFormatFileSystemType1, kFormatLabel1);
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, "/archive/source_path"),
+                        chromeos::FORMAT_ERROR_UNKNOWN, "/archive/source_path",
+                        kFormatLabel1),
             observer_->GetFormatEvent(0));
 }
 
@@ -649,7 +670,8 @@
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
+                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath,
+                        kFormatLabel1),
             observer_->GetFormatEvent(1));
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
   EXPECT_EQ(kDevice1MountPath,
@@ -684,7 +706,8 @@
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
+                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath,
+                        kFormatLabel1),
             observer_->GetFormatEvent(1));
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
@@ -737,11 +760,13 @@
   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
+                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath,
+                        kFormatLabel2),
             observer_->GetFormatEvent(1));
-  EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
-                        chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetFormatEvent(2));
+  EXPECT_EQ(
+      FormatEvent(DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
+                  kDevice1SourcePath, kFormatLabel1),
+      observer_->GetFormatEvent(2));
 
   EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
   EXPECT_EQ(kDevice1MountPath,
@@ -807,11 +832,13 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
                    chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
-  EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
-                        chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetFormatEvent(1));
+  EXPECT_EQ(
+      FormatEvent(DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
+                  kDevice1SourcePath, kFormatLabel1),
+      observer_->GetFormatEvent(1));
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
+                        chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath,
+                        kFormatLabel1),
             observer_->GetFormatEvent(2));
 }
 
@@ -852,11 +879,13 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
                    chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
-  EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
-                        chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetFormatEvent(1));
+  EXPECT_EQ(
+      FormatEvent(DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
+                  kDevice1SourcePath, kFormatLabel1),
+      observer_->GetFormatEvent(1));
   EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                        chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
+                        chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath,
+                        kFormatLabel1),
             observer_->GetFormatEvent(2));
 
   // Disk should have new values for file system type and device label name
@@ -931,13 +960,25 @@
   // simulated.
   EXPECT_EQ(7U, observer_->GetEventCount());
 
-  EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent(
-                    DiskMountManager::FORMAT_COMPLETED,
-                    chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath)));
+  EXPECT_EQ(1U,
+            observer_->CountFormatEvents(FormatEvent(
+                DiskMountManager::FORMAT_COMPLETED, chromeos::FORMAT_ERROR_NONE,
+                kDevice1SourcePath, kFormatLabel1)));
 
-  EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent(
-                    DiskMountManager::FORMAT_STARTED,
-                    chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath)));
+  EXPECT_EQ(1U,
+            observer_->CountFormatEvents(FormatEvent(
+                DiskMountManager::FORMAT_COMPLETED, chromeos::FORMAT_ERROR_NONE,
+                kDevice1SourcePath, kFormatLabel2)));
+
+  EXPECT_EQ(1U,
+            observer_->CountFormatEvents(FormatEvent(
+                DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
+                kDevice1SourcePath, kFormatLabel1)));
+
+  EXPECT_EQ(1U,
+            observer_->CountFormatEvents(FormatEvent(
+                DiskMountManager::FORMAT_STARTED, chromeos::FORMAT_ERROR_NONE,
+                kDevice1SourcePath, kFormatLabel2)));
 
   EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
                                             chromeos::MOUNT_ERROR_NONE,
@@ -1069,7 +1110,8 @@
                                                        "MYUSB");
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, "/mount/non_existent"),
+                        chromeos::RENAME_ERROR_UNKNOWN, "/mount/non_existent",
+                        "MYUSB"),
             observer_->GetRenameEvent(0));
 }
 
@@ -1081,7 +1123,7 @@
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
                         chromeos::RENAME_ERROR_DEVICE_NOT_ALLOWED,
-                        kReadOnlyDeviceMountPath),
+                        kReadOnlyDeviceSourcePath, "MYUSB"),
             observer_->GetRenameEvent(0));
 }
 
@@ -1091,7 +1133,8 @@
                                                        "MYUSB");
   ASSERT_EQ(1U, observer_->GetEventCount());
   EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, "/archive/source_path"),
+                        chromeos::RENAME_ERROR_UNKNOWN, "/archive/source_path",
+                        "MYUSB"),
             observer_->GetRenameEvent(0));
 }
 
@@ -1117,9 +1160,10 @@
   EXPECT_EQ(chromeos::MOUNT_ERROR_UNKNOWN, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath),
-            observer_->GetRenameEvent(1));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_COMPLETED,
+                  chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath, "MYUSB"),
+      observer_->GetRenameEvent(1));
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
   EXPECT_EQ(kDevice1MountPath,
             fake_cros_disks_client_->last_unmount_device_path());
@@ -1152,9 +1196,10 @@
   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
 
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath),
-            observer_->GetRenameEvent(1));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_COMPLETED,
+                  chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath, "MYUSB"),
+      observer_->GetRenameEvent(1));
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
   EXPECT_EQ(kDevice1MountPath,
@@ -1203,12 +1248,14 @@
   EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
   EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath),
-            observer_->GetRenameEvent(1));
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED,
-                        chromeos::RENAME_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetRenameEvent(2));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_COMPLETED,
+                  chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath, "MYUSB2"),
+      observer_->GetRenameEvent(1));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
+                  kDevice1SourcePath, "MYUSB1"),
+      observer_->GetRenameEvent(2));
 
   EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
   EXPECT_EQ(kDevice1MountPath,
@@ -1258,12 +1305,14 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
                    chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED,
-                        chromeos::RENAME_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetRenameEvent(1));
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath),
-            observer_->GetRenameEvent(2));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
+                  kDevice1SourcePath, "MYUSB"),
+      observer_->GetRenameEvent(1));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_COMPLETED,
+                  chromeos::RENAME_ERROR_UNKNOWN, kDevice1SourcePath, "MYUSB"),
+      observer_->GetRenameEvent(2));
 }
 
 // Tests the case when renaming completes successfully.
@@ -1300,12 +1349,14 @@
   ASSERT_EQ(3U, observer_->GetEventCount());
   VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
                    chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED,
-                        chromeos::RENAME_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetRenameEvent(1));
-  EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
-                        chromeos::RENAME_ERROR_NONE, kDevice1SourcePath),
-            observer_->GetRenameEvent(2));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
+                  kDevice1SourcePath, "MYUSB1"),
+      observer_->GetRenameEvent(1));
+  EXPECT_EQ(
+      RenameEvent(DiskMountManager::RENAME_COMPLETED,
+                  chromeos::RENAME_ERROR_NONE, kDevice1SourcePath, "MYUSB1"),
+      observer_->GetRenameEvent(2));
 
   // Disk should have new value for device label name
   EXPECT_EQ("MYUSB1", disks.find(kDevice1SourcePath)->second->device_label());
@@ -1379,13 +1430,23 @@
   // simulated.
   EXPECT_EQ(7U, observer_->GetEventCount());
 
-  EXPECT_EQ(2U, observer_->CountRenameEvents(RenameEvent(
-                    DiskMountManager::RENAME_COMPLETED,
-                    chromeos::RENAME_ERROR_NONE, kDevice1SourcePath)));
+  EXPECT_EQ(1U,
+            observer_->CountRenameEvents(RenameEvent(
+                DiskMountManager::RENAME_COMPLETED, chromeos::RENAME_ERROR_NONE,
+                kDevice1SourcePath, "MYUSB2")));
 
-  EXPECT_EQ(2U, observer_->CountRenameEvents(RenameEvent(
+  EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
+                    DiskMountManager::RENAME_COMPLETED,
+                    chromeos::RENAME_ERROR_NONE, kDevice1SourcePath, "MYUSB")));
+
+  EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
                     DiskMountManager::RENAME_STARTED,
-                    chromeos::RENAME_ERROR_NONE, kDevice1SourcePath)));
+                    chromeos::RENAME_ERROR_NONE, kDevice1SourcePath, "MYUSB")));
+
+  EXPECT_EQ(1U,
+            observer_->CountRenameEvents(RenameEvent(
+                DiskMountManager::RENAME_STARTED, chromeos::RENAME_ERROR_NONE,
+                kDevice1SourcePath, "MYUSB2")));
 
   EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
                                             chromeos::MOUNT_ERROR_NONE,
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt
index 5d641b1..7a67400 100644
--- a/chromeos/profiles/airmont.afdo.newest.txt
+++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-airmont-80-3987.0-1576496920-benchmark-80.0.3987.5-r1-redacted.afdo.xz
\ No newline at end of file
+chromeos-chrome-amd64-airmont-81-3987.0-1576494869-benchmark-81.0.3999.0-r1-redacted.afdo.xz
\ No newline at end of file
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt
index f94e64d..dcce0345 100644
--- a/chromeos/profiles/broadwell.afdo.newest.txt
+++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-broadwell-81-3945.83-1576492580-benchmark-80.0.3987.5-r1-redacted.afdo.xz
\ No newline at end of file
+chromeos-chrome-amd64-broadwell-81-3945.83-1576492580-benchmark-81.0.3999.0-r1-redacted.afdo.xz
\ No newline at end of file
diff --git a/chromeos/profiles/silvermont.afdo.newest.txt b/chromeos/profiles/silvermont.afdo.newest.txt
index 1fac362..8c44b61f 100644
--- a/chromeos/profiles/silvermont.afdo.newest.txt
+++ b/chromeos/profiles/silvermont.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-silvermont-80-3987.0-1576497572-benchmark-80.0.3987.5-r1-redacted.afdo.xz
\ No newline at end of file
+chromeos-chrome-amd64-silvermont-81-3987.0-1576497268-benchmark-81.0.3995.0-r1-redacted.afdo.xz
\ No newline at end of file
diff --git a/chromeos/resources/BUILD.gn b/chromeos/resources/BUILD.gn
index c109d16..c874b26 100644
--- a/chromeos/resources/BUILD.gn
+++ b/chromeos/resources/BUILD.gn
@@ -79,6 +79,21 @@
   output_dir = "$root_gen_dir/chromeos"
 }
 
+# Resources used by chrome://sample-system-web-app
+grit("sample_system_web_app_resources") {
+  source = "../components/sample_system_web_app_ui/resources/sample_system_web_app_resources.grd"
+
+  source_is_generated = true
+
+  outputs = [
+    "grit/chromeos_sample_system_web_app_resources.h",
+    "grit/chromeos_sample_system_web_app_resources_map.cc",
+    "grit/chromeos_sample_system_web_app_resources_map.h",
+    "chromeos_sample_system_web_app_resources.pak",
+  ]
+  output_dir = "$root_gen_dir/chromeos"
+}
+
 # Resources used by chrome://media-app, and parts of the sandboxed app it hosts
 # that do not come from the app bundle (below).
 grit("media_app_resources") {
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc
index 821232e..704be38 100644
--- a/chromeos/services/assistant/assistant_manager_service_impl.cc
+++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -98,6 +98,8 @@
 
 constexpr float kDefaultSliderStep = 0.1f;
 
+constexpr char kAndroidSettingsAppPackage[] = "com.android.settings";
+
 bool IsScreenContextAllowed(ash::AssistantStateBase* assistant_state) {
   return assistant_state->allowed_state() ==
              ash::mojom::AssistantAllowedState::ALLOWED &&
@@ -1330,6 +1332,10 @@
     std::vector<mojom::AndroidAppInfoPtr> apps_info) {
   std::vector<action::AndroidAppInfo> android_apps_info;
   for (const auto& app_info : apps_info) {
+    // TODO(b/146355799): Remove the special handling for Android settings app.
+    if (app_info->package_name == kAndroidSettingsAppPackage)
+      continue;
+
     android_apps_info.push_back({app_info->package_name, app_info->version,
                                  app_info->localized_app_name,
                                  app_info->intent});
diff --git a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.cc b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.cc
index 4218ad0..7b256fb 100644
--- a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.cc
+++ b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.cc
@@ -10,6 +10,66 @@
 namespace chromeos {
 
 namespace device_sync {
+FakeDeviceSyncClient::SetSoftwareFeatureStateInputs::
+    SetSoftwareFeatureStateInputs(
+        const std::string& public_key,
+        multidevice::SoftwareFeature software_feature,
+        bool enabled,
+        bool is_exclusive,
+        mojom::DeviceSync::SetSoftwareFeatureStateCallback callback)
+    : public_key(public_key),
+      software_feature(software_feature),
+      enabled(enabled),
+      is_exclusive(is_exclusive),
+      callback(std::move(callback)) {}
+
+FakeDeviceSyncClient::SetSoftwareFeatureStateInputs::
+    SetSoftwareFeatureStateInputs(SetSoftwareFeatureStateInputs&&) = default;
+
+FakeDeviceSyncClient::SetSoftwareFeatureStateInputs::
+    ~SetSoftwareFeatureStateInputs() = default;
+
+FakeDeviceSyncClient::SetFeatureStatusInputs::SetFeatureStatusInputs(
+    const std::string& device_instance_id,
+    multidevice::SoftwareFeature feature,
+    FeatureStatusChange status_change,
+    mojom::DeviceSync::SetFeatureStatusCallback callback)
+    : device_instance_id(device_instance_id),
+      feature(feature),
+      status_change(status_change),
+      callback(std::move(callback)) {}
+
+FakeDeviceSyncClient::SetFeatureStatusInputs::SetFeatureStatusInputs(
+    SetFeatureStatusInputs&&) = default;
+
+FakeDeviceSyncClient::SetFeatureStatusInputs::~SetFeatureStatusInputs() =
+    default;
+
+FakeDeviceSyncClient::FindEligibleDevicesInputs::FindEligibleDevicesInputs(
+    multidevice::SoftwareFeature software_feature,
+    FindEligibleDevicesCallback callback)
+    : software_feature(software_feature), callback(std::move(callback)) {}
+
+FakeDeviceSyncClient::FindEligibleDevicesInputs::FindEligibleDevicesInputs(
+    FindEligibleDevicesInputs&&) = default;
+
+FakeDeviceSyncClient::FindEligibleDevicesInputs::~FindEligibleDevicesInputs() =
+    default;
+
+FakeDeviceSyncClient::NotifyDevicesInputs::NotifyDevicesInputs(
+    const std::vector<std::string>& device_instance_ids,
+    cryptauthv2::TargetService target_service,
+    multidevice::SoftwareFeature feature,
+    mojom::DeviceSync::NotifyDevicesCallback callback)
+    : device_instance_ids(device_instance_ids),
+      target_service(target_service),
+      feature(feature),
+      callback(std::move(callback)) {}
+
+FakeDeviceSyncClient::NotifyDevicesInputs::NotifyDevicesInputs(
+    NotifyDevicesInputs&&) = default;
+
+FakeDeviceSyncClient::NotifyDevicesInputs::~NotifyDevicesInputs() = default;
 
 FakeDeviceSyncClient::FakeDeviceSyncClient() = default;
 
@@ -17,12 +77,12 @@
 
 void FakeDeviceSyncClient::ForceEnrollmentNow(
     mojom::DeviceSync::ForceEnrollmentNowCallback callback) {
-  force_enrollment_now_callback_queue_.push(std::move(callback));
+  force_enrollment_now_callback_queue_.push_back(std::move(callback));
 }
 
 void FakeDeviceSyncClient::ForceSyncNow(
     mojom::DeviceSync::ForceSyncNowCallback callback) {
-  force_sync_now_callback_queue_.push(std::move(callback));
+  force_sync_now_callback_queue_.push_back(std::move(callback));
 }
 
 multidevice::RemoteDeviceRefList FakeDeviceSyncClient::GetSyncedDevices() {
@@ -40,7 +100,8 @@
     bool enabled,
     bool is_exclusive,
     mojom::DeviceSync::SetSoftwareFeatureStateCallback callback) {
-  set_software_feature_state_callback_queue_.push(std::move(callback));
+  set_software_feature_state_inputs_queue_.emplace_back(
+      public_key, software_feature, enabled, is_exclusive, std::move(callback));
 }
 
 void FakeDeviceSyncClient::SetFeatureStatus(
@@ -48,13 +109,15 @@
     multidevice::SoftwareFeature feature,
     FeatureStatusChange status_change,
     mojom::DeviceSync::SetFeatureStatusCallback callback) {
-  set_feature_status_callback_queue_.push(std::move(callback));
+  set_feature_status_inputs_queue_.emplace_back(
+      device_instance_id, feature, status_change, std::move(callback));
 }
 
 void FakeDeviceSyncClient::FindEligibleDevices(
     multidevice::SoftwareFeature software_feature,
     FindEligibleDevicesCallback callback) {
-  find_eligible_devices_callback_queue_.push(std::move(callback));
+  find_eligible_devices_inputs_queue_.emplace_back(software_feature,
+                                                   std::move(callback));
 }
 
 void FakeDeviceSyncClient::NotifyDevices(
@@ -62,44 +125,45 @@
     cryptauthv2::TargetService target_service,
     multidevice::SoftwareFeature feature,
     mojom::DeviceSync::NotifyDevicesCallback callback) {
-  notify_devices_callback_queue_.push(std::move(callback));
+  notify_devices_inputs_queue_.emplace_back(device_instance_ids, target_service,
+                                            feature, std::move(callback));
 }
 
 void FakeDeviceSyncClient::GetDevicesActivityStatus(
     mojom::DeviceSync::GetDevicesActivityStatusCallback callback) {
-  get_devices_activity_status_callback_queue_.push(std::move(callback));
+  get_devices_activity_status_callback_queue_.push_back(std::move(callback));
 }
 
 void FakeDeviceSyncClient::GetDebugInfo(
     mojom::DeviceSync::GetDebugInfoCallback callback) {
-  get_debug_info_callback_queue_.push(std::move(callback));
+  get_debug_info_callback_queue_.push_back(std::move(callback));
 }
 
-int FakeDeviceSyncClient::GetForceEnrollmentNowCallbackQueueSize() {
+int FakeDeviceSyncClient::GetForceEnrollmentNowCallbackQueueSize() const {
   return force_enrollment_now_callback_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetForceSyncNowCallbackQueueSize() {
+int FakeDeviceSyncClient::GetForceSyncNowCallbackQueueSize() const {
   return force_sync_now_callback_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetSetSoftwareFeatureStateCallbackQueueSize() {
-  return set_software_feature_state_callback_queue_.size();
+int FakeDeviceSyncClient::GetSetSoftwareFeatureStateInputsQueueSize() const {
+  return set_software_feature_state_inputs_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetSetFeatureStatusCallbackQueueSize() {
-  return set_feature_status_callback_queue_.size();
+int FakeDeviceSyncClient::GetSetFeatureStatusInputsQueueSize() const {
+  return set_feature_status_inputs_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetFindEligibleDevicesCallbackQueueSize() {
-  return find_eligible_devices_callback_queue_.size();
+int FakeDeviceSyncClient::GetFindEligibleDevicesInputsQueueSize() const {
+  return find_eligible_devices_inputs_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetNotifyDevicesCallbackQueueSize() {
-  return notify_devices_callback_queue_.size();
+int FakeDeviceSyncClient::GetNotifyDevicesInputsQueueSize() const {
+  return notify_devices_inputs_queue_.size();
 }
 
-int FakeDeviceSyncClient::GetGetDebugInfoCallbackQueueSize() {
+int FakeDeviceSyncClient::GetGetDebugInfoCallbackQueueSize() const {
   return get_debug_info_callback_queue_.size();
 }
 
@@ -107,45 +171,45 @@
     bool success) {
   DCHECK(force_enrollment_now_callback_queue_.size() > 0);
   std::move(force_enrollment_now_callback_queue_.front()).Run(success);
-  force_enrollment_now_callback_queue_.pop();
+  force_enrollment_now_callback_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingForceSyncNowCallback(bool success) {
   DCHECK(force_sync_now_callback_queue_.size() > 0);
   std::move(force_sync_now_callback_queue_.front()).Run(success);
-  force_sync_now_callback_queue_.pop();
+  force_sync_now_callback_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingSetSoftwareFeatureStateCallback(
     mojom::NetworkRequestResult result_code) {
-  DCHECK(set_software_feature_state_callback_queue_.size() > 0);
-  std::move(set_software_feature_state_callback_queue_.front())
+  DCHECK(set_software_feature_state_inputs_queue_.size() > 0);
+  std::move(set_software_feature_state_inputs_queue_.front().callback)
       .Run(result_code);
-  set_software_feature_state_callback_queue_.pop();
+  set_software_feature_state_inputs_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingSetFeatureStatusCallback(
     mojom::NetworkRequestResult result_code) {
-  DCHECK(set_feature_status_callback_queue_.size() > 0);
-  std::move(set_feature_status_callback_queue_.front()).Run(result_code);
-  set_feature_status_callback_queue_.pop();
+  DCHECK(set_feature_status_inputs_queue_.size() > 0);
+  std::move(set_feature_status_inputs_queue_.front().callback).Run(result_code);
+  set_feature_status_inputs_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingFindEligibleDevicesCallback(
     mojom::NetworkRequestResult result_code,
     multidevice::RemoteDeviceRefList eligible_devices,
     multidevice::RemoteDeviceRefList ineligible_devices) {
-  DCHECK(find_eligible_devices_callback_queue_.size() > 0);
-  std::move(find_eligible_devices_callback_queue_.front())
+  DCHECK(find_eligible_devices_inputs_queue_.size() > 0);
+  std::move(find_eligible_devices_inputs_queue_.front().callback)
       .Run(result_code, eligible_devices, ineligible_devices);
-  find_eligible_devices_callback_queue_.pop();
+  find_eligible_devices_inputs_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingNotifyDevicesCallback(
     mojom::NetworkRequestResult result_code) {
-  DCHECK(notify_devices_callback_queue_.size() > 0);
-  std::move(notify_devices_callback_queue_.front()).Run(result_code);
-  notify_devices_callback_queue_.pop();
+  DCHECK(notify_devices_inputs_queue_.size() > 0);
+  std::move(notify_devices_inputs_queue_.front().callback).Run(result_code);
+  notify_devices_inputs_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingGetDevicesActivityStatusCallback(
@@ -155,7 +219,7 @@
   DCHECK(get_devices_activity_status_callback_queue_.size() > 0);
   std::move(get_devices_activity_status_callback_queue_.front())
       .Run(result_code, std::move(device_activity_status));
-  get_devices_activity_status_callback_queue_.pop();
+  get_devices_activity_status_callback_queue_.pop_front();
 }
 
 void FakeDeviceSyncClient::InvokePendingGetDebugInfoCallback(
@@ -163,7 +227,7 @@
   DCHECK(get_debug_info_callback_queue_.size() > 0);
   std::move(get_debug_info_callback_queue_.front())
       .Run(std::move(debug_info_ptr));
-  get_debug_info_callback_queue_.pop();
+  get_debug_info_callback_queue_.pop_front();
 }
 
 }  // namespace device_sync
diff --git a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
index dc4a41c6..e66e85f 100644
--- a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
+++ b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
@@ -6,11 +6,11 @@
 #define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_FAKE_DEVICE_SYNC_CLIENT_H_
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "chromeos/components/multidevice/remote_device_ref.h"
@@ -28,16 +28,92 @@
 // Test double implementation of DeviceSyncClient.
 class FakeDeviceSyncClient : public DeviceSyncClient {
  public:
+  struct SetSoftwareFeatureStateInputs {
+    SetSoftwareFeatureStateInputs(
+        const std::string& public_key,
+        multidevice::SoftwareFeature software_feature,
+        bool enabled,
+        bool is_exclusive,
+        mojom::DeviceSync::SetSoftwareFeatureStateCallback callback);
+    SetSoftwareFeatureStateInputs(SetSoftwareFeatureStateInputs&&);
+    ~SetSoftwareFeatureStateInputs();
+
+    const std::string public_key;
+    const multidevice::SoftwareFeature software_feature;
+    const bool enabled;
+    const bool is_exclusive;
+    mojom::DeviceSync::SetSoftwareFeatureStateCallback callback;
+  };
+
+  struct SetFeatureStatusInputs {
+    SetFeatureStatusInputs(
+        const std::string& device_instance_id,
+        multidevice::SoftwareFeature feature,
+        FeatureStatusChange status_change,
+        mojom::DeviceSync::SetFeatureStatusCallback callback);
+    SetFeatureStatusInputs(SetFeatureStatusInputs&&);
+    ~SetFeatureStatusInputs();
+
+    const std::string device_instance_id;
+    const multidevice::SoftwareFeature feature;
+    const FeatureStatusChange status_change;
+    mojom::DeviceSync::SetFeatureStatusCallback callback;
+  };
+
+  struct FindEligibleDevicesInputs {
+    FindEligibleDevicesInputs(multidevice::SoftwareFeature software_feature,
+                              FindEligibleDevicesCallback callback);
+    FindEligibleDevicesInputs(FindEligibleDevicesInputs&&);
+    ~FindEligibleDevicesInputs();
+
+    const multidevice::SoftwareFeature software_feature;
+    FindEligibleDevicesCallback callback;
+  };
+
+  struct NotifyDevicesInputs {
+    NotifyDevicesInputs(const std::vector<std::string>& device_instance_ids,
+                        cryptauthv2::TargetService target_service,
+                        multidevice::SoftwareFeature feature,
+                        mojom::DeviceSync::NotifyDevicesCallback callback);
+    NotifyDevicesInputs(NotifyDevicesInputs&&);
+    ~NotifyDevicesInputs();
+
+    const std::vector<std::string> device_instance_ids;
+    const cryptauthv2::TargetService target_service;
+    const multidevice::SoftwareFeature feature;
+    mojom::DeviceSync::NotifyDevicesCallback callback;
+  };
+
   FakeDeviceSyncClient();
   ~FakeDeviceSyncClient() override;
 
-  int GetForceEnrollmentNowCallbackQueueSize();
-  int GetForceSyncNowCallbackQueueSize();
-  int GetSetSoftwareFeatureStateCallbackQueueSize();
-  int GetSetFeatureStatusCallbackQueueSize();
-  int GetFindEligibleDevicesCallbackQueueSize();
-  int GetNotifyDevicesCallbackQueueSize();
-  int GetGetDebugInfoCallbackQueueSize();
+  const base::circular_deque<SetSoftwareFeatureStateInputs>&
+  set_software_feature_state_inputs_queue() const {
+    return set_software_feature_state_inputs_queue_;
+  }
+
+  const base::circular_deque<SetFeatureStatusInputs>&
+  set_feature_status_inputs_queue() const {
+    return set_feature_status_inputs_queue_;
+  }
+
+  const base::circular_deque<FindEligibleDevicesInputs>&
+  find_eligible_devices_inputs_queue() const {
+    return find_eligible_devices_inputs_queue_;
+  }
+
+  const base::circular_deque<NotifyDevicesInputs>& notify_devices_inputs_queue()
+      const {
+    return notify_devices_inputs_queue_;
+  }
+
+  int GetForceEnrollmentNowCallbackQueueSize() const;
+  int GetForceSyncNowCallbackQueueSize() const;
+  int GetSetSoftwareFeatureStateInputsQueueSize() const;
+  int GetSetFeatureStatusInputsQueueSize() const;
+  int GetFindEligibleDevicesInputsQueueSize() const;
+  int GetNotifyDevicesInputsQueueSize() const;
+  int GetGetDebugInfoCallbackQueueSize() const;
 
   void InvokePendingForceEnrollmentNowCallback(bool success);
   void InvokePendingForceSyncNowCallback(bool success);
@@ -103,20 +179,19 @@
   multidevice::RemoteDeviceRefList synced_devices_;
   base::Optional<multidevice::RemoteDeviceRef> local_device_metadata_;
 
-  std::queue<mojom::DeviceSync::ForceEnrollmentNowCallback>
+  base::circular_deque<mojom::DeviceSync::ForceEnrollmentNowCallback>
       force_enrollment_now_callback_queue_;
-  std::queue<mojom::DeviceSync::ForceSyncNowCallback>
+  base::circular_deque<mojom::DeviceSync::ForceSyncNowCallback>
       force_sync_now_callback_queue_;
-  std::queue<mojom::DeviceSync::SetSoftwareFeatureStateCallback>
-      set_software_feature_state_callback_queue_;
-  std::queue<mojom::DeviceSync::SetFeatureStatusCallback>
-      set_feature_status_callback_queue_;
-  std::queue<FindEligibleDevicesCallback> find_eligible_devices_callback_queue_;
-  std::queue<mojom::DeviceSync::NotifyDevicesCallback>
-      notify_devices_callback_queue_;
-  std::queue<mojom::DeviceSync::GetDevicesActivityStatusCallback>
+  base::circular_deque<SetSoftwareFeatureStateInputs>
+      set_software_feature_state_inputs_queue_;
+  base::circular_deque<SetFeatureStatusInputs> set_feature_status_inputs_queue_;
+  base::circular_deque<FindEligibleDevicesInputs>
+      find_eligible_devices_inputs_queue_;
+  base::circular_deque<NotifyDevicesInputs> notify_devices_inputs_queue_;
+  base::circular_deque<mojom::DeviceSync::GetDevicesActivityStatusCallback>
       get_devices_activity_status_callback_queue_;
-  std::queue<mojom::DeviceSync::GetDebugInfoCallback>
+  base::circular_deque<mojom::DeviceSync::GetDebugInfoCallback>
       get_debug_info_callback_queue_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeDeviceSyncClient);
diff --git a/chromeos/services/multidevice_setup/grandfathered_easy_unlock_host_disabler_unittest.cc b/chromeos/services/multidevice_setup/grandfathered_easy_unlock_host_disabler_unittest.cc
index 5690c2af..d9a7b83 100644
--- a/chromeos/services/multidevice_setup/grandfathered_easy_unlock_host_disabler_unittest.cc
+++ b/chromeos/services/multidevice_setup/grandfathered_easy_unlock_host_disabler_unittest.cc
@@ -147,7 +147,7 @@
             GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 
   fake_device_sync_client()->InvokePendingSetSoftwareFeatureStateCallback(
       device_sync::mojom::NetworkRequestResult::kSuccess);
@@ -180,7 +180,7 @@
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 // Situation #3:
@@ -208,7 +208,7 @@
             GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 
   fake_device_sync_client()->InvokePendingSetSoftwareFeatureStateCallback(
       device_sync::mojom::NetworkRequestResult::kSuccess);
@@ -228,7 +228,7 @@
             GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 // Situation #1 where device A is removed from list of synced devices:
@@ -252,7 +252,7 @@
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 // Situation #1 with failure:
@@ -272,12 +272,12 @@
 
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   fake_device_sync_client()->InvokePendingSetSoftwareFeatureStateCallback(
       device_sync::mojom::NetworkRequestResult::kInternalServerError);
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 
   EXPECT_EQ(test_devices()[0].GetDeviceId(),
             GetEasyUnlockHostIdToDisablePrefValue());
@@ -287,7 +287,7 @@
 
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 TEST_F(MultiDeviceSetupGrandfatheredEasyUnlockHostDisablerTest,
@@ -299,7 +299,7 @@
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 TEST_F(MultiDeviceSetupGrandfatheredEasyUnlockHostDisablerTest,
@@ -312,7 +312,7 @@
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 TEST_F(MultiDeviceSetupGrandfatheredEasyUnlockHostDisablerTest,
@@ -325,7 +325,7 @@
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 }
 
 // Simulate:
@@ -344,7 +344,7 @@
 
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   fake_device_sync_client()->InvokePendingSetSoftwareFeatureStateCallback(
       device_sync::mojom::NetworkRequestResult::kInternalServerError);
 
@@ -354,7 +354,7 @@
 
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   EXPECT_FALSE(mock_timer()->IsRunning());
   EXPECT_EQ(kNoDevice, GetEasyUnlockHostIdToDisablePrefValue());
 }
@@ -380,7 +380,7 @@
 
   EXPECT_EQ(
       2,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   EXPECT_EQ(test_devices()[1].GetDeviceId(),
             GetEasyUnlockHostIdToDisablePrefValue());
 
diff --git a/chromeos/services/multidevice_setup/host_backend_delegate_impl_unittest.cc b/chromeos/services/multidevice_setup/host_backend_delegate_impl_unittest.cc
index d221874..a9447af 100644
--- a/chromeos/services/multidevice_setup/host_backend_delegate_impl_unittest.cc
+++ b/chromeos/services/multidevice_setup/host_backend_delegate_impl_unittest.cc
@@ -127,10 +127,9 @@
 
   int GetSetHostNetworkRequestCallbackQueueSize() {
     return DoTestDevicesHaveInstanceIds()
-               ? fake_device_sync_client_
-                     ->GetSetFeatureStatusCallbackQueueSize()
+               ? fake_device_sync_client_->GetSetFeatureStatusInputsQueueSize()
                : fake_device_sync_client_
-                     ->GetSetSoftwareFeatureStateCallbackQueueSize();
+                     ->GetSetSoftwareFeatureStateInputsQueueSize();
   }
 
   void InvokePendingSetHostNetworkRequestCallback(
@@ -196,8 +195,10 @@
 
   void AttemptToSetMultiDeviceHostOnBackend(
       const base::Optional<multidevice::RemoteDeviceRef>& host_device) {
+    base::Optional<multidevice::RemoteDeviceRef> host_before_call =
+        delegate_->GetMultiDeviceHostFromBackend();
     bool attempting_to_set_host_which_already_exists =
-        host_device == delegate_->GetMultiDeviceHostFromBackend();
+        host_device == host_before_call;
     size_t num_pending_host_request_change_events_before_call =
         observer_->num_pending_host_request_changes();
     bool was_request_for_same_device_as_pending_request =
@@ -225,9 +226,15 @@
                 observer_->num_pending_host_request_changes());
     }
 
-    // TODO(khorimoto): Check that the parameters passed to
-    // |fake_device_sync_client_| are correct. Currently, FakeDeviceSyncClient
-    // does provide a mechanism for checking these parameters.
+    // Verify that the correct parameters were passed to
+    // SetSoftwareFeatureState() or SetFeatureStatus().
+    if (host_device) {
+      VerifyLatestSetHostNetworkRequest(*host_device, true /* should_enable */);
+    } else {
+      ASSERT_TRUE(host_before_call);
+      VerifyLatestSetHostNetworkRequest(*host_before_call,
+                                        false /* should_enable */);
+    }
   }
 
   void SetHostInDeviceSyncClient(
@@ -267,6 +274,40 @@
   }
 
  private:
+  void VerifyLatestSetHostNetworkRequest(
+      const multidevice::RemoteDeviceRef expected_host,
+      bool expected_should_enable) {
+    // Verify inputs to SetSoftwareFeatureState().
+    if (expected_host.instance_id().empty()) {
+      ASSERT_FALSE(
+          fake_device_sync_client_->set_software_feature_state_inputs_queue()
+              .empty());
+      const device_sync::FakeDeviceSyncClient::SetSoftwareFeatureStateInputs&
+          inputs = fake_device_sync_client_
+                       ->set_software_feature_state_inputs_queue()
+                       .back();
+      EXPECT_EQ(expected_host.public_key(), inputs.public_key);
+      EXPECT_EQ(multidevice::SoftwareFeature::kBetterTogetherHost,
+                inputs.software_feature);
+      EXPECT_EQ(expected_should_enable, inputs.enabled);
+      EXPECT_EQ(expected_should_enable, inputs.is_exclusive);
+      return;
+    }
+
+    // Verify inputs to SetFeatureStatus().
+    ASSERT_FALSE(
+        fake_device_sync_client_->set_feature_status_inputs_queue().empty());
+    const device_sync::FakeDeviceSyncClient::SetFeatureStatusInputs& inputs =
+        fake_device_sync_client_->set_feature_status_inputs_queue().back();
+    EXPECT_EQ(expected_host.instance_id(), inputs.device_instance_id);
+    EXPECT_EQ(multidevice::SoftwareFeature::kBetterTogetherHost,
+              inputs.feature);
+    EXPECT_EQ(expected_should_enable
+                  ? device_sync::FeatureStatusChange::kEnableExclusively
+                  : device_sync::FeatureStatusChange::kDisable,
+              inputs.status_change);
+  }
+
   multidevice::RemoteDeviceRefList test_devices_;
 
   std::unique_ptr<FakeEligibleHostDevicesProvider>
@@ -303,7 +344,7 @@
   EXPECT_FALSE(delegate()->HasPendingHostRequest());
   EXPECT_EQ(test_devices()[0], delegate()->GetMultiDeviceHostFromBackend());
 
-  // Remove device 0 such that there is no longer a host..
+  // Remove device 0 such that there is no longer a host.
   AttemptToSetMultiDeviceHostOnBackend(base::nullopt);
   EXPECT_EQ(1, GetSetHostNetworkRequestCallbackQueueSize());
   InvokePendingSetHostNetworkRequestCallback(
@@ -634,8 +675,7 @@
   EXPECT_TRUE(delegate()->HasPendingHostRequest());
   EXPECT_EQ(test_devices()[0], delegate()->GetPendingHostRequest());
   EXPECT_EQ(base::nullopt, delegate()->GetMultiDeviceHostFromBackend());
-  EXPECT_EQ(1,
-            fake_device_sync_client()->GetSetFeatureStatusCallbackQueueSize());
+  EXPECT_EQ(1, fake_device_sync_client()->GetSetFeatureStatusInputsQueueSize());
 
   // Now, attempt to set device 1, which does not have an Instance ID. Device 1
   // is now the pending host, but no SetSoftwareFeatureState call was made since
@@ -646,7 +686,7 @@
   EXPECT_EQ(base::nullopt, delegate()->GetMultiDeviceHostFromBackend());
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
 
   // Fire the callback for device 0 and have it succeed. This should affect the
   // value of GetMultiDeviceHostFromBackend(); however, because device 0 is not
@@ -657,11 +697,10 @@
   // HostBackendDelegate implementation.
   fake_device_sync_client()->InvokePendingSetFeatureStatusCallback(
       device_sync::mojom::NetworkRequestResult::kSuccess);
-  EXPECT_EQ(0,
-            fake_device_sync_client()->GetSetFeatureStatusCallbackQueueSize());
+  EXPECT_EQ(0, fake_device_sync_client()->GetSetFeatureStatusInputsQueueSize());
   EXPECT_EQ(
       1,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   SimulateNewHostDevicesSynced(test_devices()[0] /* host_device_after_sync */,
                                false /* expected_to_fulfill_pending_request */);
   EXPECT_TRUE(delegate()->HasPendingHostRequest());
@@ -671,11 +710,10 @@
   // Fire the callback for device 1, and have it succeed.
   fake_device_sync_client()->InvokePendingSetSoftwareFeatureStateCallback(
       device_sync::mojom::NetworkRequestResult::kSuccess);
-  EXPECT_EQ(0,
-            fake_device_sync_client()->GetSetFeatureStatusCallbackQueueSize());
+  EXPECT_EQ(0, fake_device_sync_client()->GetSetFeatureStatusInputsQueueSize());
   EXPECT_EQ(
       0,
-      fake_device_sync_client()->GetSetSoftwareFeatureStateCallbackQueueSize());
+      fake_device_sync_client()->GetSetSoftwareFeatureStateInputsQueueSize());
   SimulateNewHostDevicesSynced(test_devices()[1] /* host_device_after_sync */,
                                true /* expected_to_fulfill_pending_request */);
   EXPECT_FALSE(delegate()->HasPendingHostRequest());
diff --git a/chromeos/services/multidevice_setup/host_verifier_impl.cc b/chromeos/services/multidevice_setup/host_verifier_impl.cc
index a09a6c5..54729e5 100644
--- a/chromeos/services/multidevice_setup/host_verifier_impl.cc
+++ b/chromeos/services/multidevice_setup/host_verifier_impl.cc
@@ -13,6 +13,7 @@
 #include "base/no_destructor.h"
 #include "chromeos/components/multidevice/logging/logging.h"
 #include "chromeos/components/multidevice/software_feature.h"
+#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 
diff --git a/chromeos/services/multidevice_setup/host_verifier_impl_unittest.cc b/chromeos/services/multidevice_setup/host_verifier_impl_unittest.cc
index 48dc3b4..b7d0597f 100644
--- a/chromeos/services/multidevice_setup/host_verifier_impl_unittest.cc
+++ b/chromeos/services/multidevice_setup/host_verifier_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "chromeos/components/multidevice/remote_device_test_util.h"
 #include "chromeos/components/multidevice/software_feature.h"
 #include "chromeos/components/multidevice/software_feature_state.h"
+#include "chromeos/services/device_sync/proto/cryptauth_common.pb.h"
 #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h"
 #include "chromeos/services/multidevice_setup/fake_host_backend_delegate.h"
 #include "chromeos/services/multidevice_setup/fake_host_verifier.h"
@@ -151,6 +152,12 @@
 
   void InvokePendingDeviceNotificationCall(bool success) {
     if (test_device_.instance_id().empty()) {
+      // Verify input parameters to FindEligibleDevices().
+      EXPECT_EQ(multidevice::SoftwareFeature::kBetterTogetherHost,
+                fake_device_sync_client_->find_eligible_devices_inputs_queue()
+                    .front()
+                    .software_feature);
+
       fake_device_sync_client_->InvokePendingFindEligibleDevicesCallback(
           success
               ? device_sync::mojom::NetworkRequestResult::kSuccess
@@ -160,6 +167,20 @@
       return;
     }
 
+    // Verify input parameters to NotifyDevices().
+    EXPECT_EQ(std::vector<std::string>{test_device_.instance_id()},
+              fake_device_sync_client_->notify_devices_inputs_queue()
+                  .front()
+                  .device_instance_ids);
+    EXPECT_EQ(cryptauthv2::TargetService::DEVICE_SYNC,
+              fake_device_sync_client_->notify_devices_inputs_queue()
+                  .front()
+                  .target_service);
+    EXPECT_EQ(multidevice::SoftwareFeature::kBetterTogetherHost,
+              fake_device_sync_client_->notify_devices_inputs_queue()
+                  .front()
+                  .feature);
+
     fake_device_sync_client_->InvokePendingNotifyDevicesCallback(
         success
             ? device_sync::mojom::NetworkRequestResult::kSuccess
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
index eca5e53..d37b540 100644
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -15,6 +15,7 @@
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/payments/payments_service_url.h"
+#include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_handle.h"
@@ -62,6 +63,14 @@
 // static
 ContentAutofillDriver* ContentAutofillDriver::GetForRenderFrameHost(
     content::RenderFrameHost* render_frame_host) {
+  // With back-forward cache, the page stays alive and its mojo connections are
+  // not closed. The page would be frozen and would eventually stop doing work,
+  // but the messages can still arrive when the frame is not active. Given that
+  // autofill logic can show popups, it's problematic - prevent pages using
+  // autofill from entering back-forward cache for now to avoid it.
+  content::BackForwardCache::DisableForRenderFrameHost(
+      render_frame_host, "autofill::ContentAutofillDriver");
+
   ContentAutofillDriverFactory* factory =
       ContentAutofillDriverFactory::FromWebContents(
           content::WebContents::FromRenderFrameHost(render_frame_host));
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc
index a34b85e..35e691af 100644
--- a/components/autofill/content/browser/content_autofill_driver_factory.cc
+++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -112,9 +112,10 @@
 
   // ContentAutofillDriver are created on demand here.
   if (!driver) {
-    AddForKey(render_frame_host,
-              base::Bind(CreateDriver, render_frame_host, client(), app_locale_,
-                         enable_download_manager_, provider_));
+    AddForKey(
+        render_frame_host,
+        base::BindRepeating(CreateDriver, render_frame_host, client(),
+                            app_locale_, enable_download_manager_, provider_));
     driver = DriverForKey(render_frame_host);
   }
 
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 9815b85..d4a02d1 100644
--- a/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -57,7 +57,9 @@
                              std::move(handle)));
   }
 
-  void SetQuitLoopClosure(base::Closure closure) { quit_closure_ = closure; }
+  void SetQuitLoopClosure(base::OnceClosure closure) {
+    quit_closure_ = std::move(closure);
+  }
 
   // Returns the id and formdata received via
   // mojo interface method mojom::AutofillAgent::FillForm().
@@ -143,10 +145,8 @@
 
  private:
   void CallDone() {
-    if (!quit_closure_.is_null()) {
-      quit_closure_.Run();
-      quit_closure_.Reset();
-    }
+    if (!quit_closure_.is_null())
+      std::move(quit_closure_).Run();
   }
 
   // mojom::AutofillAgent:
@@ -221,7 +221,7 @@
 
   mojo::AssociatedReceiverSet<mojom::AutofillAgent> receivers_;
 
-  base::Closure quit_closure_;
+  base::OnceClosure quit_closure_;
 
   // Records data received from FillForm() call.
   int32_t fill_form_id_;
diff --git a/components/autofill/content/browser/key_press_handler_manager_unittest.cc b/components/autofill/content/browser/key_press_handler_manager_unittest.cc
index 601c895..f1d8fad 100644
--- a/components/autofill/content/browser/key_press_handler_manager_unittest.cc
+++ b/components/autofill/content/browser/key_press_handler_manager_unittest.cc
@@ -57,7 +57,7 @@
  protected:
   content::RenderWidgetHost::KeyPressEventCallback CallbackForName(
       const char* name) {
-    return base::Bind(DummyHandler, name, &callback_trace_);
+    return base::BindRepeating(DummyHandler, name, &callback_trace_);
   }
 
   // String encoding the events related to adding and removing callbacks. For
diff --git a/components/autofill/content/browser/risk/fingerprint_browsertest.cc b/components/autofill/content/browser/risk/fingerprint_browsertest.cc
index 295ffc3..3ee659f 100644
--- a/components/autofill/content/browser/risk/fingerprint_browsertest.cc
+++ b/components/autofill/content/browser/risk/fingerprint_browsertest.cc
@@ -211,8 +211,8 @@
       "25.0.0.123", kCharset, kAcceptLanguages, AutofillClock::Now(), kLocale,
       kUserAgent,
       base::TimeDelta::FromDays(1),  // Ought to be longer than any test run.
-      base::Bind(&AutofillRiskFingerprintTest::GetFingerprintTestCallback,
-                 base::Unretained(this), run_loop.QuitWhenIdleClosure()));
+      base::BindOnce(&AutofillRiskFingerprintTest::GetFingerprintTestCallback,
+                     base::Unretained(this), run_loop.QuitWhenIdleClosure()));
 
   // Wait for the callback to be called.
   run_loop.Run();
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index e372068..eafd262e 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -149,8 +149,8 @@
   render_frame->GetWebFrame()->SetAutofillClient(this);
   password_autofill_agent->SetAutofillAgent(this);
   AddFormObserver(this);
-  registry->AddInterface(
-      base::Bind(&AutofillAgent::BindPendingReceiver, base::Unretained(this)));
+  registry->AddInterface(base::BindRepeating(
+      &AutofillAgent::BindPendingReceiver, base::Unretained(this)));
 }
 
 AutofillAgent::~AutofillAgent() {
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 0b7bdae89..070440c 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -424,8 +424,8 @@
       checked_safe_browsing_reputation_(false),
       focus_state_notifier_(this),
       password_generation_agent_(nullptr) {
-  registry->AddInterface(base::Bind(&PasswordAutofillAgent::BindPendingReceiver,
-                                    base::Unretained(this)));
+  registry->AddInterface(base::BindRepeating(
+      &PasswordAutofillAgent::BindPendingReceiver, base::Unretained(this)));
 }
 
 PasswordAutofillAgent::~PasswordAutofillAgent() {
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h
index 3d8226bf..7962ef3 100644
--- a/components/autofill/core/browser/autofill_client.h
+++ b/components/autofill/core/browser/autofill_client.h
@@ -202,7 +202,7 @@
       const UserProvidedCardDetails& user_provided_card_details)>
       UploadSaveCardPromptCallback;
 
-  typedef base::Callback<void(const CreditCard&)> CreditCardScanCallback;
+  typedef base::OnceCallback<void(const CreditCard&)> CreditCardScanCallback;
 
   // Callback to run if user presses the Save button in the migration dialog.
   // Will pass a vector of GUIDs of cards that the user selected to upload to
@@ -344,6 +344,13 @@
   virtual void ConfirmSaveUpiIdLocally(
       const std::string& upi_id,
       base::OnceCallback<void(bool user_decision)> callback) = 0;
+
+  // Shows the dialog including all credit cards that are available to be used
+  // as a virtual card. |candidates| must not be empty and has at least one
+  // card. Runs |callback| when a card is selected.
+  virtual void OfferVirtualCardOptions(
+      const std::vector<CreditCard*>& candidates,
+      base::OnceCallback<void(const std::string&)> callback) = 0;
 #endif
 
   // Runs |callback| if the |profile| should be imported as personal data.
@@ -408,7 +415,7 @@
   // Shows the user interface for scanning a credit card. Invokes the |callback|
   // when a credit card is scanned successfully. Should be called only if
   // HasCreditCardScanFeature() returns true.
-  virtual void ScanCreditCard(const CreditCardScanCallback& callback) = 0;
+  virtual void ScanCreditCard(CreditCardScanCallback callback) = 0;
 
   // Shows an Autofill popup with the given |values|, |labels|, |icons|, and
   // |identifiers| for the element at |element_bounds|. |delegate| will be
diff --git a/components/autofill/core/browser/autofill_driver_factory.cc b/components/autofill/core/browser/autofill_driver_factory.cc
index 58ec815..7009de2d 100644
--- a/components/autofill/core/browser/autofill_driver_factory.cc
+++ b/components/autofill/core/browser/autofill_driver_factory.cc
@@ -30,7 +30,8 @@
 
 void AutofillDriverFactory::AddForKey(
     void* key,
-    base::Callback<std::unique_ptr<AutofillDriver>()> factory_method) {
+    const base::RepeatingCallback<std::unique_ptr<AutofillDriver>()>&
+        factory_method) {
   auto insertion_result = driver_map_.insert(std::make_pair(key, nullptr));
   // This can be called twice for the key representing the main frame.
   if (insertion_result.second) {
diff --git a/components/autofill/core/browser/autofill_driver_factory.h b/components/autofill/core/browser/autofill_driver_factory.h
index 0c1a0a106..07767b5 100644
--- a/components/autofill/core/browser/autofill_driver_factory.h
+++ b/components/autofill/core/browser/autofill_driver_factory.h
@@ -45,7 +45,8 @@
   // end up notifying the driver that a user gesture has been observed.
   void AddForKey(
       void* key,
-      base::Callback<std::unique_ptr<AutofillDriver>()> factory_method);
+      const base::RepeatingCallback<std::unique_ptr<AutofillDriver>()>&
+          factory_method);
 
   // Deletes the AutofillDriver for |key|.
   void DeleteForKey(void* key);
diff --git a/components/autofill/core/browser/autofill_driver_factory_unittest.cc b/components/autofill/core/browser/autofill_driver_factory_unittest.cc
index 48ccf45..bd0fb6e 100644
--- a/components/autofill/core/browser/autofill_driver_factory_unittest.cc
+++ b/components/autofill/core/browser/autofill_driver_factory_unittest.cc
@@ -93,9 +93,10 @@
     return std::make_unique<CountingAutofillDriver>(instance_counter_.val());
   }
 
-  base::Callback<std::unique_ptr<AutofillDriver>()> CreateDriverCallback() {
-    return base::Bind(&AutofillDriverFactoryTest::CreateDriver,
-                      base::Unretained(this));
+  base::RepeatingCallback<std::unique_ptr<AutofillDriver>()>
+  CreateDriverCallback() {
+    return base::BindRepeating(&AutofillDriverFactoryTest::CreateDriver,
+                               base::Unretained(this));
   }
 
  protected:
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index dd2bd38..e4dbc98 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -262,13 +262,4 @@
 #endif
 }
 
-bool ShouldUseActiveSignedInAccount() {
-  // If butter is enabled or the feature to get the Payment Identity from Sync
-  // is enabled, the account of the active signed-in user should be used.
-  return base::FeatureList::IsEnabled(
-             features::kAutofillEnableAccountWalletStorage) ||
-         base::FeatureList::IsEnabled(
-             features::kAutofillGetPaymentsIdentityFromSync);
-}
-
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h
index b1280e74..88d3fc5c 100644
--- a/components/autofill/core/browser/autofill_experiments.h
+++ b/components/autofill/core/browser/autofill_experiments.h
@@ -53,9 +53,6 @@
 // response of the option.
 bool OfferStoreUnmaskedCards(bool is_off_the_record);
 
-// Returns whether the account of the active signed-in user should be used.
-bool ShouldUseActiveSignedInAccount();
-
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/components/autofill/core/browser/autofill_experiments_unittest.cc b/components/autofill/core/browser/autofill_experiments_unittest.cc
index 353901b..47c3f1b 100644
--- a/components/autofill/core/browser/autofill_experiments_unittest.cc
+++ b/components/autofill/core/browser/autofill_experiments_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/autofill_experiments.h"
 
+#include "base/bind_helpers.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
@@ -27,7 +28,7 @@
   void SetUp() override {
     pref_service_.registry()->RegisterBooleanPref(
         prefs::kAutofillWalletImportEnabled, true);
-    log_manager_ = LogManager::Create(nullptr, base::Closure());
+    log_manager_ = LogManager::Create(nullptr, base::NullCallback());
   }
 
   bool IsCreditCardUploadEnabled(const AutofillSyncSigninState sync_state) {
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index a0cca62..caa56823 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -239,7 +239,7 @@
     AutofillMetrics::LogAutocompleteSuggestionAcceptedIndex(position);
     manager_->OnAutocompleteEntrySelected(value);
   } else if (identifier == POPUP_ITEM_ID_SCAN_CREDIT_CARD) {
-    manager_->client()->ScanCreditCard(base::Bind(
+    manager_->client()->ScanCreditCard(base::BindOnce(
         &AutofillExternalDelegate::OnCreditCardScanned, GetWeakPtr()));
   } else if (identifier == POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO) {
     manager_->client()->ExecuteCommand(identifier);
@@ -248,6 +248,12 @@
   } else if (identifier == POPUP_ITEM_ID_HIDE_AUTOFILL_SUGGESTIONS) {
     // No-op as the popup will be closed in the end of the method.
     manager_->OnUserHideSuggestions(query_form_, query_field_);
+  } else if (identifier == POPUP_ITEM_ID_USE_VIRTUAL_CARD) {
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+    manager_->FetchVirtualCardCandidates();
+#else
+    NOTREACHED();
+#endif
   } else {
     if (identifier > 0) {  // Denotes an Autofill suggestion.
       AutofillMetrics::LogAutofillSuggestionAcceptedIndex(
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index d860778..de0959e 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -69,7 +69,7 @@
  public:
   MockAutofillClient() {}
 
-  MOCK_METHOD1(ScanCreditCard, void(const CreditCardScanCallback& callbacK));
+  MOCK_METHOD1(ScanCreditCard, void(CreditCardScanCallback callbacK));
 
   MOCK_METHOD6(ShowAutofillPopup,
                void(const gfx::RectF& element_bounds,
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index c469aa7b..7801bc0 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -12,6 +12,7 @@
 #include <map>
 #include <memory>
 #include <set>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -359,6 +360,39 @@
                      });
 }
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+// Retrieves all valid credit card candidates for virtual card selection. A
+// valid candidate must have exactly one cloud token.
+std::vector<CreditCard*> GetVirtualCardCandidates(
+    PersonalDataManager* personal_data_manager) {
+  DCHECK(personal_data_manager);
+  std::vector<CreditCard*> candidates =
+      personal_data_manager->GetServerCreditCards();
+  const std::vector<CreditCardCloudTokenData*> cloud_token_data =
+      personal_data_manager->GetCreditCardCloudTokenData();
+
+  // Constructs map.
+  std::unordered_map<std::string, int> id_count;
+  for (CreditCardCloudTokenData* data : cloud_token_data) {
+    const auto& iterator = id_count.find(data->masked_card_id);
+    if (iterator == id_count.end())
+      id_count.emplace(data->masked_card_id, 1);
+    else
+      iterator->second += 1;
+  }
+
+  // Remove the card from the vector that either has multiple cloud token data
+  // or has no cloud token data.
+  base::EraseIf(candidates, [&](const auto& card) {
+    const auto& iterator = id_count.find(card->server_id());
+    return iterator == id_count.end() || iterator->second > 1;
+  });
+
+  // Returns the remaining valid cards.
+  return candidates;
+}
+#endif
+
 }  // namespace
 
 AutofillManager::FillingContext::FillingContext() = default;
@@ -525,6 +559,29 @@
       /*autoselect_first_suggestion=*/false, should_display_gpay_logo);
 }
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+void AutofillManager::FetchVirtualCardCandidates() {
+  const std::vector<CreditCard*>& candidates =
+      GetVirtualCardCandidates(personal_data_);
+  // Make sure the |candidates| is not empty, otherwise the check in
+  // ShouldShowVirtualCardOption() should fail.
+  DCHECK(!candidates.empty());
+
+  client_->OfferVirtualCardOptions(
+      candidates,
+      base::BindOnce(&AutofillManager::OnVirtualCardCandidateSelected,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AutofillManager::OnVirtualCardCandidateSelected(
+    const std::string& selected_card_id) {
+  // TODO(crbug.com/1020740): Implement this and the following flow in a
+  // separate CL. The following flow will be sending a request to Payments
+  // to fetched the up-to-date cloud token data for the selected card and fill
+  // the information in the form.
+}
+#endif
+
 bool AutofillManager::ShouldParseForms(const std::vector<FormData>& forms,
                                        const base::TimeTicks timestamp) {
   bool autofill_enabled = IsAutofillEnabled();
@@ -2422,10 +2479,10 @@
     return false;
   }
 
-  // If no credit card cloud token data is available, return false.
-  // TODO(crbug.com/1020740): Wait for the changes on the AutofillTable is
-  // landed, and then add that check here (and also unit test in
-  // autofill_manager_unittest.cc).
+  // If no credit card candidate has related cloud token data available, return
+  // false.
+  if (GetVirtualCardCandidates(personal_data_).empty())
+    return false;
 
   // If card number field or expiration date field is not detected, return
   // false.
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index cc6bf1b..cf13fc9 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -119,6 +119,20 @@
                                           const FormData& form,
                                           const FormFieldData& field_data);
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+  // Returns the list of credit cards that have associated cloud token data.
+  virtual void FetchVirtualCardCandidates();
+
+  // Callback invoked when an actual card is selected. |selected_card_id| will
+  // be used to identify the card. The selected card's cloud token data will be
+  // fetched from the server.
+  // TODO(crbug.com/1020740): Passes card server id for now. In the future when
+  // one actual credit card can have multiple virtual cards, passes instrument
+  // token instead. Design TBD.
+  virtual void OnVirtualCardCandidateSelected(
+      const std::string& selected_card_id);
+#endif
+
   // Called from our external delegate so they cannot be private.
   virtual void FillOrPreviewForm(AutofillDriver::RendererFormDataAction action,
                                  int query_id,
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 1762467..f125065 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -7822,17 +7822,19 @@
     scoped_feature_list_.InitAndEnableFeature(
         features::kAutofillEnableVirtualCard);
 
-    // Add only one local card so the second suggestion (if any) must be the
+    // Add only one server card so the second suggestion (if any) must be the
     // "Use a virtual card number" option.
     personal_data_.ClearCreditCards();
-    CreditCard credit_card;
+    CreditCard masked_server_card(CreditCard::MASKED_SERVER_CARD,
+                                  /*server_id=*/"a123");
     // TODO(crbug.com/1020740): Replace all the hard-coded expiration year in
     // this file with NextYear().
-    test::SetCreditCardInfo(&credit_card, "Elvis Presley",
+    test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
                             "4234567890123456",  // Visa
                             "04", "2999", "1");
-    credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-    personal_data_.AddCreditCard(credit_card);
+    masked_server_card.SetNetworkForMaskedCard(kVisaCard);
+    masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
+    personal_data_.AddServerCreditCard(masked_server_card);
   }
 
   void CreateCompleteFormAndGetSuggestions() {
@@ -7845,6 +7847,15 @@
     GetAutofillSuggestions(form, field);
   }
 
+  // Adds a CreditCardCloudTokenData to PersonalDataManager. This needs to be
+  // called before suggestions are fetched.
+  void CreateCloudTokenDataForDefaultCard() {
+    personal_data_.ClearCloudTokenData();
+    CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1();
+    data1.masked_card_id = "a123";
+    personal_data_.AddCloudTokenData(data1);
+  }
+
   void VerifyNoVirtualCardSuggestions() {
     external_delegate_->CheckSuggestionCount(kDefaultPageID, 1);
     // Suggestion details need to match the credit card added in the SetUp()
@@ -7927,6 +7938,28 @@
                               autofill_manager_->GetPackedCreditCardID(7)));
 }
 
+// Ensures the "Use a virtual card number" option should not be shown when there
+// is no cloud token data for the card.
+TEST_F(AutofillManagerTestForVirtualCardOption,
+       ShouldNotShowDueToNoCloudTokenData) {
+  CreateCompleteFormAndGetSuggestions();
+
+  VerifyNoVirtualCardSuggestions();
+}
+
+// Ensures the "Use a virtual card number" option should not be shown when there
+// is multiple cloud token data for the card.
+TEST_F(AutofillManagerTestForVirtualCardOption,
+       ShouldNotShowDueToMultipleCloudTokenData) {
+  CreateCloudTokenDataForDefaultCard();
+  CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2();
+  data2.masked_card_id = "a123";
+  personal_data_.AddCloudTokenData(data2);
+  CreateCompleteFormAndGetSuggestions();
+
+  VerifyNoVirtualCardSuggestions();
+}
+
 // Ensures the "Use a virtual card number" option should not be shown when card
 // expiration date field is not detected.
 TEST_F(AutofillManagerTestForVirtualCardOption,
@@ -7985,7 +8018,9 @@
 
 // Ensures the "Use a virtual card number" option should be shown when all
 // requirements are met.
-TEST_F(AutofillManagerTestForVirtualCardOption, ShouldShowVirtualCardOption) {
+TEST_F(AutofillManagerTestForVirtualCardOption,
+       ShouldShowVirtualCardOption_OneCard) {
+  CreateCloudTokenDataForDefaultCard();
   CreateCompleteFormAndGetSuggestions();
 
   // Ensures the card suggestion and the virtual card suggestion are shown.
@@ -8000,6 +8035,50 @@
                      IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL),
                  "", "", PopupItemId::POPUP_ITEM_ID_USE_VIRTUAL_CARD));
 }
+
+// Ensures the "Use a virtual card number" option should be shown when there are
+// multiple cards and at least one card meets requirements.
+TEST_F(AutofillManagerTestForVirtualCardOption,
+       ShouldShowVirtualCardOption_MultipleCards) {
+  CreateCloudTokenDataForDefaultCard();
+
+  // Adds another card which does not meet the requirements (has two cloud
+  // tokens).
+  CreditCard masked_server_card(CreditCard::MASKED_SERVER_CARD,
+                                /*server_id=*/"a456");
+  // TODO(crbug.com/1020740): Replace all the hard-coded expiration year in
+  // this file with NextYear().
+  test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
+                          "4111111111111111",  // Visa
+                          "04", "2999", "1");
+  masked_server_card.SetNetworkForMaskedCard(kVisaCard);
+  masked_server_card.set_guid("00000000-0000-0000-0000-000000000008");
+  personal_data_.AddServerCreditCard(masked_server_card);
+  CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1();
+  data1.masked_card_id = "a456";
+  personal_data_.AddCloudTokenData(data1);
+  CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2();
+  data2.masked_card_id = "a456";
+  personal_data_.AddCloudTokenData(data2);
+
+  CreateCompleteFormAndGetSuggestions();
+
+  // Ensures the card suggestion and the virtual card suggestion are shown.
+  external_delegate_->CheckSuggestionCount(kDefaultPageID, 3);
+  CheckSuggestions(
+      kDefaultPageID,
+      Suggestion(
+          std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8("1111"),
+          "Expires on 04/99", kVisaCard,
+          autofill_manager_->GetPackedCreditCardID(8)),
+      Suggestion(
+          std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8("3456"),
+          "Expires on 04/99", kVisaCard,
+          autofill_manager_->GetPackedCreditCardID(7)),
+      Suggestion(l10n_util::GetStringUTF8(
+                     IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL),
+                 "", "", PopupItemId::POPUP_ITEM_ID_USE_VIRTUAL_CARD));
+}
 #endif
 
 // Test param indicates if there is an active screen reader.
diff --git a/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc b/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
index 7caf49b..b167d010 100644
--- a/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
+++ b/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/logging/log_buffer_submitter.h"
 
+#include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/values.h"
 #include "components/autofill/core/browser/logging/log_manager.h"
@@ -29,7 +30,7 @@
   LogRouter router;
   ignore_result(router.RegisterReceiver(&receiver));
   std::unique_ptr<LogManager> log_manager =
-      LogManager::Create(&router, base::Closure());
+      LogManager::Create(&router, base::NullCallback());
 
   EXPECT_CALL(receiver, LogEntry(testing::Eq(testing::ByRef(expected))));
   log_manager->Log() << 42;
@@ -42,7 +43,7 @@
   LogRouter router;
   ignore_result(router.RegisterReceiver(&receiver));
   std::unique_ptr<LogManager> log_manager =
-      LogManager::Create(&router, base::Closure());
+      LogManager::Create(&router, base::NullCallback());
 
   EXPECT_CALL(receiver, LogEntry(testing::_)).Times(0);
   log_manager->Log();
@@ -52,14 +53,14 @@
 
 TEST(LogBufferSubmitter, CorrectActivation) {
   std::unique_ptr<LogManager> log_manager =
-      LogManager::Create(nullptr, base::Closure());
+      LogManager::Create(nullptr, base::NullCallback());
   EXPECT_FALSE(log_manager->Log().buffer().active());
 
   LogRouter router;
   MockLogReceiver receiver;
   ignore_result(router.RegisterReceiver(&receiver));
   std::unique_ptr<LogManager> log_manager_2 =
-      LogManager::Create(&router, base::Closure());
+      LogManager::Create(&router, base::NullCallback());
   EXPECT_TRUE(log_manager_2->Log().buffer().active());
   router.UnregisterReceiver(&receiver);
 }
diff --git a/components/autofill/core/browser/logging/log_manager.cc b/components/autofill/core/browser/logging/log_manager.cc
index 6ad0e7d..a34258f 100644
--- a/components/autofill/core/browser/logging/log_manager.cc
+++ b/components/autofill/core/browser/logging/log_manager.cc
@@ -13,7 +13,8 @@
 
 class LogManagerImpl : public LogManager {
  public:
-  LogManagerImpl(LogRouter* log_router, base::Closure notification_callback);
+  LogManagerImpl(LogRouter* log_router,
+                 base::RepeatingClosure notification_callback);
 
   ~LogManagerImpl() override;
 
@@ -35,16 +36,16 @@
   bool is_suspended_ = false;
 
   // Called every time the logging activity status changes.
-  base::Closure notification_callback_;
+  base::RepeatingClosure notification_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(LogManagerImpl);
 };
 
 LogManagerImpl::LogManagerImpl(LogRouter* log_router,
-                               base::Closure notification_callback)
+                               base::RepeatingClosure notification_callback)
     : log_router_(log_router),
       can_use_log_router_(log_router_ && log_router_->RegisterManager(this)),
-      notification_callback_(notification_callback) {}
+      notification_callback_(std::move(notification_callback)) {}
 
 LogManagerImpl::~LogManagerImpl() {
   if (log_router_)
@@ -100,8 +101,9 @@
 // static
 std::unique_ptr<LogManager> LogManager::Create(
     LogRouter* log_router,
-    base::Closure notification_callback) {
-  return std::make_unique<LogManagerImpl>(log_router, notification_callback);
+    base::RepeatingClosure notification_callback) {
+  return std::make_unique<LogManagerImpl>(log_router,
+                                          std::move(notification_callback));
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/logging/log_manager.h b/components/autofill/core/browser/logging/log_manager.h
index ba959387..9cbd0eca 100644
--- a/components/autofill/core/browser/logging/log_manager.h
+++ b/components/autofill/core/browser/logging/log_manager.h
@@ -53,7 +53,7 @@
   // called every time the activity status of logging changes.
   static std::unique_ptr<LogManager> Create(
       LogRouter* log_router,
-      base::Closure notification_callback);
+      base::RepeatingClosure notification_callback);
 
   // This is the preferred way to submitting log entries.
   virtual LogBufferSubmitter Log() = 0;
diff --git a/components/autofill/core/browser/logging/log_manager_unittest.cc b/components/autofill/core/browser/logging/log_manager_unittest.cc
index d1bcc7c1..e9c2ab7 100644
--- a/components/autofill/core/browser/logging/log_manager_unittest.cc
+++ b/components/autofill/core/browser/logging/log_manager_unittest.cc
@@ -44,8 +44,9 @@
  protected:
   void SetUp() override {
     manager_ = LogManager::Create(
-        &router_, base::Bind(&MockNotifiedObject::NotifyAboutLoggingActivity,
-                             base::Unretained(&notified_object_)));
+        &router_,
+        base::BindRepeating(&MockNotifiedObject::NotifyAboutLoggingActivity,
+                            base::Unretained(&notified_object_)));
   }
 
   void TearDown() override {
@@ -95,7 +96,7 @@
 }
 
 TEST_F(LogManagerTest, NullCallbackWillNotCrash) {
-  manager_ = LogManager::Create(&router_, base::Closure());
+  manager_ = LogManager::Create(&router_, base::NullCallback());
   EXPECT_EQ(std::vector<base::Value>(), router_.RegisterReceiver(&receiver_));
   router_.UnregisterReceiver(&receiver_);
 }
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
index 42cbca9..e9b27552 100644
--- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
+++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.cc
@@ -57,9 +57,13 @@
       payments_client_(client->GetPaymentsClient()),
       user_is_verifiable_callback_received_(
           base::WaitableEvent::ResetPolicy::AUTOMATIC,
-          base::WaitableEvent::InitialState::NOT_SIGNALED) {}
+          base::WaitableEvent::InitialState::NOT_SIGNALED) {
+  user_is_opted_in_ = IsUserOptedIn();
+}
 
-CreditCardFIDOAuthenticator::~CreditCardFIDOAuthenticator() {}
+CreditCardFIDOAuthenticator::~CreditCardFIDOAuthenticator() {
+  UpdateUserPref();
+}
 
 void CreditCardFIDOAuthenticator::Authenticate(
     const CreditCard* card,
@@ -104,8 +108,8 @@
     // If user is already opted-in, then a new card is trying to be
     // authorized. Otherwise, a user with a credential on file is trying to
     // opt-in.
-    current_flow_ = IsUserOptedIn() ? FOLLOWUP_AFTER_CVC_AUTH_FLOW
-                                    : OPT_IN_WITH_CHALLENGE_FLOW;
+    current_flow_ = user_is_opted_in_ ? FOLLOWUP_AFTER_CVC_AUTH_FLOW
+                                      : OPT_IN_WITH_CHALLENGE_FLOW;
     GetAssertion(ParseRequestOptions(std::move(request_options)));
   }
 }
@@ -140,22 +144,21 @@
 
 void CreditCardFIDOAuthenticator::SyncUserOptIn(
     AutofillClient::UnmaskDetails& unmask_details) {
-  bool is_user_opted_in = IsUserOptedIn();
+  user_is_opted_in_ = IsUserOptedIn();
 
   // If payments is offering to opt-in, then that means user is not opted in.
   if (unmask_details.offer_fido_opt_in) {
-    is_user_opted_in = false;
+    user_is_opted_in_ = false;
   }
 
   // If payments is requesting a FIDO auth, then that means user is opted in.
   if (unmask_details.unmask_auth_method ==
       AutofillClient::UnmaskAuthMethod::FIDO) {
-    is_user_opted_in = true;
+    user_is_opted_in_ = true;
   }
 
   // Update pref setting if needed.
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_->GetPrefs(),
-                                                  is_user_opted_in);
+  UpdateUserPref();
 }
 
 void CreditCardFIDOAuthenticator::CancelVerification() {
@@ -173,6 +176,14 @@
   card_authorization_token_ = card_authorization_token;
   AutofillMetrics::LogWebauthnOptInPromoShown(
       /*is_checkout_flow=*/!card_authorization_token_.empty());
+
+  // At this point, it must be the case that the user is opted-out, otherwise
+  // there would be no need to register the user. However, if the user is
+  // opting-in through the settings page, the user preference is set to opted-in
+  // directly from the toggle switch being turned on. Storing the actual opt-in
+  // state in |user_is_opted_in_| for now, and will update the pref store once
+  // the UI flow is complete to avoid abrupt UI changes.
+  user_is_opted_in_ = false;
 }
 
 void CreditCardFIDOAuthenticator::OnWebauthnOfferDialogUserResponse(
@@ -197,8 +208,8 @@
     current_flow_ = NONE_FLOW;
     GetOrCreateFidoAuthenticationStrikeDatabase()->AddStrikes(
         FidoAuthenticationStrikeDatabase::kStrikesToAddWhenOptInOfferDeclined);
-    ::autofill::prefs::SetCreditCardFIDOAuthEnabled(
-        autofill_client_->GetPrefs(), false);
+    user_is_opted_in_ = false;
+    UpdateUserPref();
   }
 }
 #endif
@@ -355,6 +366,8 @@
       GetOrCreateFidoAuthenticationStrikeDatabase()->AddStrikes(
           FidoAuthenticationStrikeDatabase::
               kStrikesToAddWhenUserVerificationFailsOnOptInAttempt);
+      user_is_opted_in_ = false;
+      UpdateUserPref();
     }
 
     current_flow_ = NONE_FLOW;
@@ -399,6 +412,8 @@
       GetOrCreateFidoAuthenticationStrikeDatabase()->AddStrikes(
           FidoAuthenticationStrikeDatabase::
               kStrikesToAddWhenUserVerificationFailsOnOptInAttempt);
+      user_is_opted_in_ = false;
+      UpdateUserPref();
     }
 
     current_flow_ = NONE_FLOW;
@@ -417,9 +432,14 @@
          current_flow_ == FOLLOWUP_AFTER_CVC_AUTH_FLOW);
 
   // Update user preference to keep in sync with server.
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(
-      autofill_client_->GetPrefs(),
-      response.user_is_opted_in.value_or(IsUserOptedIn()));
+  user_is_opted_in_ = response.user_is_opted_in.value_or(user_is_opted_in_);
+
+  // When fetching the challenge on the settings page, don't update the user
+  // preference yet. Otherwise the toggle will be visibly turned off, which may
+  // seem confusing.
+  bool is_settings_page = card_authorization_token_.empty();
+  if (!is_settings_page || current_flow_ != OPT_IN_FETCH_CHALLENGE_FLOW)
+    UpdateUserPref();
 
   // End the flow if the server responded with an error.
   if (result != AutofillClient::PaymentsRpcResult::SUCCESS) {
@@ -704,4 +724,9 @@
   }
   AutofillMetrics::LogWebauthnResult(event, metric);
 }
+
+void CreditCardFIDOAuthenticator::UpdateUserPref() {
+  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_->GetPrefs(),
+                                                  user_is_opted_in_);
+}
 }  // namespace autofill
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
index d51ebd8..0ba8fc8 100644
--- a/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
+++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator.h
@@ -212,6 +212,9 @@
   // Logs the result of a WebAuthn prompt.
   void LogWebauthnResult(AuthenticatorStatus status);
 
+  // Updates the user preference to the value of |user_is_opted_in_|.
+  void UpdateUserPref();
+
   // Card being unmasked.
   const CreditCard* card_;
 
@@ -244,6 +247,10 @@
   // Weak pointer to object that is requesting authentication.
   base::WeakPtr<Requester> requester_;
 
+  // Is set to true when user is opted-in, else false. This value will always
+  // override the value in the pref store in the case of any discrepancies.
+  bool user_is_opted_in_;
+
   // Strike database to ensure we limit the number of times we offer fido
   // authentication.
   std::unique_ptr<FidoAuthenticationStrikeDatabase>
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
index 0f4316a..f0aab77 100644
--- a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
@@ -235,6 +235,13 @@
     fido_authenticator_->OnDidGetOptChangeResult(result, response);
   }
 
+  void SetUserOptInPreference(bool user_is_opted_in) {
+    ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
+                                                    user_is_opted_in);
+    fido_authenticator_->user_is_opted_in_ =
+        fido_authenticator_->IsUserOptedIn();
+  }
+
  protected:
   std::unique_ptr<TestAuthenticationRequester> requester_;
   base::test::TaskEnvironment task_environment_;
@@ -255,24 +262,21 @@
 TEST_F(CreditCardFIDOAuthenticatorTest, IsUserOptedIn_False) {
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  false);
+  SetUserOptInPreference(false);
   EXPECT_FALSE(fido_authenticator_->IsUserOptedIn());
 }
 
 TEST_F(CreditCardFIDOAuthenticatorTest, IsUserOptedIn_True) {
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  true);
+  SetUserOptInPreference(true);
   EXPECT_TRUE(fido_authenticator_->IsUserOptedIn());
 }
 
 TEST_F(CreditCardFIDOAuthenticatorTest, SyncUserOptIn_OnOfferedOptIn) {
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  true);
+  SetUserOptInPreference(true);
   EXPECT_TRUE(fido_authenticator_->IsUserOptedIn());
 
   // If payments is offering to opt-in, then that means user is not opted in.
@@ -285,8 +289,7 @@
 TEST_F(CreditCardFIDOAuthenticatorTest, SyncUserOptIn_OnFIDOAuthRequest) {
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  false);
+  SetUserOptInPreference(false);
   EXPECT_FALSE(fido_authenticator_->IsUserOptedIn());
 
   // If payments is requesting a FIDO auth, then that means user is opted in.
@@ -590,8 +593,7 @@
 TEST_F(CreditCardFIDOAuthenticatorTest, Register_NewCardAuthorization) {
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  true);
+  SetUserOptInPreference(true);
   EXPECT_TRUE(fido_authenticator_->IsUserOptedIn());
 
   fido_authenticator_->Authorize(
@@ -613,8 +615,7 @@
   scoped_feature_list_.InitAndEnableFeature(
       features::kAutofillCreditCardAuthentication);
   base::HistogramTester histogram_tester;
-  ::autofill::prefs::SetCreditCardFIDOAuthEnabled(autofill_client_.GetPrefs(),
-                                                  true);
+  SetUserOptInPreference(true);
 
   EXPECT_TRUE(fido_authenticator_->IsUserOptedIn());
 
diff --git a/components/autofill/core/browser/payments/full_card_request.cc b/components/autofill/core/browser/payments/full_card_request.cc
index 29f8900..d03fc5f9 100644
--- a/components/autofill/core/browser/payments/full_card_request.cc
+++ b/components/autofill/core/browser/payments/full_card_request.cc
@@ -107,8 +107,8 @@
 
   if (should_unmask_card_) {
     risk_data_loader_->LoadRiskData(
-        base::Bind(&FullCardRequest::OnDidGetUnmaskRiskData,
-                   weak_ptr_factory_.GetWeakPtr()));
+        base::BindOnce(&FullCardRequest::OnDidGetUnmaskRiskData,
+                       weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc
index 1161d56..ab27666 100644
--- a/components/autofill/core/browser/payments/payments_client.cc
+++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -260,13 +260,10 @@
                    base::Value(kUnmaskCardBillableServiceNumber));
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     std::string request_content;
     base::JSONWriter::Write(request_dict, &request_content);
@@ -369,13 +366,10 @@
     }
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     int value = 0;
     if (base::StringToInt(request_details_.user_response.exp_month, &value))
@@ -496,13 +490,10 @@
                    base::Value(kUnmaskCardBillableServiceNumber));
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     std::string reason;
     switch (request_details_.reason) {
@@ -623,13 +614,10 @@
     context.SetKey("billable_service", base::Value(billable_service_number_));
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     base::Value addresses(base::Value::Type::LIST);
     for (const AutofillProfile& profile : addresses_) {
@@ -798,13 +786,10 @@
     }
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     SetStringIfNotEmpty(request_details_.card, CREDIT_CARD_NAME_FULL,
                         app_locale, "cardholder_name", request_dict);
@@ -913,13 +898,10 @@
     }
     request_dict.SetKey("context", std::move(context));
 
-    if (ShouldUseActiveSignedInAccount()) {
-      base::Value chrome_user_context(base::Value::Type::DICTIONARY);
-      chrome_user_context.SetKey("full_sync_enabled",
-                                 base::Value(full_sync_enabled_));
-      request_dict.SetKey("chrome_user_context",
-                          std::move(chrome_user_context));
-    }
+    base::Value chrome_user_context(base::Value::Type::DICTIONARY);
+    chrome_user_context.SetKey("full_sync_enabled",
+                               base::Value(full_sync_enabled_));
+    request_dict.SetKey("chrome_user_context", std::move(chrome_user_context));
 
     request_dict.SetKey("context_token",
                         base::Value(request_details_.context_token));
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc
index d8c5cca..c565a3d 100644
--- a/components/autofill/core/browser/payments/payments_client_unittest.cc
+++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -113,11 +113,6 @@
 
   void TearDown() override { client_.reset(); }
 
-  void EnableAutofillGetPaymentsIdentityFromSync() {
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kAutofillGetPaymentsIdentityFromSync);
-  }
-
   // Registers a field trial with the specified name and group and an associated
   // google web property variation id.
   void CreateFieldTrialWithId(const std::string& trial_name,
@@ -379,9 +374,8 @@
 }
 
 TEST_F(PaymentsClientTest, GetUnmaskDetailsIncludesChromeUserContext) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillGetPaymentsIdentityFromSync},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage});  // Disabled
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartGettingUnmaskDetails();
   IssueOAuthToken();
@@ -443,7 +437,6 @@
 }
 
 TEST_F(PaymentsClientTest, UnmaskSuccessAccountFromSyncTest) {
-  EnableAutofillGetPaymentsIdentityFromSync();
   StartUnmasking(CardUnmaskOptions());
   IssueOAuthToken();
   ReturnResponse(net::HTTP_OK, "{ \"pan\": \"1234\" }");
@@ -452,9 +445,8 @@
 }
 
 TEST_F(PaymentsClientTest, UnmaskIncludesChromeUserContext) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillGetPaymentsIdentityFromSync},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage});  // Disabled
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartUnmasking(CardUnmaskOptions());
   IssueOAuthToken();
@@ -467,9 +459,8 @@
 
 TEST_F(PaymentsClientTest,
        UnmaskIncludesChromeUserContextIfWalletStorageFlagEnabled) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillEnableAccountWalletStorage},    // Enabled
-      {features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
+  scoped_feature_list_.InitAndEnableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartUnmasking(CardUnmaskOptions());
   IssueOAuthToken();
@@ -480,22 +471,6 @@
   EXPECT_TRUE(GetUploadData().find("full_sync_enabled") != std::string::npos);
 }
 
-TEST_F(PaymentsClientTest, UnmaskExcludesChromeUserContextIfExperimentsOff) {
-  scoped_feature_list_.InitWithFeatures(
-      {},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage,
-       features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
-
-  StartUnmasking(CardUnmaskOptions());
-  IssueOAuthToken();
-  ReturnResponse(net::HTTP_OK, "{}");
-
-  // ChromeUserContext was not set.
-  EXPECT_TRUE(!GetUploadData().empty());
-  EXPECT_TRUE(GetUploadData().find("chrome_user_context") == std::string::npos);
-  EXPECT_TRUE(GetUploadData().find("full_sync_enabled") == std::string::npos);
-}
-
 TEST_F(PaymentsClientTest, UnmaskLogsCvcLengthForAutofill) {
   base::HistogramTester histogram_tester;
   StartUnmasking(CardUnmaskOptions()
@@ -608,9 +583,8 @@
 }
 
 TEST_F(PaymentsClientTest, GetDetailsIncludesChromeUserContext) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillGetPaymentsIdentityFromSync},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage});  // Disabled
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartGettingUploadDetails();
 
@@ -621,9 +595,8 @@
 
 TEST_F(PaymentsClientTest,
        GetDetailsIncludesChromeUserContextIfWalletStorageFlagEnabled) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillEnableAccountWalletStorage},    // Enabled
-      {features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
+  scoped_feature_list_.InitAndEnableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartGettingUploadDetails();
 
@@ -633,21 +606,6 @@
 }
 
 TEST_F(PaymentsClientTest,
-       GetDetailsExcludesChromeUserContextIfExperimentsOff) {
-  scoped_feature_list_.InitWithFeatures(
-      {},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage,
-       features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
-
-  StartGettingUploadDetails();
-
-  // ChromeUserContext was not set.
-  EXPECT_TRUE(!GetUploadData().empty());
-  EXPECT_TRUE(GetUploadData().find("chrome_user_context") == std::string::npos);
-  EXPECT_TRUE(GetUploadData().find("full_sync_enabled") == std::string::npos);
-}
-
-TEST_F(PaymentsClientTest,
        GetDetailsIncludesUpstreamCheckoutFlowUploadCardSourceInRequest) {
   StartGettingUploadDetails(
       PaymentsClient::UploadCardSource::UPSTREAM_CHECKOUT_FLOW);
@@ -795,7 +753,6 @@
 }
 
 TEST_F(PaymentsClientTest, GetUploadAccountFromSyncTest) {
-  EnableAutofillGetPaymentsIdentityFromSync();
   // Set up a different account.
   const AccountInfo& secondary_account_info =
       identity_test_env_.MakeAccountAvailable("secondary@gmail.com");
@@ -925,9 +882,8 @@
 }
 
 TEST_F(PaymentsClientTest, UploadIncludesChromeUserContext) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillGetPaymentsIdentityFromSync},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage});  // Disabled
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartUploading(/*include_cvc=*/true);
   IssueOAuthToken();
@@ -939,9 +895,8 @@
 
 TEST_F(PaymentsClientTest,
        UploadIncludesChromeUserContextIfWalletStorageFlagEnabled) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillEnableAccountWalletStorage},    // Enabled
-      {features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
+  scoped_feature_list_.InitAndEnableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartUploading(/*include_cvc=*/true);
   IssueOAuthToken();
@@ -951,21 +906,6 @@
   EXPECT_TRUE(GetUploadData().find("full_sync_enabled") != std::string::npos);
 }
 
-TEST_F(PaymentsClientTest, UploadExcludesChromeUserContextIfExperimentsOff) {
-  scoped_feature_list_.InitWithFeatures(
-      {},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage,
-       features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
-
-  StartUploading(/*include_cvc=*/true);
-  IssueOAuthToken();
-
-  // ChromeUserContext was not set.
-  EXPECT_TRUE(!GetUploadData().empty());
-  EXPECT_TRUE(GetUploadData().find("chrome_user_context") == std::string::npos);
-  EXPECT_TRUE(GetUploadData().find("full_sync_enabled") == std::string::npos);
-}
-
 TEST_F(PaymentsClientTest, UploadDoesNotIncludeCvcInRequestIfNotProvided) {
   StartUploading(/*include_cvc=*/false);
   IssueOAuthToken();
@@ -1027,9 +967,8 @@
 }
 
 TEST_F(PaymentsClientTest, MigrationRequestIncludesChromeUserContext) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillGetPaymentsIdentityFromSync},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage});  // Disabled
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartMigrating(/*has_cardholder_name=*/true);
   IssueOAuthToken();
@@ -1041,9 +980,8 @@
 
 TEST_F(PaymentsClientTest,
        MigrationRequestIncludesChromeUserContextIfWalletStorageFlagEnabled) {
-  scoped_feature_list_.InitWithFeatures(
-      {features::kAutofillEnableAccountWalletStorage},    // Enabled
-      {features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
+  scoped_feature_list_.InitAndEnableFeature(
+      features::kAutofillEnableAccountWalletStorage);
 
   StartMigrating(/*has_cardholder_name=*/true);
   IssueOAuthToken();
@@ -1053,22 +991,6 @@
   EXPECT_TRUE(GetUploadData().find("full_sync_enabled") != std::string::npos);
 }
 
-TEST_F(PaymentsClientTest,
-       MigrationRequestExcludesChromeUserContextIfExperimentsOff) {
-  scoped_feature_list_.InitWithFeatures(
-      {},  // Enabled
-      {features::kAutofillEnableAccountWalletStorage,
-       features::kAutofillGetPaymentsIdentityFromSync});  // Disabled
-
-  StartMigrating(/*has_cardholder_name=*/true);
-  IssueOAuthToken();
-
-  // ChromeUserContext was not set.
-  EXPECT_TRUE(!GetUploadData().empty());
-  EXPECT_TRUE(GetUploadData().find("chrome_user_context") == std::string::npos);
-  EXPECT_TRUE(GetUploadData().find("full_sync_enabled") == std::string::npos);
-}
-
 TEST_F(PaymentsClientTest, MigrationSuccessWithSaveResult) {
   StartMigrating(/*has_cardholder_name=*/true);
   IssueOAuthToken();
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 2b8b7a5..218da39 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -541,15 +541,14 @@
 }
 
 CoreAccountInfo PersonalDataManager::GetAccountInfoForPaymentsServer() const {
-  // If butter is enabled or the feature to get the Payment Identity from Sync
-  // is enabled, return the account of the active signed-in user irrespective of
-  // whether they enabled sync or not.
-  // Otherwise, return the latest cached AccountInfo of the user's primary
-  // account, which is empty if the user has disabled sync.
+  // Return the account of the active signed-in user irrespective of whether
+  // they enabled sync or not.
+  // However if there is no |sync_service_| (e.g. in incognito), return the
+  // latest cached AccountInfo of the user's primary account, which is empty if
+  // the user has disabled sync.
   // In both cases, the AccountInfo will be empty if the user is not signed in.
-  return ShouldUseActiveSignedInAccount() && sync_service_
-             ? sync_service_->GetAuthenticatedAccountInfo()
-             : identity_manager_->GetPrimaryAccountInfo();
+  return sync_service_ ? sync_service_->GetAuthenticatedAccountInfo()
+                       : identity_manager_->GetPrimaryAccountInfo();
 }
 
 // TODO(crbug.com/903914): Clean up this function so that it's more clear what
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 9a5f7731..24236dd3 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -7461,37 +7461,16 @@
   active_info.email = kSyncTransportAccountEmail;
   sync_service_.SetAuthenticatedAccountInfo(active_info);
 
-  // The IdentityManager's AccountInfo should be returned by default.
+  // The Active Sync AccountInfo should be returned.
+  EXPECT_EQ(kSyncTransportAccountEmail,
+            personal_data_->GetAccountInfoForPaymentsServer().email);
+
+  // The Active Sync AccountInfo should still be returned even if
+  // kAutofillEnableAccountWalletStorage is disabled.
   {
     base::test::ScopedFeatureList scoped_features;
-    scoped_features.InitWithFeatures(
-        /*enabled_features=*/{},
-        /*disabled_features=*/{features::kAutofillEnableAccountWalletStorage,
-                               features::kAutofillGetPaymentsIdentityFromSync});
-
-    EXPECT_EQ(kPrimaryAccountEmail,
-              personal_data_->GetAccountInfoForPaymentsServer().email);
-  }
-
-  // The Active Sync AccountInfo should be returned if
-  // kAutofillEnableAccountWalletStorage is enabled.
-  {
-    base::test::ScopedFeatureList scoped_features;
-    scoped_features.InitWithFeatures(
-        /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
-        /*disabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync});
-
-    EXPECT_EQ(kSyncTransportAccountEmail,
-              personal_data_->GetAccountInfoForPaymentsServer().email);
-  }
-
-  // The Active Sync AccountInfo should be returned if
-  // kAutofillGetPaymentsIdentityFromSync is enabled.
-  {
-    base::test::ScopedFeatureList scoped_features;
-    scoped_features.InitWithFeatures(
-        /*enabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync},
-        /*disabled_features=*/{features::kAutofillEnableAccountWalletStorage});
+    scoped_features.InitAndDisableFeature(
+        features::kAutofillEnableAccountWalletStorage);
 
     EXPECT_EQ(kSyncTransportAccountEmail,
               personal_data_->GetAccountInfoForPaymentsServer().email);
@@ -7793,14 +7772,12 @@
             personal_data_->GetSyncSigninState());
 
   // Check that the sync state is |SignedInAndSyncFeature| if the the sync
-  // feature is enabled even if the kAutofillEnableAccountWalletStorage and
-  // kAutofillGetPaymentsIdentityFromSync features are enabled.
+  // feature is enabled even if the kAutofillEnableAccountWalletStorage feature
+  // is enabled.
   {
     base::test::ScopedFeatureList scoped_features;
-    scoped_features.InitWithFeatures(
-        /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage,
-                              features::kAutofillGetPaymentsIdentityFromSync},
-        /*disabled_features=*/{});
+    scoped_features.InitAndEnableFeature(
+        features::kAutofillEnableAccountWalletStorage);
     EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled,
               personal_data_->GetSyncSigninState());
   }
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc
index 1d5634c..8cb7b086 100644
--- a/components/autofill/core/browser/test_autofill_client.cc
+++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -133,6 +133,10 @@
 void TestAutofillClient::ConfirmSaveUpiIdLocally(
     const std::string& upi_id,
     base::OnceCallback<void(bool accept)> callback) {}
+
+void TestAutofillClient::OfferVirtualCardOptions(
+    const std::vector<CreditCard*>& candidates,
+    base::OnceCallback<void(const std::string&)> callback) {}
 #endif
 
 void TestAutofillClient::ConfirmSaveAutofillProfile(
@@ -193,8 +197,7 @@
   return false;
 }
 
-void TestAutofillClient::ScanCreditCard(
-    const CreditCardScanCallback& callback) {}
+void TestAutofillClient::ScanCreditCard(CreditCardScanCallback callback) {}
 
 void TestAutofillClient::ShowAutofillPopup(
     const gfx::RectF& element_bounds,
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h
index 1b33051..1491f83 100644
--- a/components/autofill/core/browser/test_autofill_client.h
+++ b/components/autofill/core/browser/test_autofill_client.h
@@ -79,6 +79,9 @@
   void ConfirmSaveUpiIdLocally(
       const std::string& upi_id,
       base::OnceCallback<void(bool accept)> callback) override;
+  void OfferVirtualCardOptions(
+      const std::vector<CreditCard*>& candidates,
+      base::OnceCallback<void(const std::string&)> callback) override;
 #endif
   void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
                                   base::OnceClosure callback) override;
@@ -103,7 +106,7 @@
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    base::OnceClosure callback) override;
   bool HasCreditCardScanFeature() override;
-  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ScanCreditCard(CreditCardScanCallback callback) override;
   void ShowAutofillPopup(
       const gfx::RectF& element_bounds,
       base::i18n::TextDirection text_direction,
diff --git a/components/autofill/core/browser/test_personal_data_manager.cc b/components/autofill/core/browser/test_personal_data_manager.cc
index 25f2f4b..f9f34e6 100644
--- a/components/autofill/core/browser/test_personal_data_manager.cc
+++ b/components/autofill/core/browser/test_personal_data_manager.cc
@@ -278,6 +278,10 @@
   server_credit_cards_.clear();
 }
 
+void TestPersonalDataManager::ClearCloudTokenData() {
+  server_credit_card_cloud_token_data_.clear();
+}
+
 AutofillProfile* TestPersonalDataManager::GetProfileWithGUID(const char* guid) {
   for (AutofillProfile* profile : GetProfiles()) {
     if (!profile->guid().compare(guid))
@@ -302,4 +306,12 @@
   NotifyPersonalDataObserver();
 }
 
+void TestPersonalDataManager::AddCloudTokenData(
+    const CreditCardCloudTokenData& cloud_token_data) {
+  std::unique_ptr<CreditCardCloudTokenData> data =
+      std::make_unique<CreditCardCloudTokenData>(cloud_token_data);
+  server_credit_card_cloud_token_data_.push_back(std::move(data));
+  NotifyPersonalDataObserver();
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/test_personal_data_manager.h b/components/autofill/core/browser/test_personal_data_manager.h
index 5aa67fd4..4437ba0 100644
--- a/components/autofill/core/browser/test_personal_data_manager.h
+++ b/components/autofill/core/browser/test_personal_data_manager.h
@@ -68,6 +68,9 @@
   // Clears |local_credit_cards_| and |server_credit_cards_|.
   void ClearCreditCards();
 
+  // Clears |server_credit_card_cloud_token_data_|.
+  void ClearCloudTokenData();
+
   // Gets a profile based on the provided |guid|.
   AutofillProfile* GetProfileWithGUID(const char* guid);
 
@@ -78,6 +81,9 @@
   // AddFullServerCreditCard().
   void AddServerCreditCard(const CreditCard& credit_card);
 
+  // Adds a cloud token data to |server_credit_card_cloud_token_data_|.
+  void AddCloudTokenData(const CreditCardCloudTokenData& cloud_token_data);
+
   void set_timezone_country_code(const std::string& timezone_country_code) {
     timezone_country_code_ = timezone_country_code;
   }
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
index f8a7b8a9..da204d9 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
@@ -96,7 +96,7 @@
 
   void ShowPrompt() {
     controller_->ShowPrompt(
-        base::Bind(
+        base::BindOnce(
             &CardUnmaskPromptControllerImplGenericTest::GetCardUnmaskPromptView,
             base::Unretained(this)),
         test::GetMaskedServerCard(), AutofillClient::UNMASK_FOR_AUTOFILL,
@@ -105,7 +105,7 @@
 
   void ShowPromptAmex() {
     controller_->ShowPrompt(
-        base::Bind(
+        base::BindOnce(
             &CardUnmaskPromptControllerImplGenericTest::GetCardUnmaskPromptView,
             base::Unretained(this)),
         test::GetMaskedServerCardAmex(), AutofillClient::UNMASK_FOR_AUTOFILL,
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index 240119d0..c4fb8e5e 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -37,9 +37,10 @@
     scoped_refptr<WebDatabaseBackend> web_database_backend,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
-    const base::Closure& on_changed_callback,
-    const base::Closure& on_address_conversion_completed_callback,
-    const base::Callback<void(syncer::ModelType)>& on_sync_started_callback)
+    const base::RepeatingClosure& on_changed_callback,
+    const base::RepeatingClosure& on_address_conversion_completed_callback,
+    const base::RepeatingCallback<void(syncer::ModelType)>&
+        on_sync_started_callback)
     : base::RefCountedDeleteOnSequence<AutofillWebDataBackendImpl>(
           std::move(db_task_runner)),
       ui_task_runner_(ui_task_runner),
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
index 1b58a8b..9ac3bfa 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
@@ -51,9 +51,10 @@
       scoped_refptr<WebDatabaseBackend> web_database_backend,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
-      const base::Closure& on_changed_callback,
-      const base::Closure& on_address_conversion_completed_callback,
-      const base::Callback<void(syncer::ModelType)>& on_sync_started_callback);
+      const base::RepeatingClosure& on_changed_callback,
+      const base::RepeatingClosure& on_address_conversion_completed_callback,
+      const base::RepeatingCallback<void(syncer::ModelType)>&
+          on_sync_started_callback);
 
   void SetAutofillProfileChangedCallback(
       base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
@@ -249,9 +250,9 @@
   // TODO(caitkp): Make it so nobody but us needs direct DB access anymore.
   scoped_refptr<WebDatabaseBackend> web_database_backend_;
 
-  base::Closure on_changed_callback_;
-  base::Closure on_address_conversion_completed_callback_;
-  base::Callback<void(syncer::ModelType)> on_sync_started_callback_;
+  base::RepeatingClosure on_changed_callback_;
+  base::RepeatingClosure on_address_conversion_completed_callback_;
+  base::RepeatingCallback<void(syncer::ModelType)> on_sync_started_callback_;
 
   base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
       on_autofill_profile_changed_cb_;
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.cc b/components/autofill/core/browser/webdata/autofill_webdata_service.cc
index 3fd8c2c..7ba34c6 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_service.cc
@@ -21,7 +21,6 @@
 #include "components/webdata/common/web_database_backend.h"
 #include "components/webdata/common/web_database_service.h"
 
-using base::Bind;
 using base::Time;
 
 namespace autofill {
@@ -34,16 +33,18 @@
       ui_task_runner_(std::move(ui_task_runner)),
       db_task_runner_(std::move(db_task_runner)),
       autofill_backend_(nullptr) {
-  base::Closure on_changed_callback =
-      Bind(&AutofillWebDataService::NotifyAutofillMultipleChangedOnUISequence,
-           weak_ptr_factory_.GetWeakPtr());
-  base::Closure on_address_conversion_completed_callback =
-      Bind(&AutofillWebDataService::
-               NotifyAutofillAddressConversionCompletedOnUISequence,
-           weak_ptr_factory_.GetWeakPtr());
-  base::Callback<void(syncer::ModelType)> on_sync_started_callback =
-      Bind(&AutofillWebDataService::NotifySyncStartedOnUISequence,
-           weak_ptr_factory_.GetWeakPtr());
+  base::RepeatingClosure on_changed_callback = base::BindRepeating(
+      &AutofillWebDataService::NotifyAutofillMultipleChangedOnUISequence,
+      weak_ptr_factory_.GetWeakPtr());
+  base::RepeatingClosure on_address_conversion_completed_callback =
+      base::BindRepeating(
+          &AutofillWebDataService::
+              NotifyAutofillAddressConversionCompletedOnUISequence,
+          weak_ptr_factory_.GetWeakPtr());
+  base::RepeatingCallback<void(syncer::ModelType)> on_sync_started_callback =
+      base::BindRepeating(
+          &AutofillWebDataService::NotifySyncStartedOnUISequence,
+          weak_ptr_factory_.GetWeakPtr());
   autofill_backend_ = new AutofillWebDataBackendImpl(
       wdbs_->GetBackend(), ui_task_runner_, db_task_runner_,
       on_changed_callback, on_address_conversion_completed_callback,
@@ -74,38 +75,43 @@
 
 void AutofillWebDataService::AddFormFields(
     const std::vector<FormFieldData>& fields) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::AddFormElements,
-           autofill_backend_, fields));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::AddFormElements,
+                                autofill_backend_, fields));
 }
 
 WebDataServiceBase::Handle AutofillWebDataService::GetFormValuesForElementName(
     const base::string16& name, const base::string16& prefix, int limit,
     WebDataServiceConsumer* consumer) {
-  return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetFormValuesForElementName,
-           autofill_backend_, name, prefix, limit), consumer);
+  return wdbs_->ScheduleDBTaskWithResult(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::GetFormValuesForElementName,
+                     autofill_backend_, name, prefix, limit),
+      consumer);
 }
 
 void AutofillWebDataService::RemoveFormElementsAddedBetween(
     const Time& delete_begin, const Time& delete_end) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveFormElementsAddedBetween,
-           autofill_backend_, delete_begin, delete_end));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE,
+      base::BindOnce(
+          &AutofillWebDataBackendImpl::RemoveFormElementsAddedBetween,
+          autofill_backend_, delete_begin, delete_end));
 }
 
 void AutofillWebDataService::RemoveFormValueForElementName(
     const base::string16& name, const base::string16& value) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveFormValueForElementName,
-           autofill_backend_, name, value));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::RemoveFormValueForElementName,
+                     autofill_backend_, name, value));
 }
 
 void AutofillWebDataService::AddAutofillProfile(
     const AutofillProfile& profile) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::AddAutofillProfile,
-           autofill_backend_, profile));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::AddAutofillProfile,
+                                autofill_backend_, profile));
 }
 
 void AutofillWebDataService::SetAutofillProfileChangedCallback(
@@ -115,22 +121,26 @@
 
 void AutofillWebDataService::UpdateAutofillProfile(
     const AutofillProfile& profile) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::UpdateAutofillProfile,
-           autofill_backend_, profile));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::UpdateAutofillProfile,
+                     autofill_backend_, profile));
 }
 
 void AutofillWebDataService::RemoveAutofillProfile(
     const std::string& guid) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveAutofillProfile,
-           autofill_backend_, guid));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::RemoveAutofillProfile,
+                     autofill_backend_, guid));
 }
 
 WebDataServiceBase::Handle AutofillWebDataService::GetAutofillProfiles(
     WebDataServiceConsumer* consumer) {
-  return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetAutofillProfiles, autofill_backend_),
+  return wdbs_->ScheduleDBTaskWithResult(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::GetAutofillProfiles,
+                     autofill_backend_),
       consumer);
 }
 
@@ -138,7 +148,8 @@
     WebDataServiceConsumer* consumer) {
   return wdbs_->ScheduleDBTaskWithResult(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetServerProfiles, autofill_backend_),
+      base::BindOnce(&AutofillWebDataBackendImpl::GetServerProfiles,
+                     autofill_backend_),
       consumer);
 }
 
@@ -146,69 +157,73 @@
     const std::string& app_locale,
     const std::string& primary_account_email) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE, Bind(&AutofillWebDataBackendImpl::
-                          ConvertWalletAddressesAndUpdateWalletCards,
-                      autofill_backend_, app_locale, primary_account_email));
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::
+                         ConvertWalletAddressesAndUpdateWalletCards,
+                     autofill_backend_, app_locale, primary_account_email));
 }
 
 WebDataServiceBase::Handle
     AutofillWebDataService::GetCountOfValuesContainedBetween(
         const Time& begin, const Time& end, WebDataServiceConsumer* consumer) {
-  return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetCountOfValuesContainedBetween,
-           autofill_backend_, begin, end),
-           consumer);
+  return wdbs_->ScheduleDBTaskWithResult(
+      FROM_HERE,
+      base::BindOnce(
+          &AutofillWebDataBackendImpl::GetCountOfValuesContainedBetween,
+          autofill_backend_, begin, end),
+      consumer);
 }
 
 void AutofillWebDataService::UpdateAutofillEntries(
     const std::vector<AutofillEntry>& autofill_entries) {
-  wdbs_->ScheduleDBTask(FROM_HERE,
-                        Bind(&AutofillWebDataBackendImpl::UpdateAutofillEntries,
-                             autofill_backend_,
-                             autofill_entries));
+  wdbs_->ScheduleDBTask(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::UpdateAutofillEntries,
+                     autofill_backend_, autofill_entries));
 }
 
 void AutofillWebDataService::AddCreditCard(const CreditCard& credit_card) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::AddCreditCard,
-           autofill_backend_, credit_card));
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::AddCreditCard,
+                                autofill_backend_, credit_card));
 }
 
 void AutofillWebDataService::UpdateCreditCard(
     const CreditCard& credit_card) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::UpdateCreditCard,
-           autofill_backend_, credit_card));
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::UpdateCreditCard,
+                                autofill_backend_, credit_card));
 }
 
 void AutofillWebDataService::RemoveCreditCard(const std::string& guid) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveCreditCard,
-           autofill_backend_, guid));
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::RemoveCreditCard,
+                                autofill_backend_, guid));
 }
 
 void AutofillWebDataService::AddFullServerCreditCard(
     const CreditCard& credit_card) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE, Bind(&AutofillWebDataBackendImpl::AddFullServerCreditCard,
-                      autofill_backend_, credit_card));
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::AddFullServerCreditCard,
+                     autofill_backend_, credit_card));
 }
 
 WebDataServiceBase::Handle AutofillWebDataService::GetCreditCards(
     WebDataServiceConsumer* consumer) {
-  return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetCreditCards, autofill_backend_),
+  return wdbs_->ScheduleDBTaskWithResult(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::GetCreditCards,
+                     autofill_backend_),
       consumer);
 }
 
 WebDataServiceBase::Handle AutofillWebDataService::GetServerCreditCards(
     WebDataServiceConsumer* consumer) {
-  return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetServerCreditCards,
-           autofill_backend_),
+  return wdbs_->ScheduleDBTaskWithResult(
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::GetServerCreditCards,
+                     autofill_backend_),
       consumer);
 }
 
@@ -217,28 +232,29 @@
     const base::string16& full_number) {
   wdbs_->ScheduleDBTask(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::UnmaskServerCreditCard,
-           autofill_backend_, credit_card, full_number));
+      base::BindOnce(&AutofillWebDataBackendImpl::UnmaskServerCreditCard,
+                     autofill_backend_, credit_card, full_number));
 }
 
 void AutofillWebDataService::MaskServerCreditCard(const std::string& id) {
   wdbs_->ScheduleDBTask(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::MaskServerCreditCard,
-           autofill_backend_, id));
+      base::BindOnce(&AutofillWebDataBackendImpl::MaskServerCreditCard,
+                     autofill_backend_, id));
 }
 
 void AutofillWebDataService::AddUpiId(const std::string& upi_id) {
-  wdbs_->ScheduleDBTask(FROM_HERE, Bind(&AutofillWebDataBackendImpl::AddUpiId,
-                                        autofill_backend_, upi_id));
+  wdbs_->ScheduleDBTask(FROM_HERE,
+                        base::BindOnce(&AutofillWebDataBackendImpl::AddUpiId,
+                                       autofill_backend_, upi_id));
 }
 
 WebDataServiceBase::Handle AutofillWebDataService::GetPaymentsCustomerData(
     WebDataServiceConsumer* consumer) {
   return wdbs_->ScheduleDBTaskWithResult(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetPaymentsCustomerData,
-           autofill_backend_),
+      base::BindOnce(&AutofillWebDataBackendImpl::GetPaymentsCustomerData,
+                     autofill_backend_),
       consumer);
 }
 
@@ -246,36 +262,37 @@
     WebDataServiceConsumer* consumer) {
   return wdbs_->ScheduleDBTaskWithResult(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::GetCreditCardCloudTokenData,
-           autofill_backend_),
+      base::BindOnce(&AutofillWebDataBackendImpl::GetCreditCardCloudTokenData,
+                     autofill_backend_),
       consumer);
 }
 
 void AutofillWebDataService::ClearAllServerData() {
   wdbs_->ScheduleDBTask(
-      FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::ClearAllServerData,
-           autofill_backend_));
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::ClearAllServerData,
+                                autofill_backend_));
 }
 
 void AutofillWebDataService::ClearAllLocalData() {
   wdbs_->ScheduleDBTask(
-      FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::ClearAllLocalData, autofill_backend_));
+      FROM_HERE, base::BindOnce(&AutofillWebDataBackendImpl::ClearAllLocalData,
+                                autofill_backend_));
 }
 
 void AutofillWebDataService::UpdateServerCardMetadata(
     const CreditCard& credit_card) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE, Bind(&AutofillWebDataBackendImpl::UpdateServerCardMetadata,
-                      autofill_backend_, credit_card));
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::UpdateServerCardMetadata,
+                     autofill_backend_, credit_card));
 }
 
 void AutofillWebDataService::UpdateServerAddressMetadata(
     const AutofillProfile& profile) {
   wdbs_->ScheduleDBTask(
-      FROM_HERE, Bind(&AutofillWebDataBackendImpl::UpdateServerAddressMetadata,
-                      autofill_backend_, profile));
+      FROM_HERE,
+      base::BindOnce(&AutofillWebDataBackendImpl::UpdateServerAddressMetadata,
+                     autofill_backend_, profile));
 }
 
 void AutofillWebDataService::RemoveAutofillDataModifiedBetween(
@@ -283,23 +300,25 @@
     const Time& delete_end) {
   wdbs_->ScheduleDBTask(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveAutofillDataModifiedBetween,
-           autofill_backend_, delete_begin, delete_end));
+      base::BindOnce(
+          &AutofillWebDataBackendImpl::RemoveAutofillDataModifiedBetween,
+          autofill_backend_, delete_begin, delete_end));
 }
 
 void AutofillWebDataService::RemoveOriginURLsModifiedBetween(
     const Time& delete_begin, const Time& delete_end) {
   wdbs_->ScheduleDBTask(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveOriginURLsModifiedBetween,
-           autofill_backend_, delete_begin, delete_end));
+      base::BindOnce(
+          &AutofillWebDataBackendImpl::RemoveOriginURLsModifiedBetween,
+          autofill_backend_, delete_begin, delete_end));
 }
 
 void AutofillWebDataService::RemoveOrphanAutofillTableRows() {
   wdbs_->ScheduleDBTask(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveOrphanAutofillTableRows,
-           autofill_backend_));
+      base::BindOnce(&AutofillWebDataBackendImpl::RemoveOrphanAutofillTableRows,
+                     autofill_backend_));
 }
 
 void AutofillWebDataService::AddObserver(
@@ -334,10 +353,10 @@
 }
 
 void AutofillWebDataService::GetAutofillBackend(
-    const base::Callback<void(AutofillWebDataBackend*)>& callback) {
+    base::OnceCallback<void(AutofillWebDataBackend*)> callback) {
   db_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(callback, base::RetainedRef(autofill_backend_)));
+      FROM_HERE, base::BindOnce(std::move(callback),
+                                base::RetainedRef(autofill_backend_)));
 }
 
 base::SingleThreadTaskRunner* AutofillWebDataService::GetDBTaskRunner() {
@@ -349,8 +368,9 @@
     WebDataServiceConsumer* consumer) {
   return wdbs_->ScheduleDBTaskWithResult(
       FROM_HERE,
-      Bind(&AutofillWebDataBackendImpl::RemoveExpiredAutocompleteEntries,
-           autofill_backend_),
+      base::BindOnce(
+          &AutofillWebDataBackendImpl::RemoveExpiredAutocompleteEntries,
+          autofill_backend_),
       consumer);
 }
 
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.h b/components/autofill/core/browser/webdata/autofill_webdata_service.h
index ef5169b..5315abfb 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_service.h
+++ b/components/autofill/core/browser/webdata/autofill_webdata_service.h
@@ -193,7 +193,7 @@
   // an AutofillWebdataBackend. This backend can be used to access or update the
   // WebDatabase directly on the DB sequence.
   void GetAutofillBackend(
-      const base::Callback<void(AutofillWebDataBackend*)>& callback);
+      base::OnceCallback<void(AutofillWebDataBackend*)> callback);
 
   // Returns a task runner that can be used to schedule tasks on the DB
   // sequence.
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 627d4a9d..30c526b 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -76,11 +76,6 @@
     "AutofillEnforceMinRequiredFieldsForUpload",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
-// When enabled, gets payment identity from sync service instead of
-// identity manager.
-const base::Feature kAutofillGetPaymentsIdentityFromSync{
-    "AutofillGetPaymentsIdentityFromSync", base::FEATURE_ENABLED_BY_DEFAULT};
-
 // When enabled, autofill suggestions are displayed in the keyboard accessory
 // instead of the regular popup.
 const base::Feature kAutofillKeyboardAccessory{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 1306a9f..60e1239 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -33,7 +33,6 @@
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
-extern const base::Feature kAutofillGetPaymentsIdentityFromSync;
 extern const base::Feature kAutofillKeyboardAccessory;
 extern const base::Feature kAutofillPruneSuggestions;
 extern const base::Feature kAutofillMetadataUploads;
diff --git a/components/autofill_assistant/OWNERS b/components/autofill_assistant/OWNERS
index 3009761..f2cc151c 100644
--- a/components/autofill_assistant/OWNERS
+++ b/components/autofill_assistant/OWNERS
@@ -1,10 +1,12 @@
 # Please keep these in alphabetical order
 arbesser@google.com
 gogerald@chromium.org
+hluca@google.com
 jdemeulenaere@chromium.org
 marianfe@google.com
 mcarlen@chromium.org
 rouslan@chromium.org
+sandromaggi@google.com
 szermatt@chromium.org
 
 # COMPONENT: UI>Browser>Autofill
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index bb634b2..178f307f 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -80,8 +80,11 @@
       base::OnceCallback<void(const ClientStatus&)> callback) = 0;
 
   // Wait for up to |max_wait_time| for element conditions to match on the page,
-  // then call |callback| with a successful status if at least an element
-  // matched, an error status otherwise.
+  // then call |callback| with the last status.
+  //
+  // |check_elements| should register the elements to check, process their state
+  // and reports its decision to the callback it's passed. WaitForDom retries as
+  // long as the decision is not OK, and max_wait_time is not reached.
   //
   // If |allow_interrupt| interrupts can run while waiting.
   virtual void WaitForDom(
diff --git a/components/autofill_assistant/browser/actions/prompt_action.cc b/components/autofill_assistant/browser/actions/prompt_action.cc
index 27d04bd..0d5e2f7 100644
--- a/components/autofill_assistant/browser/actions/prompt_action.cc
+++ b/components/autofill_assistant/browser/actions/prompt_action.cc
@@ -42,19 +42,49 @@
   SetupPreconditions();
   UpdateUserActions();
 
-  if (HasNonemptyPreconditions() || HasAutoSelect()) {
-    RunPeriodicChecks();
-    timer_ = std::make_unique<base::RepeatingTimer>();
-    timer_->Start(FROM_HERE,
-                  delegate_->GetSettings().periodic_script_check_interval,
-                  base::BindRepeating(&PromptAction::RunPeriodicChecks,
-                                      weak_ptr_factory_.GetWeakPtr()));
+  if (HasNonemptyPreconditions() || HasAutoSelect() ||
+      proto_.prompt().allow_interrupt()) {
+    delegate_->WaitForDom(base::TimeDelta::Max(),
+                          proto_.prompt().allow_interrupt(),
+                          base::BindRepeating(&PromptAction::RegisterChecks,
+                                              weak_ptr_factory_.GetWeakPtr()),
+                          base::BindOnce(&PromptAction::OnDoneWaitForDom,
+                                         weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
-void PromptAction::RunPeriodicChecks() {
-  CheckPreconditions();
-  CheckAutoSelect();
+void PromptAction::RegisterChecks(
+    BatchElementChecker* checker,
+    base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback) {
+  if (!callback_) {
+    // Action is done; checks aren't necessary anymore.
+    std::move(wait_for_dom_callback).Run(OkClientStatus());
+    return;
+  }
+
+  UpdateUserActions();
+
+  for (size_t i = 0; i < preconditions_.size(); i++) {
+    preconditions_[i]->Check(checker,
+                             base::BindOnce(&PromptAction::OnPreconditionResult,
+                                            weak_ptr_factory_.GetWeakPtr(), i));
+  }
+
+  auto_select_choice_index_ = -1;
+  for (int i = 0; i < proto_.prompt().choices_size(); i++) {
+    Selector selector =
+        Selector(proto_.prompt().choices(i).auto_select_if_element_exists());
+    if (selector.empty())
+      continue;
+
+    checker->AddElementCheck(
+        selector, base::BindOnce(&PromptAction::OnAutoSelectElementExists,
+                                 weak_ptr_factory_.GetWeakPtr(), i));
+  }
+
+  checker->AddAllDoneCallback(base::BindOnce(&PromptAction::OnElementChecksDone,
+                                             weak_ptr_factory_.GetWeakPtr(),
+                                             std::move(wait_for_dom_callback)));
 }
 
 void PromptAction::SetupPreconditions() {
@@ -78,18 +108,6 @@
   return false;
 }
 
-void PromptAction::CheckPreconditions() {
-  precondition_checker_ = std::make_unique<BatchElementChecker>();
-  for (size_t i = 0; i < preconditions_.size(); i++) {
-    preconditions_[i]->Check(precondition_checker_.get(),
-                             base::BindOnce(&PromptAction::OnPreconditionResult,
-                                            weak_ptr_factory_.GetWeakPtr(), i));
-  }
-  precondition_checker_->AddAllDoneCallback(base::BindOnce(
-      &PromptAction::OnPreconditionChecksDone, weak_ptr_factory_.GetWeakPtr()));
-  delegate_->RunElementChecks(precondition_checker_.get());
-}
-
 void PromptAction::OnPreconditionResult(size_t choice_index, bool result) {
   if (precondition_results_[choice_index] == result)
     return;
@@ -98,11 +116,6 @@
   precondition_changed_ = true;
 }
 
-void PromptAction::OnPreconditionChecksDone() {
-  if (precondition_changed_)
-    UpdateUserActions();
-}
-
 void PromptAction::UpdateUserActions() {
   DCHECK(callback_);  // Make sure we're still waiting for a response
 
@@ -136,26 +149,6 @@
   return false;
 }
 
-void PromptAction::CheckAutoSelect() {
-  auto_select_checker_ = std::make_unique<BatchElementChecker>();
-
-  // Wait as long as necessary for one of the elements to show up. This is
-  // cancelled by CancelPrompt()
-  for (int i = 0; i < proto_.prompt().choices_size(); i++) {
-    Selector selector =
-        Selector(proto_.prompt().choices(i).auto_select_if_element_exists());
-    if (selector.empty())
-      continue;
-
-    auto_select_checker_->AddElementCheck(
-        selector, base::BindOnce(&PromptAction::OnAutoSelectElementExists,
-                                 weak_ptr_factory_.GetWeakPtr(), i));
-  }
-  auto_select_checker_->AddAllDoneCallback(base::BindOnce(
-      &PromptAction::OnAutoSelectDone, weak_ptr_factory_.GetWeakPtr()));
-  delegate_->RunElementChecks(auto_select_checker_.get());
-}
-
 void PromptAction::OnAutoSelectElementExists(
     int choice_index,
     const ClientStatus& element_status) {
@@ -167,7 +160,27 @@
   // check callback.
 }
 
-void PromptAction::OnAutoSelectDone() {
+void PromptAction::OnElementChecksDone(
+    base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback) {
+  if (precondition_changed_)
+    UpdateUserActions();
+
+  // Calling wait_for_dom_callback with successful status is a way of asking the
+  // WaitForDom to end gracefully and call OnDoneWaitForDom with the status.
+  // Note that it is possible for WaitForDom to decide not to call
+  // OnDoneWaitForDom, if an interrupt triggers at the same time, so we cannot
+  // cancel the prompt and choose the suggestion just yet.
+  if (auto_select_choice_index_ >= 0) {
+    std::move(wait_for_dom_callback).Run(OkClientStatus());
+    return;
+  }
+
+  // Let WaitForDom know we're still waiting for an element.
+  std::move(wait_for_dom_callback).Run(ClientStatus(ELEMENT_RESOLUTION_FAILED));
+}
+
+void PromptAction::OnDoneWaitForDom(const ClientStatus& status) {
+  // Status doesn't matter; it's just forwarded from AutoSelectDone.
   if (auto_select_choice_index_ >= 0) {
     delegate_->CancelPrompt();
     OnSuggestionChosen(auto_select_choice_index_);
@@ -181,11 +194,6 @@
   }
   DCHECK(choice_index >= 0 && choice_index <= proto_.prompt().choices_size());
 
-  // Interrupt checks and timer.
-  timer_.reset();
-  precondition_checker_.reset();
-  auto_select_checker_.reset();
-
   PromptProto::Choice choice;
   UpdateProcessedAction(ACTION_APPLIED);
   *processed_action_proto_->mutable_prompt_choice() =
diff --git a/components/autofill_assistant/browser/actions/prompt_action.h b/components/autofill_assistant/browser/actions/prompt_action.h
index b93e0e7..41b876d5 100644
--- a/components/autofill_assistant/browser/actions/prompt_action.h
+++ b/components/autofill_assistant/browser/actions/prompt_action.h
@@ -12,7 +12,6 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
 #include "components/autofill_assistant/browser/actions/action.h"
 #include "components/autofill_assistant/browser/batch_element_checker.h"
 #include "components/autofill_assistant/browser/chip.h"
@@ -31,18 +30,19 @@
   // Overrides Action:
   void InternalProcessAction(ProcessActionCallback callback) override;
 
-  void RunPeriodicChecks();
+  void RegisterChecks(
+      BatchElementChecker* checker,
+      base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback);
   void SetupPreconditions();
   bool HasNonemptyPreconditions();
-  void CheckPreconditions();
   void OnPreconditionResult(size_t choice_index, bool result);
-  void OnPreconditionChecksDone();
   void UpdateUserActions();
   bool HasAutoSelect();
-  void CheckAutoSelect();
   void OnAutoSelectElementExists(int choice_index,
                                  const ClientStatus& element_status);
-  void OnAutoSelectDone();
+  void OnElementChecksDone(
+      base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback);
+  void OnDoneWaitForDom(const ClientStatus& status);
   void OnSuggestionChosen(int choice_index);
 
   ProcessActionCallback callback_;
@@ -59,17 +59,12 @@
   // the set of user actions must be updated.
   bool precondition_changed_ = false;
 
-  // Batch element checker for preconditions.
-  std::unique_ptr<BatchElementChecker> precondition_checker_;
+  // Batch element checker for preconditions and auto-selection.
+  std::unique_ptr<BatchElementChecker> element_checker_;
 
   // If >= 0, contains the index of the Choice to auto-select.
   int auto_select_choice_index_ = -1;
 
-  // Batch element checker for auto-selection, if any.
-  std::unique_ptr<BatchElementChecker> auto_select_checker_;
-
-  std::unique_ptr<base::RepeatingTimer> timer_;
-
   base::WeakPtrFactory<PromptAction> weak_ptr_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(PromptAction);
diff --git a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
index 5573223..ef324038 100644
--- a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/test/gmock_callback_support.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
+#include "base/timer/timer.h"
 #include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
 #include "components/autofill_assistant/browser/web/mock_web_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -42,10 +43,8 @@
     ON_CALL(mock_web_controller_, OnGetFieldValue(_, _))
         .WillByDefault(RunOnceCallback<1>(ClientStatus(), ""));
 
-    ON_CALL(mock_action_delegate_, RunElementChecks)
-        .WillByDefault(Invoke([this](BatchElementChecker* checker) {
-          checker->Run(&mock_web_controller_);
-        }));
+    EXPECT_CALL(mock_action_delegate_, OnWaitForDom(_, _, _, _))
+        .WillRepeatedly(Invoke(this, &PromptActionTest::FakeWaitForDom));
     ON_CALL(mock_action_delegate_, Prompt(_))
         .WillByDefault(Invoke(
             [this](std::unique_ptr<std::vector<UserAction>> user_actions) {
@@ -55,6 +54,65 @@
   }
 
  protected:
+  // Fakes ActionDelegate::WaitForDom.
+  //
+  // This simulates a WaitForDom that calls |check_elements_| every seconds
+  // until it gets a successful callback, then calls done_waiting_callback.
+  void FakeWaitForDom(
+      base::TimeDelta max_wait_time,
+      bool allow_interrupt,
+      base::RepeatingCallback<
+          void(BatchElementChecker*,
+               base::OnceCallback<void(const ClientStatus&)>)>& check_elements,
+      base::OnceCallback<void(const ClientStatus&)>& done_waiting_callback) {
+    RunFakeWaitForDom(check_elements, std::move(done_waiting_callback));
+  }
+
+  void RunFakeWaitForDom(
+      base::RepeatingCallback<
+          void(BatchElementChecker*,
+               base::OnceCallback<void(const ClientStatus&)>)> check_elements,
+      base::OnceCallback<void(const ClientStatus&)> done_waiting_callback) {
+    checker_ = std::make_unique<BatchElementChecker>();
+    has_check_elements_result_ = false;
+    check_elements.Run(checker_.get(),
+                       base::BindOnce(&PromptActionTest::OnCheckElementsDone,
+                                      base::Unretained(this)));
+    checker_->AddAllDoneCallback(base::BindOnce(
+        &PromptActionTest::OnWaitForDomDone, base::Unretained(this),
+        check_elements, std::move(done_waiting_callback)));
+    checker_->Run(&mock_web_controller_);
+  }
+
+  // Called from the check_elements callback passed to FakeWaitForDom.
+  void OnCheckElementsDone(const ClientStatus& result) {
+    ASSERT_FALSE(has_check_elements_result_);  // Duplicate calls
+    has_check_elements_result_ = true;
+    check_elements_result_ = result;
+  }
+
+  // Called by |checker_| once it's done and either ends the WaitForDom or
+  // schedule another run.
+  void OnWaitForDomDone(
+      base::RepeatingCallback<
+          void(BatchElementChecker*,
+               base::OnceCallback<void(const ClientStatus&)>)> check_elements,
+      base::OnceCallback<void(const ClientStatus&)> done_waiting_callback) {
+    ASSERT_TRUE(
+        has_check_elements_result_);  // OnCheckElementsDone() not called
+
+    if (check_elements_result_.ok()) {
+      std::move(done_waiting_callback).Run(check_elements_result_);
+    } else {
+      wait_for_dom_timer_ = std::make_unique<base::OneShotTimer>();
+      wait_for_dom_timer_->Start(
+          FROM_HERE, base::TimeDelta::FromSeconds(1),
+          base::BindOnce(&PromptActionTest::RunFakeWaitForDom,
+                         base::Unretained(this), check_elements,
+                         std::move(done_waiting_callback)));
+    }
+  }
+
   // task_env_ must be first to guarantee other field
   // creation run in that environment.
   base::test::TaskEnvironment task_env_;
@@ -65,6 +123,10 @@
   ActionProto proto_;
   PromptProto* prompt_proto_;
   std::unique_ptr<std::vector<UserAction>> user_actions_;
+  std::unique_ptr<BatchElementChecker> checker_;
+  bool has_check_elements_result_ = false;
+  ClientStatus check_elements_result_;
+  std::unique_ptr<base::OneShotTimer> wait_for_dom_timer_;
 };
 
 TEST_F(PromptActionTest, ChoicesMissing) {
@@ -185,7 +247,7 @@
   EXPECT_TRUE((*user_actions_)[0].HasCallback());
 }
 
-TEST_F(PromptActionTest, AutoSelect) {
+TEST_F(PromptActionTest, AutoSelectWhenElementExists) {
   auto* choice_proto = prompt_proto_->add_choices();
   choice_proto->set_server_payload("auto-select");
   choice_proto->mutable_auto_select_if_element_exists()->add_selectors(
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index 7dc91b20..8ff5925 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -541,9 +541,9 @@
   EnterState(AutofillAssistantState::STOPPED);
 }
 
-void Controller::EnterState(AutofillAssistantState state) {
+bool Controller::EnterState(AutofillAssistantState state) {
   if (state_ == state)
-    return;
+    return false;
 
   DVLOG(2) << __func__ << ": " << state_ << " -> " << state;
 
@@ -569,6 +569,7 @@
   } else {
     StopPeriodicScriptChecks();
   }
+  return true;
 }
 
 void Controller::SetWebControllerForTest(
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h
index 9d34fd2..11294bcb 100644
--- a/components/autofill_assistant/browser/controller.h
+++ b/components/autofill_assistant/browser/controller.h
@@ -137,7 +137,7 @@
   void AddListener(ScriptExecutorDelegate::Listener* listener) override;
   void RemoveListener(ScriptExecutorDelegate::Listener* listener) override;
 
-  void EnterState(AutofillAssistantState state) override;
+  bool EnterState(AutofillAssistantState state) override;
   void SetCollectUserDataOptions(CollectUserDataOptions* options) override;
   void WriteUserData(
       base::OnceCallback<void(UserData*, UserData::FieldChange*)>) override;
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
index bd7f1be..14b6b5b5 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -62,8 +62,12 @@
   return "en-US";
 }
 
-void FakeScriptExecutorDelegate::EnterState(AutofillAssistantState state) {
-  state_ = state;
+bool FakeScriptExecutorDelegate::EnterState(AutofillAssistantState state) {
+  if (GetState() == state)
+    return false;
+
+  state_history_.emplace_back(state);
+  return true;
 }
 
 void FakeScriptExecutorDelegate::SetTouchableElementArea(
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h
index b93d62a..672c33f 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.h
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -37,7 +37,7 @@
   content::WebContents* GetWebContents() override;
   std::string GetAccountEmailAddress() override;
   std::string GetLocale() override;
-  void EnterState(AutofillAssistantState state) override;
+  bool EnterState(AutofillAssistantState state) override;
   void SetTouchableElementArea(const ElementAreaProto& element) override;
   void SetStatusMessage(const std::string& message) override;
   std::string GetStatusMessage() const override;
@@ -83,7 +83,13 @@
     trigger_context_ = std::move(trigger_context);
   }
 
-  AutofillAssistantState GetState() { return state_; }
+  std::vector<AutofillAssistantState> GetStateHistory() {
+    return state_history_;
+  }
+  AutofillAssistantState GetState() {
+    return state_history_.empty() ? AutofillAssistantState::INACTIVE
+                                  : state_history_.back();
+  }
 
   Details* GetDetails() { return details_.get(); }
 
@@ -113,7 +119,7 @@
   WebController* web_controller_ = nullptr;
   ClientMemory memory_;
   std::unique_ptr<TriggerContext> trigger_context_;
-  AutofillAssistantState state_ = AutofillAssistantState::INACTIVE;
+  std::vector<AutofillAssistantState> state_history_;
   std::string status_message_;
   std::unique_ptr<Details> details_;
   std::unique_ptr<InfoBox> info_box_;
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 853025e..ec17652 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -231,6 +231,7 @@
     UserData* user_data,
     const UserModel* user_model) {
   delegate_->EnterState(AutofillAssistantState::RUNNING);
+  delegate_->SetUserActions(nullptr);
   std::move(callback).Run(user_data, user_model);
 }
 
@@ -272,21 +273,6 @@
 
 void ScriptExecutor::Prompt(
     std::unique_ptr<std::vector<UserAction>> user_actions) {
-  if (touchable_element_area_) {
-    // Prompt() reproduces the end-of-script appearance and behavior during
-    // script execution. This includes allowing access to touchable elements,
-    // set through a previous call to the focus action with touchable_elements
-    // set.
-    delegate_->SetTouchableElementArea(*touchable_element_area_);
-
-    // The touchable_elements_ currently set in the script is reset, so that it
-    // won't affect the real end of the script.
-    touchable_element_area_.reset();
-
-    // The touchable element and overlays are cleared again in
-    // ScriptExecutor::OnChosen or ScriptExecutor::ClearChips
-  }
-
   // We change the chips callback with a callback that cleans up the state
   // before calling the initial callback.
   for (auto& user_action : *user_actions) {
@@ -297,7 +283,17 @@
                                               weak_ptr_factory_.GetWeakPtr()));
   }
 
-  delegate_->EnterState(AutofillAssistantState::PROMPT);
+  if (delegate_->EnterState(AutofillAssistantState::PROMPT) &&
+      touchable_element_area_) {
+    // Prompt() reproduces the end-of-script appearance and behavior during
+    // script execution. This includes allowing access to touchable elements,
+    // set through a previous call to the focus action with touchable_elements
+    // set.
+    delegate_->SetTouchableElementArea(*touchable_element_area_);
+
+    // The touchable element and overlays are cleared in
+    // ScriptExecutor::CleanUpAfterPrompt
+  }
   delegate_->SetUserActions(std::move(user_actions));
 }
 
@@ -307,6 +303,10 @@
 }
 
 void ScriptExecutor::CleanUpAfterPrompt() {
+  // Mark touchable_elements_ as consumed, so that it won't affect the next
+  // prompt or the end of the script.
+  touchable_element_area_.reset();
+
   delegate_->ClearTouchableElementArea();
   delegate_->EnterState(AutofillAssistantState::RUNNING);
 }
@@ -845,7 +845,6 @@
     for (const auto* interrupt : *main_script_->ordered_interrupts_) {
       if (ran_interrupts_.find(interrupt->handle.path) !=
           ran_interrupts_.end()) {
-        // Only run an interrupt once in a WaitForDomOperation, to avoid loops.
         continue;
       }
 
@@ -881,7 +880,15 @@
 
 void ScriptExecutor::WaitForDomOperation::OnAllChecksDone(
     base::OnceCallback<void(const ClientStatus&)> report_attempt_result) {
-  if (!runnable_interrupts_.empty()) {
+  if (runnable_interrupts_.empty()) {
+    // Since no interrupts fired, allow previously-run interrupts to be run
+    // again in the next round. This is meant to give elements one round to
+    // disappear and avoid the simplest form of loops. A round with interrupts
+    // firing doesn't count as one round here, because an interrupt can run
+    // quickly and return immediately, without waiting for
+    // periodic_element_check_interval.
+    ran_interrupts_.clear();
+  } else {
     // We must go through runnable_interrupts_ to make sure priority order is
     // respected in case more than one interrupt is ready to run.
     for (const auto* interrupt : *main_script_->ordered_interrupts_) {
@@ -905,6 +912,8 @@
       main_script_->last_global_payload_, main_script_->initial_script_payload_,
       /* listener= */ this, main_script_->scripts_state_, &no_interrupts_,
       delegate_);
+  delegate_->EnterState(AutofillAssistantState::RUNNING);
+  delegate_->SetUserActions(nullptr);
   interrupt_executor_->Run(
       base::BindOnce(&ScriptExecutor::WaitForDomOperation::OnInterruptDone,
                      base::Unretained(this)));
@@ -919,6 +928,7 @@
     return;
   }
   RestoreStatusMessage();
+  RestorePreInterruptScroll();
 
   // Restart. We use the original wait time since the interruption could have
   // triggered any kind of actions, including actions that wait on the user. We
@@ -940,7 +950,6 @@
   if (!callback_)
     return;
 
-  RestorePreInterruptScroll();
   std::move(callback_).Run(element_status, result);
 }
 
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index 41c94e8..edb91e2 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -308,7 +308,8 @@
     // The status message that was displayed when the interrupt started.
     std::string pre_interrupt_status_;
 
-    // Paths of the interrupts that were run during the current action.
+    // Paths of the interrupts that were just run. These interrupts are
+    // prevented from firing for one round.
     std::set<std::string> ran_interrupts_;
 
     RetryTimer retry_timer_;
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h
index 2b95199..c42e3436 100644
--- a/components/autofill_assistant/browser/script_executor_delegate.h
+++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -59,7 +59,9 @@
   virtual content::WebContents* GetWebContents() = 0;
   virtual std::string GetAccountEmailAddress() = 0;
   virtual std::string GetLocale() = 0;
-  virtual void EnterState(AutofillAssistantState state) = 0;
+
+  // Enters the given state. Returns true if the state was changed.
+  virtual bool EnterState(AutofillAssistantState state) = 0;
 
   // Make the area of the screen that correspond to the given elements
   // touchable.
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc
index 8fdd457..5a0ce146 100644
--- a/components/autofill_assistant/browser/script_executor_unittest.cc
+++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -828,6 +828,119 @@
               Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS)));
 }
 
+TEST_F(ScriptExecutorTest, RunInterruptDuringPrompt) {
+  SetupInterrupt("interrupt", "interrupt_trigger");
+
+  // Main script has a prompt with an "auto_select" element. This functions very
+  // much like a WaitForDom, except for the UI changes triggered by the switches
+  // between PROMPT and RUNNING states.
+  ActionsResponseProto interruptible;
+  auto* prompt_action = interruptible.add_actions()->mutable_prompt();
+  prompt_action->set_allow_interrupt(true);
+  prompt_action->add_choices()
+      ->mutable_auto_select_if_element_exists()
+      ->add_selectors("end_prompt");
+  interruptible.add_actions()->mutable_tell()->set_message("done");
+  EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _))
+      .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible)));
+
+  EXPECT_CALL(mock_web_controller_,
+              OnElementCheck(Eq(Selector({"interrupt_trigger"})), _))
+      .WillOnce(RunOnceCallback<1>(OkClientStatus()))
+      .WillRepeatedly(
+          RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)));
+
+  EXPECT_CALL(mock_web_controller_,
+              OnElementCheck(Eq(Selector({"end_prompt"})), _))
+      .WillRepeatedly(RunOnceCallback<1>(OkClientStatus()));
+
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _))
+      .WillRepeatedly(RunOnceCallback<4>(true, ""));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  executor_->Run(executor_callback_.Get());
+
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS)));
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS)));
+
+  // Expected scenario:
+  // - show prompt (enter PROMPT state)
+  // - notice interrupt_trigger element
+  // - run interrupt (enter RUNNING state)
+  // - show prompt again (enter PROMPT state)
+  // - notice end_prompt element
+  // - end prompt, continue main script (enter RUNNING state)
+  // - run tell, which sets message to "done"
+  EXPECT_THAT(delegate_.GetStateHistory(),
+              ElementsAre(AutofillAssistantState::PROMPT,
+                          AutofillAssistantState::RUNNING,
+                          AutofillAssistantState::PROMPT,
+                          AutofillAssistantState::RUNNING));
+  EXPECT_EQ("done", delegate_.GetStatusMessage());
+}
+
+TEST_F(ScriptExecutorTest, RunInterruptMultipleTimesDuringPrompt) {
+  SetupInterrupt("interrupt", "interrupt_trigger");
+
+  // Main script has a prompt with an "auto_select" element. This functions very
+  // much like a WaitForDom, except for the UI changes triggered by the switches
+  // between PROMPT and RUNNING states.
+  ActionsResponseProto interruptible;
+  auto* prompt_action = interruptible.add_actions()->mutable_prompt();
+  prompt_action->set_allow_interrupt(true);
+  prompt_action->add_choices()
+      ->mutable_auto_select_if_element_exists()
+      ->add_selectors("end_prompt");
+  EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _))
+      .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible)));
+
+  // interrupt_trigger goes away and come back, which means that the interrupt
+  // will be run twice.
+  EXPECT_CALL(mock_web_controller_,
+              OnElementCheck(Eq(Selector({"interrupt_trigger"})), _))
+      .WillOnce(RunOnceCallback<1>(OkClientStatus()))
+      .WillOnce(RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)))
+      .WillOnce(RunOnceCallback<1>(OkClientStatus()))
+      .WillRepeatedly(
+          RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)));
+
+  // It takes a several rounds for end_prompt to appear, which gives time for
+  // the interrupt to run.
+  EXPECT_CALL(mock_web_controller_,
+              OnElementCheck(Eq(Selector({"end_prompt"})), _))
+      .WillOnce(RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)))
+      .WillOnce(RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)))
+      .WillOnce(RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)))
+      .WillOnce(RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)))
+      .WillRepeatedly(RunOnceCallback<1>(OkClientStatus()));
+
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _))
+      .WillRepeatedly(RunOnceCallback<4>(true, ""));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  executor_->Run(executor_callback_.Get());
+  for (int try_count = 0;
+       try_count < 10 && scripts_state_[kScriptPath] == SCRIPT_STATUS_RUNNING;
+       try_count++) {
+    task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  }
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS)));
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS)));
+
+  EXPECT_THAT(
+      delegate_.GetStateHistory(),
+      ElementsAre(
+          AutofillAssistantState::PROMPT, AutofillAssistantState::RUNNING,
+          AutofillAssistantState::PROMPT, AutofillAssistantState::RUNNING,
+          AutofillAssistantState::PROMPT, AutofillAssistantState::RUNNING));
+}
+
 TEST_F(ScriptExecutorTest, UpdateScriptListGetNext) {
   should_update_scripts_ = false;
   scripts_update_.clear();
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 2c50d26..8d02049 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -1208,6 +1208,10 @@
     reserved 13;
   }
   repeated Choice choices = 4;
+
+  // If true, run scripts flagged with 'interrupt=true' as soon as their
+  // preconditions match, then go back to the prompt.
+  optional bool allow_interrupt = 5;
 }
 
 message ContactDetailsProto {
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp
index 1c61a21..5a99178 100644
--- a/components/autofill_payments_strings.grdp
+++ b/components/autofill_payments_strings.grdp
@@ -483,6 +483,22 @@
     <message name="IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL" desc="Text shown in the button in the Autofill dropdown menu when a credit card form field is queried, to offer the option to use a virtual card.">
       Use a virtual card number...
     </message>
+    <message name="IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CONTENT_TITLE" desc="The title shown in the Autofill virtual card selection dialog. This dialog offers available virtual credit cards for users to choose to fill the form with. [ICU Syntax]">
+      {NUM_CARDS, plural,
+      =1 {Use a virtual number for this card}
+      other {Select a card}}
+    </message>
+    <message name="IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CONTENT_EXPLANATION" desc="The detailed explanations shown in the Autofill virtual card selection dialog. This dialog offers available virtual credit cards for users to choose to fill the form with. [ICU Syntax]">
+      {NUM_CARDS, plural,
+      =1 {This card will be charged when you pay, but its real number won't be shared with this site. For extra security, a temporary CVC will be generated.}
+      other {The card you select will be charged when you pay, but its real number won't be shared with this site. For extra security, a temporary CVC will be generated.}}
+    </message>
+    <message name="IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_OK_BUTTON_LABEL" desc="Text shown in the OK button in the Autofill virtual card selection dialog. This dialog offers all available virtual credit cards for users to choose.">
+      Continue
+    </message>
+    <message name="IDS_AUTOFILL_VIRTUAL_CARD_SELECTION_DIALOG_CANCEL_BUTTON_LABEL" desc="Text shown in the Cancel button in the Autofill virtual card selection dialog. This dialog offers all available virtual credit cards for users to choose.">
+      Cancel
+    </message>
   </if>
 
   <message name="IDS_AUTOFILL_SAVE_UPI_PROMPT_TITLE" desc="Title text for the prompt to save a UPI ID locally, which the user used in a page. UPI is an online payment method. A UPI ID is an email-like string.">
diff --git a/components/dom_distiller/core/javascript/dom_distiller_viewer.js b/components/dom_distiller/core/javascript/dom_distiller_viewer.js
index f40e565..f66089f 100644
--- a/components/dom_distiller/core/javascript/dom_distiller_viewer.js
+++ b/components/dom_distiller/core/javascript/dom_distiller_viewer.js
@@ -169,8 +169,17 @@
 maybeSetWebFont();
 updateSliderFromElement(document.querySelector('#font-size-selection'));
 
-const pincher = (function() {
-  'use strict';
+// The zooming speed relative to pinching speed.
+const FONT_SCALE_MULTIPLIER = 0.5;
+
+const MIN_SPAN_LENGTH = 20;
+
+// This has to be in sync with 'font-size' in distilledpage.css.
+// This value is hard-coded because JS might be injected before CSS is ready.
+// See crbug.com/1004663.
+const baseSize = 14;
+
+class Pincher {
   // When users pinch in Reader Mode, the page would zoom in or out as if it
   // is a normal web page allowing user-zoom. At the end of pinch gesture, the
   // page would do text reflow. These pinch-to-zoom and text reflow effects
@@ -187,70 +196,70 @@
   //
   // TODO(wychen): Improve scroll position when elementFromPoint is body.
 
-  let pinching = false;
-  let fontSizeAnchor = 1.0;
+  constructor() {
+    this.pinching = false;
+    this.fontSizeAnchor = 1.0;
 
-  let focusElement = null;
-  let focusPos = 0;
-  let initClientMid;
+    this.focusElement = null;
+    this.focusPos = 0;
+    this.initClientMid = null;
 
-  let clampedScale = 1;
+    this.clampedScale = 1.0;
 
-  let lastSpan;
-  let lastClientMid;
+    this.lastSpan = null;
+    this.lastClientMid = null;
 
-  let scale = 1;
-  let shiftX;
-  let shiftY;
+    this.scale = 1.0;
+    this.shiftX = 0;
+    this.shiftY = 0;
+  }
 
-  // The zooming speed relative to pinching speed.
-  const FONT_SCALE_MULTIPLIER = 0.5;
-
-  const MIN_SPAN_LENGTH = 20;
-
-  // This has to be in sync with 'font-size' in distilledpage.css.
-  // This value is hard-coded because JS might be injected before CSS is ready.
-  // See crbug.com/1004663.
-  const baseSize = 14;
-
-  const refreshTransform = function() {
-    const slowedScale = Math.exp(Math.log(scale) * FONT_SCALE_MULTIPLIER);
-    clampedScale = Math.max(0.5, Math.min(2.0, fontSizeAnchor * slowedScale));
+  /** @private */
+  refreshTransform_() {
+    const slowedScale = Math.exp(Math.log(this.scale) * FONT_SCALE_MULTIPLIER);
+    this.clampedScale =
+        Math.max(0.5, Math.min(2.0, this.fontSizeAnchor * slowedScale));
 
     // Use "fake" 3D transform so that the layer is not repainted.
     // With 2D transform, the frame rate would be much lower.
     // clang-format off
     document.body.style.transform =
-        'translate3d(' + shiftX + 'px,'
-                       + shiftY + 'px, 0px)' +
-        'scale(' + clampedScale / fontSizeAnchor + ')';
+        'translate3d(' + this.shiftX + 'px,'
+                       + this.shiftY + 'px, 0px)' +
+        'scale(' + this.clampedScale / this.fontSizeAnchor + ')';
     // clang-format on
-  };
-
-  function saveCenter(clientMid) {
-    // Try to preserve the pinching center after text reflow.
-    // This is accurate to the HTML element level.
-    focusElement = document.elementFromPoint(clientMid.x, clientMid.y);
-    const rect = focusElement.getBoundingClientRect();
-    initClientMid = clientMid;
-    focusPos = (initClientMid.y - rect.top) / (rect.bottom - rect.top);
   }
 
-  function restoreCenter() {
-    const rect = focusElement.getBoundingClientRect();
-    const targetTop = focusPos * (rect.bottom - rect.top) + rect.top +
-        document.scrollingElement.scrollTop - (initClientMid.y + shiftY);
+  /** @private */
+  saveCenter_(clientMid) {
+    // Try to preserve the pinching center after text reflow.
+    // This is accurate to the HTML element level.
+    this.focusElement = document.elementFromPoint(clientMid.x, clientMid.y);
+    const rect = this.focusElement.getBoundingClientRect();
+    this.initClientMid = clientMid;
+    this.focusPos =
+        (this.initClientMid.y - rect.top) / (rect.bottom - rect.top);
+  }
+
+  /** @private */
+  restoreCenter_() {
+    const rect = this.focusElement.getBoundingClientRect();
+    const targetTop = this.focusPos * (rect.bottom - rect.top) + rect.top +
+        document.scrollingElement.scrollTop -
+        (this.initClientMid.y + this.shiftY);
     document.scrollingElement.scrollTop = targetTop;
   }
 
-  function endPinch() {
-    pinching = false;
+  /** @private */
+  endPinch_() {
+    this.pinching = false;
 
     document.body.style.transformOrigin = '';
     document.body.style.transform = '';
-    document.documentElement.style.fontSize = clampedScale * baseSize + 'px';
+    document.documentElement.style.fontSize =
+        this.clampedScale * baseSize + 'px';
 
-    restoreCenter();
+    this.restoreCenter_();
 
     let img = document.getElementById('fontscaling-img');
     if (!img) {
@@ -259,12 +268,13 @@
       img.style.display = 'none';
       document.body.appendChild(img);
     }
-    img.src = '/savefontscaling/' + clampedScale;
+    img.src = '/savefontscaling/' + this.clampedScale;
   }
 
-  function touchSpan(e) {
+  /** @private */
+  touchSpan_(e) {
     const count = e.touches.length;
-    const mid = touchClientMid(e);
+    const mid = this.touchClientMid_(e);
     let sum = 0;
     for (let i = 0; i < count; i++) {
       const dx = (e.touches[i].clientX - mid.x);
@@ -275,7 +285,8 @@
     return Math.max(MIN_SPAN_LENGTH, sum / count);
   }
 
-  function touchClientMid(e) {
+  /** @private */
+  touchClientMid_(e) {
     const count = e.touches.length;
     let sumX = 0;
     let sumY = 0;
@@ -286,127 +297,129 @@
     return {x: sumX / count, y: sumY / count};
   }
 
-  function touchPageMid(e) {
-    const clientMid = touchClientMid(e);
+  /** @private */
+  touchPageMid_(e) {
+    const clientMid = this.touchClientMid_(e);
     return {
       x: clientMid.x - e.touches[0].clientX + e.touches[0].pageX,
       y: clientMid.y - e.touches[0].clientY + e.touches[0].pageY
     };
   }
 
-  return {
-    handleTouchStart: function(e) {
-      if (e.touches.length < 2) {
-        return;
-      }
-      e.preventDefault();
-
-      const span = touchSpan(e);
-      const clientMid = touchClientMid(e);
-
-      if (e.touches.length > 2) {
-        lastSpan = span;
-        lastClientMid = clientMid;
-        refreshTransform();
-        return;
-      }
-
-      scale = 1;
-      shiftX = 0;
-      shiftY = 0;
-
-      pinching = true;
-      fontSizeAnchor =
-          parseFloat(getComputedStyle(document.documentElement).fontSize) /
-          baseSize;
-
-      const pinchOrigin = touchPageMid(e);
-      document.body.style.transformOrigin =
-          pinchOrigin.x + 'px ' + pinchOrigin.y + 'px';
-
-      saveCenter(clientMid);
-
-      lastSpan = span;
-      lastClientMid = clientMid;
-
-      refreshTransform();
-    },
-
-    handleTouchMove: function(e) {
-      if (!pinching) {
-        return;
-      }
-      if (e.touches.length < 2) {
-        return;
-      }
-      e.preventDefault();
-
-      const span = touchSpan(e);
-      const clientMid = touchClientMid(e);
-
-      scale *= touchSpan(e) / lastSpan;
-      shiftX += clientMid.x - lastClientMid.x;
-      shiftY += clientMid.y - lastClientMid.y;
-
-      refreshTransform();
-
-      lastSpan = span;
-      lastClientMid = clientMid;
-    },
-
-    handleTouchEnd: function(e) {
-      if (!pinching) {
-        return;
-      }
-      e.preventDefault();
-
-      const span = touchSpan(e);
-      const clientMid = touchClientMid(e);
-
-      if (e.touches.length >= 2) {
-        lastSpan = span;
-        lastClientMid = clientMid;
-        refreshTransform();
-        return;
-      }
-
-      endPinch();
-    },
-
-    handleTouchCancel: function(e) {
-      if (!pinching) {
-        return;
-      }
-      endPinch();
-    },
-
-    reset: function() {
-      scale = 1;
-      shiftX = 0;
-      shiftY = 0;
-      clampedScale = 1;
-      document.documentElement.style.fontSize = clampedScale * baseSize + 'px';
-    },
-
-    status: function() {
-      return {
-        scale: scale,
-        clampedScale: clampedScale,
-        shiftX: shiftX,
-        shiftY: shiftY
-      };
-    },
-
-    useFontScaling: function(scaling) {
-      saveCenter({x: window.innerWidth / 2, y: window.innerHeight / 2});
-      shiftX = 0;
-      shiftY = 0;
-      document.documentElement.style.fontSize = scaling * baseSize + 'px';
-      clampedScale = scaling;
-      restoreCenter();
+  handleTouchStart(e) {
+    if (e.touches.length < 2) {
+      return;
     }
-  };
-}());
+    e.preventDefault();
+
+    const span = this.touchSpan_(e);
+    const clientMid = this.touchClientMid_(e);
+
+    if (e.touches.length > 2) {
+      this.lastSpan = span;
+      this.lastClientMid = clientMid;
+      this.refreshTransform_();
+      return;
+    }
+
+    this.scale = 1;
+    this.shiftX = 0;
+    this.shiftY = 0;
+
+    this.pinching = true;
+    this.fontSizeAnchor =
+        parseFloat(getComputedStyle(document.documentElement).fontSize) /
+        baseSize;
+
+    const pinchOrigin = this.touchPageMid_(e);
+    document.body.style.transformOrigin =
+        pinchOrigin.x + 'px ' + pinchOrigin.y + 'px';
+
+    this.saveCenter_(clientMid);
+
+    this.lastSpan = span;
+    this.lastClientMid = clientMid;
+
+    this.refreshTransform_();
+  }
+
+  handleTouchMove(e) {
+    if (!this.pinching) {
+      return;
+    }
+    if (e.touches.length < 2) {
+      return;
+    }
+    e.preventDefault();
+
+    const span = this.touchSpan_(e);
+    const clientMid = this.touchClientMid_(e);
+
+    this.scale *= this.touchSpan_(e) / this.lastSpan;
+    this.shiftX += clientMid.x - this.lastClientMid.x;
+    this.shiftY += clientMid.y - this.lastClientMid.y;
+
+    this.refreshTransform_();
+
+    this.lastSpan = span;
+    this.lastClientMid = clientMid;
+  }
+
+  handleTouchEnd(e) {
+    if (!this.pinching) {
+      return;
+    }
+    e.preventDefault();
+
+    const span = this.touchSpan_(e);
+    const clientMid = this.touchClientMid_(e);
+
+    if (e.touches.length >= 2) {
+      this.lastSpan = span;
+      this.lastClientMid = clientMid;
+      this.refreshTransform_();
+      return;
+    }
+
+    this.endPinch_();
+  }
+
+  handleTouchCancel(e) {
+    if (!this.pinching) {
+      return;
+    }
+    this.endPinch_();
+  }
+
+  reset() {
+    this.scale = 1;
+    this.shiftX = 0;
+    this.shiftY = 0;
+    this.clampedScale = 1;
+    document.documentElement.style.fontSize =
+        this.clampedScale * baseSize + 'px';
+  }
+
+  status() {
+    return {
+      scale: this.scale,
+      clampedScale: this.clampedScale,
+      shiftX: this.shiftX,
+      shiftY: this.shiftY
+    };
+  }
+
+  useFontScaling(scaling) {
+    this.saveCenter_({x: window.innerWidth / 2, y: window.innerHeight / 2});
+    this.shiftX = 0;
+    this.shiftY = 0;
+    document.documentElement.style.fontSize = scaling * baseSize + 'px';
+    this.clampedScale = scaling;
+    this.restoreCenter_();
+  }
+}
+
+const pincher = new Pincher;
 
 window.addEventListener(
     'touchstart', pincher.handleTouchStart, {passive: false});
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc
index 2ae7841..ac362c55 100644
--- a/components/download/internal/common/download_item_impl.cc
+++ b/components/download/internal/common/download_item_impl.cc
@@ -1468,9 +1468,14 @@
     URLLoaderFactoryProvider::URLLoaderFactoryProviderPtr
         url_loader_factory_provider) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  CHECK(!download_file_) << "last interrupt reason: "
-                         << DownloadInterruptReasonToString(last_reason_)
-                         << ", state: " << DebugDownloadStateString(state_);
+  if (download_file_) {
+    LOG(ERROR) << "last interrupt reason: "
+               << DownloadInterruptReasonToString(last_reason_)
+               << ", state: " << DebugDownloadStateString(state_)
+               << ", state before last interruption: "
+               << DebugDownloadStateString(state_before_interruption_);
+  }
+  CHECK(!download_file_);
   DVLOG(20) << __func__ << "() this=" << DebugString(true);
   RecordDownloadCountWithSource(START_COUNT, download_source_);
 
@@ -2116,6 +2121,7 @@
   // target-pending, which is something we don't want to do. Perhaps we should
   // explicitly transition to target-resolved prior to switching to interrupted.
   DCHECK_EQ(last_reason_, reason);
+  state_before_interruption_ = state_;
   TransitionTo(INTERRUPTED_INTERNAL);
   delegate_->DownloadInterrupted(this);
   AutoResumeIfValid();
diff --git a/components/download/public/common/download_item_impl.h b/components/download/public/common/download_item_impl.h
index f3671fc6..767fd5b 100644
--- a/components/download/public/common/download_item_impl.h
+++ b/components/download/public/common/download_item_impl.h
@@ -730,6 +730,10 @@
   // The current state of this download.
   DownloadInternalState state_ = INITIAL_INTERNAL;
 
+  // The state before download was interrupted.
+  // Remove this once http://crbug.com/1029746 is fixed.
+  DownloadInternalState state_before_interruption_ = INITIAL_INTERNAL;
+
   // Current danger type for the download.
   DownloadDangerType danger_type_ = DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
 
diff --git a/chrome/browser/policy/e2e_test/infra/__init__.py b/components/embedder_support/BUILD.gn
similarity index 64%
copy from chrome/browser/policy/e2e_test/infra/__init__.py
copy to components/embedder_support/BUILD.gn
index 9226ba6..701fbb0 100644
--- a/chrome/browser/policy/e2e_test/infra/__init__.py
+++ b/components/embedder_support/BUILD.gn
@@ -2,4 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from chrome_ent_test_case import ChromeEnterpriseTestCase
\ No newline at end of file
+static_library("switches") {
+  sources = [
+    "switches.cc",
+    "switches.h",
+  ]
+}
diff --git a/components/embedder_support/switches.cc b/components/embedder_support/switches.cc
new file mode 100644
index 0000000..d84111b
--- /dev/null
+++ b/components/embedder_support/switches.cc
@@ -0,0 +1,12 @@
+// 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 "components/embedder_support/switches.h"
+
+namespace embedder_support {
+
+// Disables pop-up blocking.
+const char kDisablePopupBlocking[] = "disable-popup-blocking";
+
+}  // namespace embedder_support
diff --git a/components/embedder_support/switches.h b/components/embedder_support/switches.h
new file mode 100644
index 0000000..336b221
--- /dev/null
+++ b/components/embedder_support/switches.h
@@ -0,0 +1,18 @@
+// 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.
+
+// Defines the shared command-line switches used by code in the Chrome
+// directory that don't have anywhere more specific to go.
+
+#ifndef COMPONENTS_EMBEDDER_SUPPORT_SWITCHES_H_
+#define COMPONENTS_EMBEDDER_SUPPORT_SWITCHES_H_
+
+// Switches used by multiple embedders.
+namespace embedder_support {
+
+extern const char kDisablePopupBlocking[];
+
+}  // namespace embedder_support
+
+#endif  // COMPONENTS_EMBEDDER_SUPPORT_SWITCHES_H_
diff --git a/components/exo/data_source.cc b/components/exo/data_source.cc
index 153e7f467..ef0a397 100644
--- a/components/exo/data_source.cc
+++ b/components/exo/data_source.cc
@@ -11,6 +11,7 @@
 #include "base/files/file_util.h"
 #include "base/i18n/character_encoding.h"
 #include "base/i18n/icu_string_conversions.h"
+#include "base/optional.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
@@ -43,7 +44,7 @@
 constexpr char kImagePNG[] = "image/png";
 constexpr char kImageAPNG[] = "image/apng";
 
-std::vector<uint8_t> ReadDataOnWorkerThread(base::ScopedFD fd) {
+base::Optional<std::vector<uint8_t>> ReadDataOnWorkerThread(base::ScopedFD fd) {
   constexpr size_t kChunkSize = 1024;
   std::vector<uint8_t> bytes;
   while (true) {
@@ -57,7 +58,7 @@
       return bytes;
     if (bytes_read < 0) {
       PLOG(ERROR) << "Failed to read selection data from clipboard";
-      return std::vector<uint8_t>();
+      return base::nullopt;
     }
   }
 }
@@ -216,15 +217,20 @@
       {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
       base::BindOnce(&ReadDataOnWorkerThread, std::move(read_fd)),
-      base::BindOnce(&DataSource::OnDataRead,
-                     read_data_weak_ptr_factory_.GetWeakPtr(),
-                     std::move(callback), mime_type));
+      base::BindOnce(
+          &DataSource::OnDataRead, read_data_weak_ptr_factory_.GetWeakPtr(),
+          std::move(callback), mime_type, std::move(failure_callback)));
 }
 
 void DataSource::OnDataRead(ReadDataCallback callback,
                             const std::string& mime_type,
-                            const std::vector<uint8_t>& data) {
-  std::move(callback).Run(mime_type, data);
+                            base::OnceClosure failure_callback,
+                            const base::Optional<std::vector<uint8_t>>& data) {
+  if (!data) {
+    std::move(failure_callback).Run();
+    return;
+  }
+  std::move(callback).Run(mime_type, *data);
 }
 
 void DataSource::GetDataForPreferredMimeTypes(
@@ -302,7 +308,7 @@
   std::move(callback).Run(mime_type, std::move(output));
 }
 
-bool DataSource::CanBeDataSourceForCopy(Surface *surface) const {
+bool DataSource::CanBeDataSourceForCopy(Surface* surface) const {
   return delegate_->CanAcceptDataEventsForSurface(surface);
 }
 
diff --git a/components/exo/data_source.h b/components/exo/data_source.h
index 2182a67..bc669cc 100644
--- a/components/exo/data_source.h
+++ b/components/exo/data_source.h
@@ -79,7 +79,7 @@
   void ReadDataForTesting(const std::string& mime_type,
                           ReadDataCallback callback);
 
-  bool CanBeDataSourceForCopy(Surface *surface) const;
+  bool CanBeDataSourceForCopy(Surface* surface) const;
 
  private:
   // Reads data from the source. Then |callback| is invoked with read data. If
@@ -91,7 +91,8 @@
 
   void OnDataRead(ReadDataCallback callback,
                   const std::string& mime_type,
-                  const std::vector<uint8_t>&);
+                  base::OnceClosure failure_callback,
+                  const base::Optional<std::vector<uint8_t>>& data);
 
   void OnTextRead(ReadTextDataCallback callback,
                   const std::string& mime_type,
diff --git a/components/exo/seat.cc b/components/exo/seat.cc
index 4cd00bc5..af1838f 100644
--- a/components/exo/seat.cc
+++ b/components/exo/seat.cc
@@ -94,16 +94,8 @@
 
 void Seat::SetSelection(DataSource* source) {
   Surface* focused_surface = GetFocusedSurface();
-  if (source && !source->CanBeDataSourceForCopy(focused_surface)) {
+  if (!source || !source->CanBeDataSourceForCopy(focused_surface))
     return;
-  }
-
-  if (!source) {
-    ui::Clipboard::GetForCurrentThread()->Clear(
-        ui::ClipboardBuffer::kCopyPaste);
-    // selection_source_ is Cancelled() and reset() in OnClipboardDataChanged().
-    return;
-  }
 
   if (selection_source_) {
     if (selection_source_->get() == source)
diff --git a/components/exo/seat_unittest.cc b/components/exo/seat_unittest.cc
index da663ba..6c8422d 100644
--- a/components/exo/seat_unittest.cc
+++ b/components/exo/seat_unittest.cc
@@ -424,7 +424,12 @@
 
   RunReadingTask();
 
-  // Should clear the clipboard.
+  {
+    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
+    writer.WriteText(base::UTF8ToUTF16("Golden data"));
+  }
+
+  // Should not affect the current state of the clipboard.
   seat.SetSelection(nullptr);
 
   ASSERT_TRUE(delegate.cancelled());
@@ -432,7 +437,7 @@
   std::string clipboard;
   ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
       ui::ClipboardBuffer::kCopyPaste, &clipboard);
-  EXPECT_EQ(clipboard, "");
+  EXPECT_EQ(clipboard, "Golden data");
 }
 
 TEST_F(SeatTest, PressedKeys) {
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
index 92f14f1..f14d4ca 100644
--- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
+++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -15,6 +15,7 @@
  */
 @StringDef({FeatureConstants.DOWNLOAD_PAGE_FEATURE,
         FeatureConstants.DOWNLOAD_PAGE_SCREENSHOT_FEATURE, FeatureConstants.DOWNLOAD_HOME_FEATURE,
+        FeatureConstants.CHROME_DUET_HOME_BUTTON_FEATURE,
         FeatureConstants.CHROME_DUET_SEARCH_FEATURE,
         FeatureConstants.CHROME_DUET_TAB_SWITCHER_FEATURE,
         FeatureConstants.CHROME_HOME_EXPAND_FEATURE,
diff --git a/components/omnibox/browser/omnibox_edit_model.h b/components/omnibox/browser/omnibox_edit_model.h
index 9193902db..6c5f6f1 100644
--- a/components/omnibox/browser/omnibox_edit_model.h
+++ b/components/omnibox/browser/omnibox_edit_model.h
@@ -385,6 +385,10 @@
   // Just forwards the call to the OmniboxView referred within.
   void SetAccessibilityLabel(const AutocompleteMatch& match);
 
+  // Reverts the edit box from a temporary text back to the original user text.
+  // Also resets the popup to the initial state.
+  void RevertTemporaryTextAndPopup();
+
  private:
   friend class OmniboxControllerTest;
   FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKey);
@@ -440,10 +444,6 @@
   void GetInfoForCurrentText(AutocompleteMatch* match,
                              GURL* alternate_nav_url) const;
 
-  // Reverts the edit box from a temporary text back to the original user text.
-  // Also resets the popup to the initial state.
-  void RevertTemporaryTextAndPopup();
-
   // Accepts current keyword if the user just typed a space at the end of
   // |new_text|.  This handles both of the following cases:
   //   (assume "foo" is a keyword, | is the input caret, [] is selected text)
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc
index 0591d2d..bd3de71 100644
--- a/components/omnibox/browser/search_suggestion_parser.cc
+++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -467,6 +467,7 @@
   for (size_t index = 0; results_list->GetString(index, &suggestion); ++index) {
     // Google search may return empty suggestions for weird input characters,
     // they make no sense at all and can cause problems in our code.
+    suggestion = base::CollapseWhitespace(suggestion, false);
     if (suggestion.empty())
       continue;
 
@@ -513,6 +514,9 @@
           // Calculator results include a "= " prefix but we don't want to
           // include this in the search terms.
           suggestion.erase(0, 2);
+          // Unlikely to happen, but better to be safe.
+          if (base::CollapseWhitespace(suggestion, false).empty())
+            continue;
         }
         if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_DESKTOP) {
           annotation = has_equals_prefix ? suggestion : match_contents;
@@ -559,7 +563,7 @@
 
       bool should_prefetch = static_cast<int>(index) == prefetch_index;
       results->suggest_results.push_back(SuggestResult(
-          base::CollapseWhitespace(suggestion, false),
+          suggestion,
           match_type,
           subtype_identifier,
           base::CollapseWhitespace(match_contents, false),
diff --git a/components/open_from_clipboard/clipboard_recent_content_impl_ios.mm b/components/open_from_clipboard/clipboard_recent_content_impl_ios.mm
index 7043afd..791833a2 100644
--- a/components/open_from_clipboard/clipboard_recent_content_impl_ios.mm
+++ b/components/open_from_clipboard/clipboard_recent_content_impl_ios.mm
@@ -230,6 +230,14 @@
 
 - (NSURL*)URLFromPasteboard {
   NSURL* url = [UIPasteboard generalPasteboard].URL;
+  // Usually, even if the user copies plaintext, if it looks like a URL, the URL
+  // property is filled. Sometimes, this doesn't happen, for instance when the
+  // pasteboard is sync'd from a Mac to the iOS simulator. In this case,
+  // fallback and manually check whether the pasteboard contains a url-like
+  // string.
+  if (!url) {
+    url = [NSURL URLWithString:UIPasteboard.generalPasteboard.string];
+  }
   if (![self.authorizedSchemes containsObject:url.scheme]) {
     return nil;
   }
diff --git a/components/os_crypt/key_storage_libsecret.cc b/components/os_crypt/key_storage_libsecret.cc
index b8a3d7c..975a69e 100644
--- a/components/os_crypt/key_storage_libsecret.cc
+++ b/components/os_crypt/key_storage_libsecret.cc
@@ -7,6 +7,7 @@
 #include "base/base64.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
 #include "build/branding_buildflags.h"
 #include "components/os_crypt/libsecret_util_linux.h"
 
@@ -49,6 +50,25 @@
   return secret_value;
 }
 
+// Checks the timestamps of the secret item and prints findings to logs. We
+// presume that at most one secret item can be present.
+void AnalyseKeyHistory(GList* secret_items) {
+  GList* first = g_list_first(secret_items);
+  if (first == nullptr)
+    return;
+
+  SecretItem* secret_item = static_cast<SecretItem*>(first->data);
+  auto created = base::Time::FromTimeT(
+      LibsecretLoader::secret_item_get_created(secret_item));
+  auto last_modified = base::Time::FromTimeT(
+      LibsecretLoader::secret_item_get_modified(secret_item));
+
+  VLOG(1) << "Libsecret key created: " << created;
+  VLOG(1) << "Libsecret key last modified: " << last_modified;
+  LOG_IF(WARNING, created != last_modified)
+      << "the encryption key has been modified since it was created.";
+}
+
 }  // namespace
 
 std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
@@ -91,6 +111,7 @@
       return password;
     return AddRandomPasswordInLibsecret();
   }
+  AnalyseKeyHistory(helper.results());
   std::string password(
       LibsecretLoader::secret_value_get_text(password_libsecret));
   LibsecretLoader::secret_value_unref(password_libsecret);
diff --git a/components/os_crypt/key_storage_libsecret_unittest.cc b/components/os_crypt/key_storage_libsecret_unittest.cc
index 7479f7d..b2e1bf8 100644
--- a/components/os_crypt/key_storage_libsecret_unittest.cc
+++ b/components/os_crypt/key_storage_libsecret_unittest.cc
@@ -143,6 +143,10 @@
                                                   ...);
 
   static SecretValue* mock_secret_item_get_secret(SecretItem* item);
+
+  static guint64 mock_secret_item_get_created(SecretItem* item);
+
+  static guint64 mock_secret_item_get_modified(SecretItem* item);
 };
 
 const gchar* MockLibsecretLoader::mock_secret_value_get_text(
@@ -231,6 +235,16 @@
 }
 
 // static
+guint64 MockLibsecretLoader::mock_secret_item_get_created(SecretItem* item) {
+  return 0;
+}
+
+// static
+guint64 MockLibsecretLoader::mock_secret_item_get_modified(SecretItem* item) {
+  return 0;
+}
+
+// static
 bool MockLibsecretLoader::ResetForOSCrypt() {
   // Methods used by KeyStorageLibsecret
   secret_password_store_sync =
@@ -243,6 +257,9 @@
   // Used by Migrate()
   secret_password_clear_sync =
       &MockLibsecretLoader::mock_secret_password_clear_sync;
+  secret_item_get_created = &MockLibsecretLoader::mock_secret_item_get_created;
+  secret_item_get_modified =
+      &MockLibsecretLoader::mock_secret_item_get_modified;
 
   g_password_store.Pointer()->Reset();
   libsecret_loaded_ = true;
diff --git a/components/os_crypt/libsecret_util_linux.cc b/components/os_crypt/libsecret_util_linux.cc
index 7587743..8567fce 100644
--- a/components/os_crypt/libsecret_util_linux.cc
+++ b/components/os_crypt/libsecret_util_linux.cc
@@ -35,6 +35,11 @@
     nullptr;
 decltype(&::secret_item_get_secret) LibsecretLoader::secret_item_get_secret =
     nullptr;
+decltype(&::secret_item_get_created) LibsecretLoader::secret_item_get_created =
+    nullptr;
+decltype(
+    &::secret_item_get_modified) LibsecretLoader::secret_item_get_modified =
+    nullptr;
 decltype(&::secret_value_get_text) LibsecretLoader::secret_value_get_text =
     nullptr;
 decltype(
@@ -51,6 +56,10 @@
      reinterpret_cast<void**>(&secret_item_get_secret)},
     {"secret_item_get_attributes",
      reinterpret_cast<void**>(&secret_item_get_attributes)},
+    {"secret_item_get_created",
+     reinterpret_cast<void**>(&secret_item_get_created)},
+    {"secret_item_get_modified",
+     reinterpret_cast<void**>(&secret_item_get_modified)},
     {"secret_item_load_secret_sync",
      reinterpret_cast<void**>(&secret_item_load_secret_sync)},
     {"secret_password_clear_sync",
diff --git a/components/os_crypt/libsecret_util_linux.h b/components/os_crypt/libsecret_util_linux.h
index 256d50f..53ce5c2 100644
--- a/components/os_crypt/libsecret_util_linux.h
+++ b/components/os_crypt/libsecret_util_linux.h
@@ -18,6 +18,10 @@
  public:
   static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_attributes)
       secret_item_get_attributes;
+  static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_created)
+      secret_item_get_created;
+  static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_modified)
+      secret_item_get_modified;
   static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_secret)
       secret_item_get_secret;
   static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_load_secret_sync)
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
index 61373f0..b7f3f1a 100644
--- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
+++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -48,7 +48,6 @@
           WebFeature::kPaymentHandler,
           WebFeature::kPaymentRequestShowWithoutGesture,
           WebFeature::kHTMLImports,
-          WebFeature::kHTMLImportsHasStyleSheets,
           WebFeature::kHTMLImportsOnReverseOriginTrials,
           WebFeature::kElementCreateShadowRoot,
           WebFeature::kElementCreateShadowRootOnReverseOriginTrials,
@@ -146,6 +145,8 @@
           WebFeature::kWebBluetoothRequestScan,
           WebFeature::
               kV8VideoPlaybackQuality_CorruptedVideoFrames_AttributeGetter,
+          WebFeature::kInputTypeCheckboxRenderedNonSquare,
+          WebFeature::kInputTypeRadioRenderedNonSquare,
       }));
   return *opt_in_features;
 }
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index de06635..0bfbe610 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -18,6 +18,7 @@
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_metrics_recorder.h"
 #include "components/safe_browsing/buildflags.h"
+#include "content/public/browser/back_forward_cache.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
@@ -86,6 +87,14 @@
 ContentPasswordManagerDriver*
 ContentPasswordManagerDriver::GetForRenderFrameHost(
     content::RenderFrameHost* render_frame_host) {
+  // With back-forward cache, the page stays alive and its mojo connections are
+  // not closed. The page would be frozen and would eventually stop doing work,
+  // but the messages can still arrive when the frame is not active. Given that
+  // autofill logic can show popups, it's problematic - prevent pages using
+  // autofill from entering back-forward cache for now to avoid it.
+  content::BackForwardCache::DisableForRenderFrameHost(
+      render_frame_host, "password_manager::ContentPasswordManagerDriver");
+
   ContentPasswordManagerDriverFactory* factory =
       ContentPasswordManagerDriverFactory::FromWebContents(
           content::WebContents::FromRenderFrameHost(render_frame_host));
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index f2d11de..2bc82ce 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -42,6 +42,7 @@
 constexpr char kAutocompleteCurrentPassword[] = "current-password";
 constexpr char kAutocompleteNewPassword[] = "new-password";
 constexpr char kAutocompleteCreditCardPrefix[] = "cc-";
+constexpr char kAutocompleteOneTimePassword[] = "one-time-code";
 
 // The susbset of autocomplete flags related to passwords.
 enum class AutocompleteFlag {
@@ -49,8 +50,8 @@
   kUsername,
   kCurrentPassword,
   kNewPassword,
-  // Represents the whole family of cc-* flags.
-  kCreditCard
+  // Represents the whole family of cc-* flags + OTP flag.
+  kNonPassword
 };
 
 // The autocomplete attribute has one of the following structures:
@@ -61,7 +62,8 @@
 // For password forms, only the field_type is relevant. So parsing the attribute
 // amounts to just taking the last token.  If that token is one of "username",
 // "current-password" or "new-password", this returns an appropriate enum value.
-// If the token starts with a "cc-" prefix, this returns kCreditCard.
+// If the token starts with a "cc-" prefix or is "one-time-code" token, this
+// returns kNonPassword.
 // Otherwise, returns kNone.
 AutocompleteFlag ExtractAutocompleteFlag(const std::string& attribute) {
   std::vector<base::StringPiece> tokens =
@@ -78,10 +80,11 @@
   if (base::LowerCaseEqualsASCII(field_type, kAutocompleteNewPassword))
     return AutocompleteFlag::kNewPassword;
 
-  if (base::StartsWith(field_type, kAutocompleteCreditCardPrefix,
-                       base::CompareCase::SENSITIVE))
-    return AutocompleteFlag::kCreditCard;
-
+  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteOneTimePassword) ||
+      base::StartsWith(field_type, kAutocompleteCreditCardPrefix,
+                       base::CompareCase::SENSITIVE)) {
+    return AutocompleteFlag::kNonPassword;
+  }
   return AutocompleteFlag::kNone;
 }
 
@@ -153,7 +156,7 @@
 // Number or one-time password.
 bool IsNotPasswordField(const ProcessedField& field) {
   return field.server_hints_not_password ||
-         field.autocomplete_flag == AutocompleteFlag::kCreditCard ||
+         field.autocomplete_flag == AutocompleteFlag::kNonPassword ||
          StringMatchesCVC(field.field->name_attribute) ||
          StringMatchesCVC(field.field->id_attribute) ||
          StringMatchesSSN(field.field->name_attribute) ||
@@ -477,7 +480,7 @@
         else if (!result->confirmation_password)
           result->confirmation_password = processed_field.field;
         break;
-      case AutocompleteFlag::kCreditCard:
+      case AutocompleteFlag::kNonPassword:
       case AutocompleteFlag::kNone:
         break;
     }
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index a23ac3a..ccb22be 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -962,6 +962,41 @@
   });
 }
 
+// Checks that fields with "one-time-code" autocomplete attribute are
+// not parsed as usernames or passwords.
+TEST(FormParserTest, SkippingFieldsWithOTPAutocomplete) {
+  CheckTestData({
+      {
+          .description_for_logging =
+              "The only password field marked as OTP in autocomplete",
+          .fields =
+              {
+                  {.role = ElementRole::USERNAME,
+                   .autocomplete_attribute = "username",
+                   .form_control_type = "text"},
+                  {.role = ElementRole::CURRENT_PASSWORD,
+                   .autocomplete_attribute = "one-time-code",
+                   .form_control_type = "password"},
+              },
+          .fallback_only = true,
+      },
+      {
+          .description_for_logging = "Non-OTP fields are considered",
+          .fields =
+              {
+                  {.role = ElementRole::USERNAME, .form_control_type = "text"},
+                  {.autocomplete_attribute = "one-time-code",
+                   .form_control_type = "text"},
+                  {.autocomplete_attribute = "one-time-code",
+                   .form_control_type = "password"},
+                  {.role = ElementRole::CURRENT_PASSWORD,
+                   .form_control_type = "password"},
+              },
+          .number_of_all_possible_passwords = 2,
+      },
+  });
+}
+
 TEST(FormParserTest, DisabledFields) {
   CheckTestData({
       {
diff --git a/components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h b/components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h
index 6176099..c50b3ba 100644
--- a/components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h
+++ b/components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h
@@ -18,7 +18,7 @@
   kHashingFailure = 2,
   // Error obtaining a valid server response.
   kInvalidServerResponse = 3,
-  // TODO(crbug.com/986298): add more errors.
+  kMaxValue = kInvalidServerResponse,
 };
 
 // Interface with callbacks for LeakDetectionCheck. Used to get the result of
diff --git a/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.cc b/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.cc
index 9d61252..b53de1d4 100644
--- a/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.cc
+++ b/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.cc
@@ -25,10 +25,15 @@
   std::string canonicalized_username = CanonicalizeUsername(username);
   LookupSingleLeakData data;
   data.username_hash_prefix = BucketizeUsername(canonicalized_username);
+  std::string scrypt_hash =
+      ScryptHashUsernameAndPassword(canonicalized_username, password);
+  if (scrypt_hash.empty())
+    return LookupSingleLeakData();
   data.encrypted_payload = CipherEncrypt(
       ScryptHashUsernameAndPassword(canonicalized_username, password),
       &data.encryption_key);
-  return data;
+  return data.encrypted_payload.empty() ? LookupSingleLeakData()
+                                        : std::move(data);
 }
 
 // Searches |reencrypted_lookup_hash| in the |encrypted_leak_match_prefixes|
diff --git a/components/password_manager/core/browser/leak_detection_delegate.cc b/components/password_manager/core/browser/leak_detection_delegate.cc
index 34230660..315704a 100644
--- a/components/password_manager/core/browser/leak_detection_delegate.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate.cc
@@ -127,6 +127,7 @@
 void LeakDetectionDelegate::OnError(LeakDetectionError error) {
   leak_check_.reset();
 
+  base::UmaHistogramEnumeration("PasswordManager.LeakDetection.Error", error);
   if (password_manager_util::IsLoggingActive(client_)) {
     BrowserSavePasswordProgressLogger logger(client_->GetLogManager());
     switch (error) {
diff --git a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
index 8b515be..aeeeb77 100644
--- a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
+++ b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
@@ -80,7 +80,7 @@
         test_case.current_shown_count);
     sync_service()->SetDisableReasons(
         test_case.is_sync_allowed
-            ? syncer::SyncService::DISABLE_REASON_NONE
+            ? syncer::SyncService::DisableReasonSet()
             : syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE);
     sync_service()->SetFirstSetupComplete(test_case.is_first_setup_complete);
     sync_service()->SetTransportState(
@@ -100,7 +100,7 @@
 
 #if !defined(OS_CHROMEOS)
 TEST_F(PasswordManagerPasswordBubbleExperimentTest, ReviveSignInPasswordPromo) {
-  sync_service()->SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  sync_service()->SetDisableReasons(syncer::SyncService::DisableReasonSet());
   sync_service()->SetFirstSetupComplete(false);
   sync_service()->SetTransportState(
       syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION);
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 412c822..74e0c58 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -55,7 +55,7 @@
 
 // Analyses the credentials submitted by user for leak detection.
 const base::Feature kLeakDetection = {"PasswordLeakDetection",
-                                      base::FEATURE_DISABLED_BY_DEFAULT};
+                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables storing leaked credentials in the database.
 const base::Feature kLeakHistory = {"PasswordLeakHistory",
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn
index 91cede8a..2035698 100644
--- a/components/performance_manager/BUILD.gn
+++ b/components/performance_manager/BUILD.gn
@@ -47,6 +47,8 @@
     "performance_manager_lock_observer.cc",
     "performance_manager_lock_observer.h",
     "performance_manager_registry.cc",
+    "performance_manager_registry_impl.cc",
+    "performance_manager_registry_impl.h",
     "performance_manager_tab_helper.cc",
     "performance_manager_tab_helper.h",
     "process_node_source.cc",
@@ -66,6 +68,7 @@
     "public/graph/system_node.h",
     "public/graph/worker_node.h",
     "public/performance_manager.h",
+    "public/performance_manager_main_thread_observer.h",
     "public/render_process_host_proxy.h",
     "public/web_contents_proxy.h",
     "render_process_host_proxy.cc",
@@ -111,6 +114,7 @@
     "graph/system_node_impl_unittest.cc",
     "graph/worker_node_impl_unittest.cc",
     "performance_manager_impl_unittest.cc",
+    "performance_manager_registry_impl_unittest.cc",
     "performance_manager_tab_helper_unittest.cc",
     "performance_manager_test_harness.cc",
     "performance_manager_test_harness.h",
diff --git a/components/performance_manager/decorators/page_live_state_decorator.cc b/components/performance_manager/decorators/page_live_state_decorator.cc
index ff28ff4..dc66ddf1 100644
--- a/components/performance_manager/decorators/page_live_state_decorator.cc
+++ b/components/performance_manager/decorators/page_live_state_decorator.cc
@@ -25,15 +25,24 @@
   PageLiveStateDataImpl& operator=(const PageLiveStateDataImpl&) = delete;
 
   // PageLiveStateDecorator::Data:
-  bool IsAttachedToUSB() const override { return is_attached_to_usb_; }
+  bool IsConnectedToUSBDevice() const override {
+    return is_connected_to_usb_device_;
+  }
+  bool IsConnectedToBluetoothDevice() const override {
+    return is_connected_to_bluetooth_device_;
+  }
   bool IsCapturingVideo() const override { return is_capturing_video_; }
   bool IsCapturingAudio() const override { return is_capturing_audio_; }
   bool IsBeingMirrored() const override { return is_being_mirrored_; }
   bool IsCapturingDesktop() const override { return is_capturing_desktop_; }
   bool IsAutoDiscardable() const override { return is_auto_discardable_; }
 
-  void set_is_attached_to_usb(bool is_attached_to_usb) {
-    is_attached_to_usb_ = is_attached_to_usb;
+  void set_is_connected_to_usb_device(bool is_connected_to_usb_device) {
+    is_connected_to_usb_device_ = is_connected_to_usb_device;
+  }
+  void set_is_connected_to_bluetooth_device(
+      bool is_connected_to_bluetooth_device) {
+    is_connected_to_bluetooth_device_ = is_connected_to_bluetooth_device;
   }
   void set_is_capturing_video(bool is_capturing_video) {
     is_capturing_video_ = is_capturing_video;
@@ -59,7 +68,8 @@
 
   explicit PageLiveStateDataImpl(const PageNodeImpl* page_node) {}
 
-  bool is_attached_to_usb_ = false;
+  bool is_connected_to_usb_device_ = false;
+  bool is_connected_to_bluetooth_device_ = false;
   bool is_capturing_video_ = false;
   bool is_capturing_audio_ = false;
   bool is_being_mirrored_ = false;
@@ -95,12 +105,21 @@
 }  // namespace
 
 // static
-void PageLiveStateDecorator::OnWebContentsAttachedToUSBChanged(
+void PageLiveStateDecorator::OnIsConnectedToUSBDeviceChanged(
     content::WebContents* contents,
-    bool is_attached_to_usb) {
-  SetPropertyForWebContents(contents,
-                            &PageLiveStateDataImpl::set_is_attached_to_usb,
-                            is_attached_to_usb);
+    bool is_connected_to_usb_device) {
+  SetPropertyForWebContents(
+      contents, &PageLiveStateDataImpl::set_is_connected_to_usb_device,
+      is_connected_to_usb_device);
+}
+
+// static
+void PageLiveStateDecorator::OnIsConnectedToBluetoothDeviceChanged(
+    content::WebContents* contents,
+    bool is_connected_to_bluetooth_device) {
+  SetPropertyForWebContents(
+      contents, &PageLiveStateDataImpl::set_is_connected_to_bluetooth_device,
+      is_connected_to_bluetooth_device);
 }
 
 // static
diff --git a/components/performance_manager/decorators/page_live_state_decorator_unittest.cc b/components/performance_manager/decorators/page_live_state_decorator_unittest.cc
index c06c290e..e925cda7 100644
--- a/components/performance_manager/decorators/page_live_state_decorator_unittest.cc
+++ b/components/performance_manager/decorators/page_live_state_decorator_unittest.cc
@@ -59,10 +59,16 @@
   content::WebContents* contents_ = nullptr;
 };
 
-TEST_F(PageLiveStateDecoratorTest, OnWebContentsAttachedToUSBChanged) {
+TEST_F(PageLiveStateDecoratorTest, OnIsConnectedToUSBDeviceChanged) {
   EndToEndPropertyTest(
-      contents(), &PageLiveStateDecorator::Data::IsAttachedToUSB,
-      &PageLiveStateDecorator::OnWebContentsAttachedToUSBChanged);
+      contents(), &PageLiveStateDecorator::Data::IsConnectedToUSBDevice,
+      &PageLiveStateDecorator::OnIsConnectedToUSBDeviceChanged);
+}
+
+TEST_F(PageLiveStateDecoratorTest, OnIsConnectedToBluetoothDeviceChanged) {
+  EndToEndPropertyTest(
+      contents(), &PageLiveStateDecorator::Data::IsConnectedToBluetoothDevice,
+      &PageLiveStateDecorator::OnIsConnectedToBluetoothDeviceChanged);
 }
 
 TEST_F(PageLiveStateDecoratorTest, OnIsCapturingVideoChanged) {
diff --git a/components/performance_manager/embedder/performance_manager_registry.h b/components/performance_manager/embedder/performance_manager_registry.h
index 29be038..6a9b3e4d8 100644
--- a/components/performance_manager/embedder/performance_manager_registry.h
+++ b/components/performance_manager/embedder/performance_manager_registry.h
@@ -66,4 +66,4 @@
 
 }  // namespace performance_manager
 
-#endif  // COMPONENTS_PERFORMANCE_MANAGER_EMBEDDER_PERFORMANCE_MANAGER_REGISTRY_H_
\ No newline at end of file
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_EMBEDDER_PERFORMANCE_MANAGER_REGISTRY_H_
diff --git a/components/performance_manager/performance_manager.cc b/components/performance_manager/performance_manager.cc
index c97f85c..fda1010 100644
--- a/components/performance_manager/performance_manager.cc
+++ b/components/performance_manager/performance_manager.cc
@@ -6,6 +6,7 @@
 
 #include "components/performance_manager/graph/page_node_impl.h"
 #include "components/performance_manager/performance_manager_impl.h"
+#include "components/performance_manager/performance_manager_registry_impl.h"
 #include "components/performance_manager/performance_manager_tab_helper.h"
 
 namespace performance_manager {
@@ -59,4 +60,16 @@
   return helper->page_node()->GetWeakPtr();
 }
 
+// static
+void PerformanceManager::AddObserver(
+    PerformanceManagerMainThreadObserver* observer) {
+  PerformanceManagerRegistryImpl::GetInstance()->AddObserver(observer);
+}
+
+// static
+void PerformanceManager::RemoveObserver(
+    PerformanceManagerMainThreadObserver* observer) {
+  PerformanceManagerRegistryImpl::GetInstance()->RemoveObserver(observer);
+}
+
 }  // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry.cc b/components/performance_manager/performance_manager_registry.cc
index 926c4de..51fb7dd 100644
--- a/components/performance_manager/performance_manager_registry.cc
+++ b/components/performance_manager/performance_manager_registry.cc
@@ -4,154 +4,10 @@
 
 #include "components/performance_manager/embedder/performance_manager_registry.h"
 
-#include "base/containers/flat_set.h"
-#include "base/sequence_checker.h"
-#include "base/stl_util.h"
-#include "components/performance_manager/performance_manager_tab_helper.h"
-#include "components/performance_manager/public/performance_manager.h"
-#include "components/performance_manager/render_process_user_data.h"
-#include "content/public/browser/render_process_host.h"
+#include "components/performance_manager/performance_manager_registry_impl.h"
 
 namespace performance_manager {
 
-namespace {
-PerformanceManagerRegistry* g_instance = nullptr;
-}  // namespace
-
-// Not in anonymous namespace to allow friending.
-class PerformanceManagerRegistryImpl
-    : public PerformanceManagerRegistry,
-      public PerformanceManagerTabHelper::DestructionObserver,
-      public RenderProcessUserData::DestructionObserver {
- public:
-  PerformanceManagerRegistryImpl();
-  ~PerformanceManagerRegistryImpl() override;
-
-  PerformanceManagerRegistryImpl(const PerformanceManagerRegistryImpl&) =
-      delete;
-  void operator=(const PerformanceManagerRegistryImpl&) = delete;
-
-  // PerformanceManagerRegistry:
-  void CreatePageNodeForWebContents(
-      content::WebContents* web_contents) override;
-  void CreateProcessNodeForRenderProcessHost(
-      content::RenderProcessHost* render_process_host) override;
-  void TearDown() override;
-
-  // PerformanceManagerTabHelper::DestructionObserver:
-  void OnPerformanceManagerTabHelperDestroying(
-      content::WebContents* web_contents) override;
-
-  // RenderProcessUserData::DestructionObserver:
-  void OnRenderProcessUserDataDestroying(
-      content::RenderProcessHost* render_process_host) override;
-
- private:
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Tracks WebContents and RenderProcessHost for which we have created user
-  // data. Used to destroy all user data when the registry is destroyed.
-  base::flat_set<content::WebContents*> web_contents_;
-  base::flat_set<content::RenderProcessHost*> render_process_hosts_;
-};
-
-PerformanceManagerRegistryImpl::PerformanceManagerRegistryImpl() {
-  DCHECK(!g_instance);
-  g_instance = this;
-
-  // The registry should be created after the PerformanceManager.
-  DCHECK(PerformanceManager::IsAvailable());
-}
-
-PerformanceManagerRegistryImpl::~PerformanceManagerRegistryImpl() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TearDown() should have been invoked to reset |g_instance| and clear
-  // |web_contents_| and |render_process_user_data_| prior to destroying the
-  // registry.
-  DCHECK(!g_instance);
-  DCHECK(web_contents_.empty());
-  DCHECK(render_process_hosts_.empty());
-}
-
-void PerformanceManagerRegistryImpl::CreatePageNodeForWebContents(
-    content::WebContents* web_contents) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  auto result = web_contents_.insert(web_contents);
-  if (result.second) {
-    // Create a PerformanceManagerTabHelper if |web_contents| doesn't already
-    // have one. Support for multiple calls to CreatePageNodeForWebContents()
-    // with the same WebContents is required for Devtools -- see comment in
-    // header file.
-    PerformanceManagerTabHelper::CreateForWebContents(web_contents);
-    PerformanceManagerTabHelper* tab_helper =
-        PerformanceManagerTabHelper::FromWebContents(web_contents);
-    DCHECK(tab_helper);
-    tab_helper->SetDestructionObserver(this);
-  }
-}
-
-void PerformanceManagerRegistryImpl::CreateProcessNodeForRenderProcessHost(
-    content::RenderProcessHost* render_process_host) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  auto result = render_process_hosts_.insert(render_process_host);
-  if (result.second) {
-    // Create a RenderProcessUserData if |render_process_host| doesn't already
-    // have one.
-    RenderProcessUserData* user_data =
-        RenderProcessUserData::CreateForRenderProcessHost(render_process_host);
-    user_data->SetDestructionObserver(this);
-  }
-}
-
-void PerformanceManagerRegistryImpl::TearDown() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  DCHECK_EQ(g_instance, this);
-  g_instance = nullptr;
-
-  // The registry should be torn down before the PerformanceManager.
-  DCHECK(PerformanceManager::IsAvailable());
-
-  for (auto* web_contents : web_contents_) {
-    PerformanceManagerTabHelper* tab_helper =
-        PerformanceManagerTabHelper::FromWebContents(web_contents);
-    DCHECK(tab_helper);
-    // Clear the destruction observer to avoid a nested notification.
-    tab_helper->SetDestructionObserver(nullptr);
-    // Destroy the tab helper.
-    tab_helper->TearDown();
-    web_contents->RemoveUserData(PerformanceManagerTabHelper::UserDataKey());
-  }
-  web_contents_.clear();
-
-  for (auto* render_process_host : render_process_hosts_) {
-    RenderProcessUserData* user_data =
-        RenderProcessUserData::GetForRenderProcessHost(render_process_host);
-    DCHECK(user_data);
-    // Clear the destruction observer to avoid a nested notification.
-    user_data->SetDestructionObserver(nullptr);
-    // Destroy the user data.
-    render_process_host->RemoveUserData(RenderProcessUserData::UserDataKey());
-  }
-  render_process_hosts_.clear();
-}
-
-void PerformanceManagerRegistryImpl::OnPerformanceManagerTabHelperDestroying(
-    content::WebContents* web_contents) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const size_t num_removed = web_contents_.erase(web_contents);
-  DCHECK_EQ(1U, num_removed);
-}
-
-void PerformanceManagerRegistryImpl::OnRenderProcessUserDataDestroying(
-    content::RenderProcessHost* render_process_host) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const size_t num_removed = render_process_hosts_.erase(render_process_host);
-  DCHECK_EQ(1U, num_removed);
-}
-
 // static
 std::unique_ptr<PerformanceManagerRegistry>
 PerformanceManagerRegistry::Create() {
@@ -160,7 +16,7 @@
 
 // static
 PerformanceManagerRegistry* PerformanceManagerRegistry::GetInstance() {
-  return g_instance;
+  return PerformanceManagerRegistryImpl::GetInstance();
 }
 
 }  // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry_impl.cc b/components/performance_manager/performance_manager_registry_impl.cc
new file mode 100644
index 0000000..7a3c1c0d
--- /dev/null
+++ b/components/performance_manager/performance_manager_registry_impl.cc
@@ -0,0 +1,134 @@
+// 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 "components/performance_manager/performance_manager_registry_impl.h"
+
+#include "base/stl_util.h"
+#include "components/performance_manager/performance_manager_tab_helper.h"
+#include "components/performance_manager/public/performance_manager.h"
+#include "components/performance_manager/public/performance_manager_main_thread_observer.h"
+#include "content/public/browser/render_process_host.h"
+
+namespace performance_manager {
+
+namespace {
+PerformanceManagerRegistryImpl* g_instance = nullptr;
+}  // namespace
+
+PerformanceManagerRegistryImpl::PerformanceManagerRegistryImpl() {
+  DCHECK(!g_instance);
+  g_instance = this;
+
+  // The registry should be created after the PerformanceManager.
+  DCHECK(PerformanceManager::IsAvailable());
+}
+
+PerformanceManagerRegistryImpl::~PerformanceManagerRegistryImpl() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TearDown() should have been invoked to reset |g_instance| and clear
+  // |web_contents_| and |render_process_user_data_| prior to destroying the
+  // registry.
+  DCHECK(!g_instance);
+  DCHECK(web_contents_.empty());
+  DCHECK(render_process_hosts_.empty());
+}
+
+// static
+PerformanceManagerRegistryImpl* PerformanceManagerRegistryImpl::GetInstance() {
+  return g_instance;
+}
+
+void PerformanceManagerRegistryImpl::AddObserver(
+    PerformanceManagerMainThreadObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void PerformanceManagerRegistryImpl::RemoveObserver(
+    PerformanceManagerMainThreadObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void PerformanceManagerRegistryImpl::CreatePageNodeForWebContents(
+    content::WebContents* web_contents) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto result = web_contents_.insert(web_contents);
+  if (result.second) {
+    // Create a PerformanceManagerTabHelper if |web_contents| doesn't already
+    // have one. Support for multiple calls to CreatePageNodeForWebContents()
+    // with the same WebContents is required for Devtools -- see comment in
+    // header file.
+    PerformanceManagerTabHelper::CreateForWebContents(web_contents);
+    PerformanceManagerTabHelper* tab_helper =
+        PerformanceManagerTabHelper::FromWebContents(web_contents);
+    DCHECK(tab_helper);
+    tab_helper->SetDestructionObserver(this);
+
+    for (auto& observer : observers_)
+      observer.OnPageNodeCreatedForWebContents(web_contents);
+  }
+}
+
+void PerformanceManagerRegistryImpl::CreateProcessNodeForRenderProcessHost(
+    content::RenderProcessHost* render_process_host) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto result = render_process_hosts_.insert(render_process_host);
+  if (result.second) {
+    // Create a RenderProcessUserData if |render_process_host| doesn't already
+    // have one.
+    RenderProcessUserData* user_data =
+        RenderProcessUserData::CreateForRenderProcessHost(render_process_host);
+    user_data->SetDestructionObserver(this);
+  }
+}
+
+void PerformanceManagerRegistryImpl::TearDown() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  DCHECK_EQ(g_instance, this);
+  g_instance = nullptr;
+
+  // The registry should be torn down before the PerformanceManager.
+  DCHECK(PerformanceManager::IsAvailable());
+
+  for (auto* web_contents : web_contents_) {
+    PerformanceManagerTabHelper* tab_helper =
+        PerformanceManagerTabHelper::FromWebContents(web_contents);
+    DCHECK(tab_helper);
+    // Clear the destruction observer to avoid a nested notification.
+    tab_helper->SetDestructionObserver(nullptr);
+    // Destroy the tab helper.
+    tab_helper->TearDown();
+    web_contents->RemoveUserData(PerformanceManagerTabHelper::UserDataKey());
+  }
+  web_contents_.clear();
+
+  for (auto* render_process_host : render_process_hosts_) {
+    RenderProcessUserData* user_data =
+        RenderProcessUserData::GetForRenderProcessHost(render_process_host);
+    DCHECK(user_data);
+    // Clear the destruction observer to avoid a nested notification.
+    user_data->SetDestructionObserver(nullptr);
+    // Destroy the user data.
+    render_process_host->RemoveUserData(RenderProcessUserData::UserDataKey());
+  }
+  render_process_hosts_.clear();
+}
+
+void PerformanceManagerRegistryImpl::OnPerformanceManagerTabHelperDestroying(
+    content::WebContents* web_contents) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  const size_t num_removed = web_contents_.erase(web_contents);
+  DCHECK_EQ(1U, num_removed);
+}
+
+void PerformanceManagerRegistryImpl::OnRenderProcessUserDataDestroying(
+    content::RenderProcessHost* render_process_host) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  const size_t num_removed = render_process_hosts_.erase(render_process_host);
+  DCHECK_EQ(1U, num_removed);
+}
+
+}  // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry_impl.h b/components/performance_manager/performance_manager_registry_impl.h
new file mode 100644
index 0000000..376989e5
--- /dev/null
+++ b/components/performance_manager/performance_manager_registry_impl.h
@@ -0,0 +1,73 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_REGISTRY_IMPL_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_REGISTRY_IMPL_H_
+
+#include "base/containers/flat_set.h"
+#include "base/observer_list.h"
+#include "base/sequence_checker.h"
+#include "components/performance_manager/embedder/performance_manager_registry.h"
+#include "components/performance_manager/performance_manager_tab_helper.h"
+#include "components/performance_manager/render_process_user_data.h"
+
+namespace content {
+class RenderProcessHost;
+class WebContents;
+}  // namespace content
+
+namespace performance_manager {
+
+class PerformanceManagerMainThreadObserver;
+
+class PerformanceManagerRegistryImpl
+    : public PerformanceManagerRegistry,
+      public PerformanceManagerTabHelper::DestructionObserver,
+      public RenderProcessUserData::DestructionObserver {
+ public:
+  PerformanceManagerRegistryImpl();
+  ~PerformanceManagerRegistryImpl() override;
+
+  PerformanceManagerRegistryImpl(const PerformanceManagerRegistryImpl&) =
+      delete;
+  void operator=(const PerformanceManagerRegistryImpl&) = delete;
+
+  // Returns the only instance of PerformanceManagerRegistryImpl living in this
+  // process, or nullptr if there is none.
+  static PerformanceManagerRegistryImpl* GetInstance();
+
+  // Adds / removes an observer that is notified when a PageNode is created on
+  // the main thread.
+  void AddObserver(PerformanceManagerMainThreadObserver* observer);
+  void RemoveObserver(PerformanceManagerMainThreadObserver* observer);
+
+  // PerformanceManagerRegistry:
+  void CreatePageNodeForWebContents(
+      content::WebContents* web_contents) override;
+  void CreateProcessNodeForRenderProcessHost(
+      content::RenderProcessHost* render_process_host) override;
+  void TearDown() override;
+
+  // PerformanceManagerTabHelper::DestructionObserver:
+  void OnPerformanceManagerTabHelperDestroying(
+      content::WebContents* web_contents) override;
+
+  // RenderProcessUserData::DestructionObserver:
+  void OnRenderProcessUserDataDestroying(
+      content::RenderProcessHost* render_process_host) override;
+
+ private:
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // Tracks WebContents and RenderProcessHost for which we have created user
+  // data. Used to destroy all user data when the registry is destroyed.
+  base::flat_set<content::WebContents*> web_contents_;
+  base::flat_set<content::RenderProcessHost*> render_process_hosts_;
+
+  base::ObserverList<PerformanceManagerMainThreadObserver> observers_;
+};
+
+}  // namespace performance_manager
+
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_PERFORMANCE_MANAGER_REGISTRY_IMPL_H_
diff --git a/components/performance_manager/performance_manager_registry_impl_unittest.cc b/components/performance_manager/performance_manager_registry_impl_unittest.cc
new file mode 100644
index 0000000..e83e162
--- /dev/null
+++ b/components/performance_manager/performance_manager_registry_impl_unittest.cc
@@ -0,0 +1,50 @@
+// 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 "components/performance_manager/performance_manager_registry_impl.h"
+
+#include "components/performance_manager/performance_manager_test_harness.h"
+#include "components/performance_manager/public/performance_manager_main_thread_observer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace performance_manager {
+
+namespace {
+
+class PerformanceManagerRegistryImplTest
+    : public PerformanceManagerTestHarness {
+ public:
+  PerformanceManagerRegistryImplTest() = default;
+};
+
+class LenientMockObserver : public PerformanceManagerMainThreadObserver {
+ public:
+  LenientMockObserver() = default;
+  ~LenientMockObserver() override = default;
+
+  MOCK_METHOD1(OnPageNodeCreatedForWebContents, void(content::WebContents*));
+};
+
+using MockObserver = ::testing::StrictMock<LenientMockObserver>;
+
+}  // namespace
+
+TEST_F(PerformanceManagerRegistryImplTest,
+       ObserverOnPageNodeCreatedForWebContents) {
+  MockObserver observer;
+  PerformanceManagerRegistryImpl* registry =
+      PerformanceManagerRegistryImpl::GetInstance();
+  registry->AddObserver(&observer);
+
+  std::unique_ptr<content::WebContents> contents =
+      content::RenderViewHostTestHarness::CreateTestWebContents();
+  EXPECT_CALL(observer, OnPageNodeCreatedForWebContents(contents.get()));
+  registry->CreatePageNodeForWebContents(contents.get());
+  testing::Mock::VerifyAndClear(&observer);
+
+  registry->RemoveObserver(&observer);
+}
+
+}  // namespace performance_manager
diff --git a/components/performance_manager/public/decorators/page_live_state_decorator.h b/components/performance_manager/public/decorators/page_live_state_decorator.h
index 22e1a328..44b85db 100644
--- a/components/performance_manager/public/decorators/page_live_state_decorator.h
+++ b/components/performance_manager/public/decorators/page_live_state_decorator.h
@@ -27,13 +27,14 @@
   PageLiveStateDecorator(const PageLiveStateDecorator& other) = delete;
   PageLiveStateDecorator& operator=(const PageLiveStateDecorator&) = delete;
 
-  // The following functions should only be called from the UI thread:
+  // Must be called when the connected to USB device state changes.
+  static void OnIsConnectedToUSBDeviceChanged(content::WebContents* contents,
+                                              bool is_connected_to_usb_device);
 
-  // Should be called whenever a WebContents gets connected or disconnected to
-  // a USB device.
-  // TODO(sebmarchand|olivierli): Call this from USBTabHelper.
-  static void OnWebContentsAttachedToUSBChanged(content::WebContents* contents,
-                                                bool is_attached_to_usb);
+  // Must be called when the connected to Bluetooth device state changes.
+  static void OnIsConnectedToBluetoothDeviceChanged(
+      content::WebContents* contents,
+      bool is_connected_to_bluetooth_device);
 
   // Functions that should be called by a MediaStreamCaptureIndicator::Observer.
   static void OnIsCapturingVideoChanged(content::WebContents* contents,
@@ -58,7 +59,8 @@
   Data(const Data& other) = delete;
   Data& operator=(const Data&) = delete;
 
-  virtual bool IsAttachedToUSB() const = 0;
+  virtual bool IsConnectedToUSBDevice() const = 0;
+  virtual bool IsConnectedToBluetoothDevice() const = 0;
   virtual bool IsCapturingVideo() const = 0;
   virtual bool IsCapturingAudio() const = 0;
   virtual bool IsBeingMirrored() const = 0;
diff --git a/components/performance_manager/public/performance_manager.h b/components/performance_manager/public/performance_manager.h
index f25c9017..972387f 100644
--- a/components/performance_manager/public/performance_manager.h
+++ b/components/performance_manager/public/performance_manager.h
@@ -18,6 +18,7 @@
 class Graph;
 class GraphOwned;
 class PageNode;
+class PerformanceManagerMainThreadObserver;
 
 // The performance manager is a rendezvous point for communicating with the
 // performance manager graph on its dedicated sequence.
@@ -47,6 +48,11 @@
   static base::WeakPtr<PageNode> GetPageNodeForWebContents(
       content::WebContents* wc);
 
+  // Adds / removes an observer that is notified of PerformanceManager events
+  // that happen on the main thread. Can only be called on the main thread.
+  static void AddObserver(PerformanceManagerMainThreadObserver* observer);
+  static void RemoveObserver(PerformanceManagerMainThreadObserver* observer);
+
  protected:
   PerformanceManager();
   virtual ~PerformanceManager();
diff --git a/components/performance_manager/public/performance_manager_main_thread_observer.h b/components/performance_manager/public/performance_manager_main_thread_observer.h
new file mode 100644
index 0000000..6ec1c58
--- /dev/null
+++ b/components/performance_manager/public/performance_manager_main_thread_observer.h
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_OBSERVER_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_OBSERVER_H_
+
+#include "base/observer_list_types.h"
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+namespace performance_manager {
+
+// Interface to observe PerformanceManager events that happen on the main
+// thread. All methods are invoked on the main thread.
+class PerformanceManagerMainThreadObserver : public base::CheckedObserver {
+ public:
+  ~PerformanceManagerMainThreadObserver() override = default;
+
+  // Invoked when a PageNode is created for |web_contents|. The PageNode can be
+  // retrieved via PerformanceManager::GetPageNodeForWebContents(). The PageNode
+  // will be destroyed when |web_contents| is destroyed or when the
+  // PerformanceManagerRegistry is destroyed, whichever comes first.
+  virtual void OnPageNodeCreatedForWebContents(
+      content::WebContents* web_contents) = 0;
+
+ protected:
+  PerformanceManagerMainThreadObserver() = default;
+};
+
+}  // namespace performance_manager
+
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_MAIN_THREAD_OBSERVER_H_
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index 328eb5f..f0052080 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -1656,4 +1656,5 @@
   optional BooleanPolicyProto device_login_screen_system_info_enforced = 93;
   optional StringListPolicyProto device_web_based_attestation_allowed_urls = 94;
   optional BooleanPolicyProto device_show_numeric_keyboard_for_password = 95;
+  optional BooleanPolicyProto login_screen_primary_mouse_button_switch = 96;
 }
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index dd98c88..804ee30 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -1145,6 +1145,55 @@
   optional string required_platform_version = 5;
 }
 
+// Provides Android application permission.
+message AndroidAppPermission {
+  // Name of application permission.
+  optional string name = 1;
+
+  // Identify whether the application permission is granted.
+  optional bool granted = 2;
+
+  // Identify whether the application permission is managed.
+  optional bool managed = 3;
+}
+
+// Provides Android application information.
+message AndroidAppInfo {
+  enum AndroidAppStatus {
+    STATUS_ENABLED = 0;
+    STATUS_SUSPENDED = 1;
+    STATUS_DISABLED = 2;
+  }
+
+  enum InstalledSource {
+    SOURCE_BY_ADMIN = 0;
+    SOURCE_BY_USER = 1;
+    SOURCE_NOT_INSTALLED = 2;
+  }
+
+  // ID of the Android application.
+  optional string app_id = 1;
+
+  // Name of the Android application.
+  optional string app_name = 2;
+
+  // Name of the Android application package.
+  optional string package_name = 3;
+
+  // Status of the Android application. It is set as STATUS_SUSPENDED if the
+  // application is suspended by specific policies.
+  optional AndroidAppStatus status = 4;
+
+  // Identify how the Android application is installed.
+  optional InstalledSource installed_source = 5;
+
+  // Package version of the Android application.
+  optional int32 version = 6;
+
+  // Permissions of the Android application.
+  repeated AndroidAppPermission permissions = 7;
+}
+
 // Chrome user profile level status.
 // Deprecated : Use ChromeUserProfileInfo instead.
 message ChromeUserProfileReport {
@@ -1476,6 +1525,8 @@
 message ChromeOsUserReportRequest {
   // Browser related info.
   optional BrowserReport browser_report = 1;
+  // Android applications installed in primary profile.
+  repeated AndroidAppInfo android_app_infos = 2;
 }
 
 // A validation issue from validating a policy value that was contained in
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 15f2418..0b6f082 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -10827,6 +10827,31 @@
           If this policy is left unset, the left button of the mouse will be the primary key initially, but can be switched by the user anytime.'''
     },
     {
+      'name': 'DeviceLoginScreenPrimaryMouseButtonSwitch',
+      'owners': ['amraboelkher@chromium.org', 'emaxx@chromium.org'],
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome_os:81-'],
+      'features': {
+        'can_be_recommended': True,
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'example_value': True,
+      'id': 657,
+      'caption': '''Switch the primary mouse button to the right button on the login screen''',
+      'tags': [],
+      'desc': '''Switch the primary mouse button to the right button on the login screen.
+
+          If this policy is set to enabled, the right button of the mouse will always be the primary key on the login screen.
+
+          If this policy is set to disabled, the left button of the mouse will always be the primary key on the login screen.
+
+          If you set this policy, users cannot change or override it.
+
+          If this policy is left unset, the left button of the mouse will be the primary key on the login screen initially, but can be switched by the user anytime.'''
+    },
+    {
       'name': 'SharedClipboardEnabled',
       'owners': ['mvanouwerkerk@chromium.org', 'yasmo@chromium.org'],
       'type': 'main',
@@ -19633,6 +19658,7 @@
     'DeviceLoginScreenDefaultScreenMagnifierType': 'accessibility_settings.login_screen_default_screen_magnifier_type',
     'DeviceLoginScreenScreenMagnifierType': 'accessibility_settings.login_screen_screen_magnifier_type',
     'DeviceLoginScreenDefaultVirtualKeyboardEnabled': 'accessibility_settings.login_screen_default_virtual_keyboard_enabled',
+    'DeviceLoginScreenPrimaryMouseButtonSwitch': 'login_screen_primary_mouse_button_switch.value',
     'DeviceLoginScreenVirtualKeyboardEnabled': 'accessibility_settings.login_screen_virtual_keyboard_enabled',
     'DeviceLoginScreenDictationEnabled': 'accessibility_settings.login_screen_dictation_enabled',
     'DeviceLoginScreenSelectToSpeakEnabled': 'accessibility_settings.login_screen_select_to_speak_enabled',
@@ -20154,6 +20180,6 @@
   ],
   'placeholders': [],
   'deleted_policy_ids': [412, 546, 562, 569, 578],
-  'highest_id_currently_used': 656,
+  'highest_id_currently_used': 657,
   'highest_atomic_group_id_currently_used': 38
 }
diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb
index bd7bba4..6fc897e 100644
--- a/components/policy/resources/policy_templates_es-419.xtb
+++ b/components/policy/resources/policy_templates_es-419.xtb
@@ -4742,7 +4742,7 @@
       Si esta opción está habilitada o no se estableció, se pueden eliminar el historial de navegación y el de descargas.
 
       Si esta opción está inhabilitada, no se pueden eliminar el historial de navegación ni el de descargas.</translation>
-<translation id="8749803771700374502">Si la lista de rechazo incluye un tipo de impresora, no se podrán visualizar estas impresoras ni obtener sus capacidades.
+<translation id="8749803771700374502">Los tipos de impresora que aparezcan en la lista de rechazo no se podrán visualizar ni obtener sus capacidades.
 
       Si se incluyen todos los tipos de impresora en la lista de rechazo, no se podrán realizar impresiones, dado que no habrá destinos disponibles para enviar un documento a imprimir.
 
diff --git a/components/policy/resources/policy_templates_es.xtb b/components/policy/resources/policy_templates_es.xtb
index ac2450e..a0e4c6e 100644
--- a/components/policy/resources/policy_templates_es.xtb
+++ b/components/policy/resources/policy_templates_es.xtb
@@ -4484,7 +4484,7 @@
 <translation id="8114382167597081590">No aplicar el modo restringido en YouTube</translation>
 <translation id="8117921351531866504">Permite establecer si los sitios web pueden comprobar si el usuario tiene algún método de pago guardado.
 
-      Si se inhabilita esta política, se informa a los sitios web que usen la API PaymentRequest.canMakePayment o PaymentRequest.hasEnrolledInstrument que no hay ningún método de pago disponible.
+      Si se inhabilita esta política, se informa a los sitios web que usen la API PaymentRequest.canMakePayment o PaymentRequest.hasEnrolledInstrument de que no hay ningún método de pago disponible.
 
       Si se habilita este ajuste o no se configura, los sitios web pueden comprobar si el usuario tiene algún método de pago guardado.</translation>
 <translation id="8118665053362250806">Establecer tamaño de caché de disco de medios</translation>
diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb
index dd0e4fe..e6e0828 100644
--- a/components/policy/resources/policy_templates_fr.xtb
+++ b/components/policy/resources/policy_templates_fr.xtb
@@ -4,6 +4,7 @@
 <translation id="1002439864875515590">Si cette règle est définie sur une chaîne vide ou n'est pas configurée, <ph name="PRODUCT_OS_NAME" /> n'affiche pas d'option de saisie semi-automatique lors de la procédure de connexion de l'utilisateur.
       Si cette règle est définie sur une chaîne représentant un nom de domaine, <ph name="PRODUCT_OS_NAME" /> affiche une option de saisie semi-automatique lors de la procédure de connexion. Ceci permettra à l'utilisateur de ne saisir que son nom d'utilisateur sans préciser l'extension du nom de domaine.  L'utilisateur est autorisé à écraser cette extension du nom de domaine.
       Si la valeur de la règle n'est pas un domaine valide, la règle n'est pas appliquée.</translation>
+<translation id="1010151305531217567">Définir le bouton droit de la souris comme bouton principal</translation>
 <translation id="101438888985615157">Faire pivoter l'écran de 180 degrés</translation>
 <translation id="1016912092715201525">Configure les vérifications du navigateur par défaut dans <ph name="PRODUCT_NAME" /> et empêche les utilisateurs de les modifier.
 
@@ -369,6 +370,15 @@
       Si ce paramètre est désactivé ou s'il n'est pas configuré, les utilisateurs d'entreprise
       ne peuvent pas utiliser ARC.</translation>
 <translation id="1553956579506604198">Empêche que des extensions externes soient installées</translation>
+<translation id="1556072857949466438">Cette règle autorise un administrateur à indiquer qu'une page peut afficher des fenêtres pop-up pendant son déchargement.
+
+      Lorsque cette règle est activée, les pages sont autorisées à afficher des fenêtres pop-up lors de leur déchargement.
+
+      Si la règle est désactivée ou n'est pas définie, les pages ne peuvent pas afficher de fenêtres contextuelles pendant leur déchargement, conformément aux spécifications (https://html.spec.whatwg.org/#apis-for-creating-and-navigating-browsing-contexts-by-name).
+
+      Cette règle sera supprimée dans Chrome 88.
+
+      Pour en savoir plus, consultez l'article https://www.chromestatus.com/feature/5989473649164288.</translation>
 <translation id="1559980755219453326">Cette règle détermine si les informations des extensions et des plug-ins doivent être enregistrées.
 
       Si cette règle n'est pas définie, ou si elle est définie sur "True", les données des extensions et des plug-ins sont collectées.
@@ -841,6 +851,17 @@
       Cette règle s'applique également aux extensions de composant telles que l'extension Hangout Services.</translation>
 <translation id="2223598546285729819">Paramètre de notification par défaut</translation>
 <translation id="2231817271680715693">Importer l'historique de navigation du navigateur par défaut à la première exécution</translation>
+<translation id="2234855698900783408">Atténuer les contrôles <ph name="CORS" /> dans la nouvelle mise en œuvre de <ph name="CORS" />, ce qui permet aux extensions de conserver un comportement compatible, et à <ph name="PRODUCT_NAME" /> d'envoyer les en-têtes spécifiés sans contrôles <ph name="CORS" />.
+
+      Si la liste est vide, <ph name="PRODUCT_NAME" /> essaie d'exécuter les extensions de manière compatible, et n'introduit pas de modifications de l'<ph name="API" /> pour <ph name="PRODUCT_NAME" /> 79 (comme indiqué à la page <ph name="WEB_REQUEST_API_MANUAL" />).
+
+      Si la liste contient des en-têtes de requêtes <ph name="HTTP" />, ces en-têtes sont ignorés lors des contrôles <ph name="CORS" />. Les contrôles sont en outre atténués pour les extensions.
+
+      Si cette liste n'est pas configurée, les deux mesures d'atténuation ci-dessus ne sont pas appliquées.
+
+      Pour en savoir plus sur <ph name="CORS" />, consultez la page <ph name="CORS_HELP_URL" />.
+
+      Notez que cette règle sera supprimée dans la version 82 de <ph name="PRODUCT_NAME" />.</translation>
 <translation id="2236488539271255289">Interdire à tous les sites de définir des données locales</translation>
 <translation id="2240879329269430151">Permet de définir si les sites Web sont autorisés à afficher les pop-ups. L'affichage des pop-ups peut être soit autorisé pour tous les sites, soit refusé pour tous les sites. 
 
@@ -1531,6 +1552,15 @@
       Si ce paramètre est activé ou s'il n'est pas configuré, l'utilisateur peut activer le proxy d'impression sur le cloud en se connectant à son compte Google.
 
       Si ce paramètre est désactivé, l'utilisateur ne peut pas activer le proxy et la machine n'est pas autorisée à partager ses imprimantes avec <ph name="CLOUD_PRINT_NAME" />.</translation>
+<translation id="3295118731207421797">Cette règle permet à un administrateur de spécifier qu'une page peut envoyer des requêtes XHR synchrones pendant sa fermeture.
+
+      Si cette règle est activée, les pages sont autorisées à envoyer des requêtes XHR synchrones pendant leur fermeture.
+
+      Si cette règle est désactivée ou n'est pas configurée, les pages ne sont pas autorisées à envoyer des requêtes XHR synchrones pendant leur fermeture.
+
+      Cette règle sera supprimée dans Chrome 88.
+
+      Pour en savoir plus, consultez l'article à l'adresse https://www.chromestatus.com/feature/4664843055398912.</translation>
 <translation id="3303653927512453822">Permet de rétablir l'ancien comportement <ph name="ATTRIBUTE_SAMESITE_NAME" /> pour tous les cookies. Si vous rétablissez l'ancien comportement, les cookies dont la valeur de l'attribut <ph name="ATTRIBUTE_SAMESITE_NAME" /> n'est pas spécifiée sont traités comme si la valeur <ph name="ATTRIBUTE_VALUE_SAMESITE_NONE" /> était définie. De plus, ceux dont l'attribut a pour valeur <ph name="ATTRIBUTE_VALUE_SAMESITE_NONE" /> n'exigent plus que la valeur de l'attribut <ph name="ATTRIBUTE_SECURE_NAME" /> soit spécifiée. Pour obtenir une description complète, consultez la page https://www.chromium.org/administrators/policy-list-3/cookie-legacy-samesite-policies.
 
           Lorsque cette règle n'est pas configurée, le comportement <ph name="ATTRIBUTE_SAMESITE_NAME" /> par défaut pour les cookies dont la valeur de l'attribut <ph name="ATTRIBUTE_SAMESITE_NAME" /> n'est pas spécifiée dépend de la configuration personnelle de l'utilisateur concernant la fonctionnalité <ph name="FEATURE_NAME_SAMESITE_BY_DEFAULT_COOKIES" />, qui peut être définie lors d'un test, ou par l'activation ou la désactivation de l'indicateur <ph name="FLAG_NAME_SAMESITE_BY_DEFAULT_COOKIES" />.</translation>
@@ -2441,6 +2471,11 @@
       Si cette règle est désactivée ou n'est pas définie, les sites ne sont pas autorisés à parcourir et à ouvrir une nouvelle fenêtre ou un nouvel onglet simultanément.</translation>
 <translation id="4680961954980851756">Activer la saisie automatique</translation>
 <translation id="4693779768620889402">Destinations basées sur des extensions</translation>
+<translation id="4699592681017489215">Cette règle configure un interrupteur local pouvant être utilisé pour désactiver les contrôles d'interception des requêtes DNS. Ces contrôles ont pour but de déterminer si le navigateur est situé derrière un proxy qui redirige les noms d'hôte inconnus.
+
+      Ils ne sont pas forcément nécessaires dans un environnement d'entreprise où la configuration réseau est connue, car cela engendre un certain volume de trafic DNS et HTTP au démarrage, et que chaque configuration DNS change.
+
+      Si cette règle n'est pas configurée ou si elle est activée, les contrôles d'interception des requêtes DNS ont lieu. Si elle est explicitement désactivée, les contrôles n'ont pas lieu.</translation>
 <translation id="4703402283970867140">Activer le modèle de réduction intelligente de la luminosité pour augmenter le délai d'assombrissement de l'écran</translation>
 <translation id="4722122254122249791">Activer l'isolation des sites pour des origines définies</translation>
 <translation id="4722399051042571387">Si la règle est configurée sur "false", les utilisateurs ne pourront pas définir un code faible et facile à deviner.
@@ -2567,7 +2602,7 @@
 <translation id="4978405676361550165">Si la règle de désactivation OffHours est définie, les règles spécifiées relatives aux appareils sont ignorées (utilisation des paramètres par défaut de ces règles) pendant la période définie. Les règles relatives aux appareils sont de nouveau appliquées par Chrome à chaque événement lorsque la période de désactivation OffHours commence ou se termine. L'utilisateur recevra une notification, puis il sera obligé de se déconnecter à la fin de la période de désactivation OffHours et lorsque les paramètres des règles relatives aux appareils sont modifiés (par exemple, si l'utilisateur est connecté avec un compte non autorisé).</translation>
 <translation id="4980635395568992380">Type de données :</translation>
 <translation id="4980794848194997251">Permet de contrôler le traitement du contenu mixte (contenu HTTP sur les sites HTTPS) dans le navigateur.
-       Si cette règle est définie sur "True" ou si elle n'est pas configurée, le contenu mixte audio et vidéo est mis à niveau automatiquement vers HTTPS (c'est-à-dire que l'URL est réécrite pour apparaître sous la forme HTTPS, sans aucune solution de remplacement si la ressource n'est pas disponible sur HTTPS). En outre, un avertissement "Non sécurisé" s'affiche dans la barre d'URL pour les images.
+       Si cette règle est définie sur "True" ou si elle n'est pas configurée, le contenu mixte audio et vidéo est mis à niveau automatiquement vers HTTPS (c'est-à-dire que l'URL est réécrite pour apparaître sous la forme HTTPS, sans aucune solution de remplacement si la ressource n'est pas disponible via HTTPS). En outre, un avertissement "Non sécurisé" s'affiche dans la barre d'URL pour les images.
        Si cette règle est définie sur "False", le contenu audio et vidéo n'est pas mis à niveau automatiquement, et aucun avertissement ne s'affiche pour les images.
        Cette règle n'influe pas sur les types de contenus mixtes autres que les images et les contenus audio/vidéo.</translation>
 <translation id="4983201894483989687">Autoriser l'exécution de plug-ins obsolètes</translation>
@@ -2658,6 +2693,10 @@
           Si vous ne définissez pas cette règle, la loupe est désactivée lors du premier affichage de l'écran de connexion. Les utilisateurs peuvent l'activer ou la désactiver à tout moment, et son état sur l'écran de connexion est appliqué à tous les utilisateurs.
 
           Remarque : Si elle est définie, la règle <ph name="DEVICE_LOGIN_SCREEN_SCREEN_MAGNIFIER_TYPE_POLICY_NAME" /> remplace cette règle.</translation>
+<translation id="5115168755602871392">Permet de transmettre les informations du ou des processeurs d'un appareil.
+
+      Si la règle est définie sur "False" ou n'est pas définie, ces informations ne sont pas transmises.
+      Si elle est définie sur "True", le modèle de chaque processeur ainsi que son architecture et la vitesse maximale de son horloge sont transmis.</translation>
 <translation id="5124368997194894978">Activer le démarrage au branchement de l'alimentation CA (courant alternatif)</translation>
 <translation id="5131211790949066746">Permet de fusionner les règles relatives aux listes d'installation d'extensions <ph name="EXTENSION_INSTALL_BLACKLIST_POLICY_NAME" />, <ph name="EXTENSION_INSTALL_WHITELIST_POLICY_NAME" /> et <ph name="EXTENSION_INSTALL_FORCELIST_POLICY_NAME" />.
 
@@ -3491,6 +3530,17 @@
 <translation id="6467613372414922590">Autoriser les hôtes de messagerie natifs au niveau de l'utilisateur (installés sans l'autorisation d'un administrateur)</translation>
 <translation id="6468980648680553776">Cette règle est obsolète. Veuillez utiliser RemoteAccessHostClientDomainList.</translation>
 <translation id="6473623140202114570">Configurez la liste des domaines sur lesquels la navigation sécurisée ne déclenchera aucun avertissement.</translation>
+<translation id="6487780893361255867">Permet d'utiliser l'ancienne mise en œuvre de <ph name="CORS" /> plutôt que la nouvelle mise en œuvre de <ph name="CORS" />.
+
+      Si cette règle est définie sur "True", l'ancienne mise en œuvre est utilisée. Elle est normalement compatible avec les versions précédentes.
+
+      Si cette règle est définie sur "False" ou si elle n'est pas configurée, la nouvelle mise en œuvre est utilisée. Elle peut causer des problèmes de compatibilité spécifiques à l'entreprise.
+
+      Cette règle sera supprimée après quelques jalons.
+
+      Pour en savoir plus sur <ph name="CORS" />, consultez la page <ph name="CORS_HELP_URL" />.
+
+      Notez que cette règle sera supprimée dans la version 82 de <ph name="PRODUCT_NAME" />.</translation>
 <translation id="6488627892044759800">Permet de configurer le type de page d'accueil par défaut dans <ph name="PRODUCT_NAME" /> et d'empêcher les utilisateurs de modifier les préférences de page d'accueil. Vous pouvez définir la page d'accueil sur une URL que vous spécifiez ou sur la page Nouvel onglet.
 
           Si vous activez ce paramètre, la page Nouvel onglet est systématiquement utilisée en guise de page d'accueil, et l'adresse URL de la page d'accueil est ignorée.
@@ -3578,6 +3628,7 @@
       Lorsque cette règle est définie sur "True", l'appareil peut lancer Powerwash.
       Si cette règle n'est pas configurée, elle est définie par défaut sur "True" : l'appareil peut lancer Powerwash.
       </translation>
+<translation id="66265932317331474">Transmettre les informations concernant le processeur</translation>
 <translation id="6628043374475466084">Formats d'URL ne déclenchant pas l'analyse des contenus téléchargés pour vérifier s'ils respectent les règles de protection des données sensibles</translation>
 <translation id="6628120204569232711">Envoyer des rapports sur l'état du stockage</translation>
 <translation id="6628646143828354685">Permet d'indiquer si les sites Web sont autorisés à accéder aux appareils Bluetooth à proximité. Soit l'accès est complètement bloqué, soit l'utilisateur reçoit un message chaque fois qu'un site Web souhaite accéder aux appareils Bluetooth à proximité.
@@ -3778,6 +3829,7 @@
       Consultez la page https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables pour obtenir la liste des variables pouvant être utilisées.
 
       Si cette règle n'est pas définie, le chemin de profil par défaut sera utilisé, et l'utilisateur pourra le remplacer avec l'indicateur de ligne de commande "--user-data-dir".</translation>
+<translation id="7008308728445338159">Contrôles d'interception des requêtes DNS activés</translation>
 <translation id="7027785306666625591">Configurer la gestion de l'alimentation dans <ph name="PRODUCT_OS_NAME" />
 
       Ces règles vous permettent de configurer le comportement du système d'exploitation "<ph name="PRODUCT_OS_NAME" />" lorsque l'utilisateur est inactif pendant un certain temps.</translation>
@@ -3873,6 +3925,15 @@
 
       Pour en savoir plus sur la règle <ph name="IEEM_SITELIST_POLICY" /> d'Internet Explorer, consultez la page https://docs.microsoft.com/internet-explorer/ie11-deploy-guide/what-is-enterprise-mode</translation>
 <translation id="7132877481099023201">URL autorisées à accéder aux appareils de capture vidéo sans avis préalable</translation>
+<translation id="7134420220355750019">Permet de définir le bouton droit de la souris comme bouton principal.
+
+          Si cette règle est activée, le bouton droit de la souris devient le bouton principal.
+
+          Si elle est désactivée, le bouton gauche de la souris reste le bouton principal.
+
+          Si vous configurez cette règle, les utilisateurs ne peuvent ni la modifier, ni l'ignorer.
+
+          Si cette règle n'est pas configurée, le bouton gauche de la souris est le bouton principal par défaut, mais l'utilisateur peut en décider autrement.</translation>
 <translation id="713712866686796666">Permet de définir la configuration quotidienne de l'alimentation alternée en heures pleines.
 
           Cette règle n'est utilisée que si la règle <ph name="DEVICE_POWER_PEAK_SHIFT_ENABLED_NAME" /> est définie sur "True".
@@ -4839,7 +4900,7 @@
       Si ce paramètre est désactivé, la suppression de l'historique du navigateur et de l'historique des téléchargements n'est pas possible.</translation>
 <translation id="8749803771700374502">Si vous ajoutez des types d'imprimantes à la liste deny, vous ne pourrez plus les voir ni récupérer leurs fonctionnalités.
 
-      Lorsque vous placez tous les types d'imprimantes sur la liste deny, vous désactivez l'impression. En effet, plus aucune destination n'est alors disponible au moment d'envoyer un document pour impression.
+      Lorsque vous placez tous les types d'imprimantes sur la liste deny, vous désactivez l'impression. En effet, plus aucune destination n'est alors disponible lorsque vous envoyez un document pour impression.
 
       Inclure le type "<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />" dans la liste deny revient à définir la règle "<ph name="POLICY_CLOUDPRINTSUBMITENABLED" />" sur "False". Pour que les destinations <ph name="CLOUD_PRINT_NAME" /> restent visibles, la règle "<ph name="POLICY_CLOUDPRINTSUBMITENABLED" />" doit être définie sur "True", et le type "<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />" ne doit pas figurer sur la liste deny.
 
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb
index 8ed8b5fb..a84a93f2 100644
--- a/components/policy/resources/policy_templates_id.xtb
+++ b/components/policy/resources/policy_templates_id.xtb
@@ -1549,7 +1549,7 @@
 
       Jika kebijakan dikonfigurasi, kebijakan dapat disetel ke salah satu nilai berikut: "tls1", "tls1.1", atau "tls1.2". Jika disetel, <ph name="PRODUCT_NAME" /> tidak akan menggunakan versi SSL/TLS yang lebih rendah daripada versi yang ditentukan. Nilai yang tidak dikenal akan diabaikan.</translation>
 <translation id="34160070798637152">Mengontrol konfigurasi jaringan tingkat perangkat.</translation>
-<translation id="3417130629744653218">Izinkan situs mengkueri metode pembayaran yang tersedia.</translation>
+<translation id="3417130629744653218">Izinkan situs membuat kueri untuk metode pembayaran yang tersedia.</translation>
 <translation id="3417418267404583991">Jika kebijakan ini disetel ke true atau tidak dikonfigurasi, <ph name="PRODUCT_OS_NAME" /> akan mengaktifkan login sebagai tamu. Login sebagai tamu adalah sesi pengguna anonim dan tidak memerlukan sandi.
 
       Jika kebijakan ini disetel ke false, <ph name="PRODUCT_OS_NAME" /> tidak akan mengizinkan dimulainya sesi tamu.</translation>
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb
index 32e63b7..4520b2e 100644
--- a/components/policy/resources/policy_templates_it.xtb
+++ b/components/policy/resources/policy_templates_it.xtb
@@ -1880,7 +1880,7 @@
           Se imposti questo criterio, gli utenti non potranno modificarlo o ignorarlo.
 
           Se questo criterio non viene impostato, inizialmente la tastiera virtuale è disattivata nella schermata di accesso, ma l'utente può attivarla in qualsiasi momento.</translation>
-<translation id="3913530489429898348">Permette di consentire a <ph name="PRODUCT_NAME" /> di inviare documenti da stampare a <ph name="CLOUD_PRINT_NAME" />.  NOTA: questa impostazione incide soltanto sul supporto di <ph name="CLOUD_PRINT_NAME" /> in <ph name="PRODUCT_NAME" />.  Non impedisce agli utenti di inviare processi di stampa su siti web.
+<translation id="3913530489429898348">Consente a <ph name="PRODUCT_NAME" /> di inviare documenti da stampare a <ph name="CLOUD_PRINT_NAME" />.  NOTA: questa impostazione incide soltanto sul supporto di <ph name="CLOUD_PRINT_NAME" /> in <ph name="PRODUCT_NAME" />.  Non impedisce agli utenti di inviare processi di stampa su siti web.
 
       Se questa impostazione viene attivata o non viene configurata, gli utenti possono stampare con <ph name="CLOUD_PRINT_NAME" /> dalla finestra di dialogo di stampa di <ph name="PRODUCT_NAME" />.
 
@@ -2452,7 +2452,7 @@
       </translation>
 <translation id="4906194810004762807">Frequenza di aggiornamento per norma dispositivo</translation>
 <translation id="4917385247580444890">Forte</translation>
-<translation id="4919122295221518724">Attiva trattamento più restrittivo dei contenuti misti</translation>
+<translation id="4919122295221518724">Attiva trattamento più restrittivo per i contenuti misti</translation>
 <translation id="4923806312383904642">Consenti a WebDriver di eseguire l'override delle norme non compatibili</translation>
 <translation id="4929721861648439998">Consente di attivare la funzione di accessibilità di audio in formato mono nella schermata di accesso.
 
@@ -4686,9 +4686,9 @@
 
       L'inserimento del valore <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> nell'elenco di tipi non consentiti equivale all'impostazione del valore false per il criterio <ph name="POLICY_CLOUDPRINTSUBMITENABLED" />. Per mantenere rilevabili le destinazioni <ph name="CLOUD_PRINT_NAME" />, il criterio <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> deve essere impostato su true e il valore <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> non deve essere nell'elenco di tipi non consentiti.
 
-      Se il criterio non viene impostato o se l'elenco viene lasciato vuoto, potranno essere rilevati tutti i tipi di stampanti.
+      Se il criterio non viene impostato o se viene impostato su un elenco vuoto, potranno essere rilevati tutti i tipi di stampanti.
 
-      Le stampanti estensione sono note anche come destinazioni dei provider di stampa e includono le eventuali destinazioni appartenenti a un'estensione <ph name="PRODUCT_NAME" />.
+      Le stampanti estensione sono note anche come destinazioni dei provider di stampa e includono le eventuali destinazioni appartenenti a un'estensione di <ph name="PRODUCT_NAME" />.
 
       Le stampanti locali sono note anche come destinazioni di stampa native e includono le destinazioni disponibili per le stampanti di computer locali e le stampanti di rete condivise.</translation>
 <translation id="8752541111574086388">Tieni presente che questo criterio è obsoleto e verrà rimosso nella versione 82 di <ph name="PRODUCT_OS_NAME" />. Usa il criterio <ph name="POWER_MANAGEMENT_IDLE_SETTINGS_POLICY_NAME" />.
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb
index f394f35..9d640cc 100644
--- a/components/policy/resources/policy_templates_ko.xtb
+++ b/components/policy/resources/policy_templates_ko.xtb
@@ -1589,7 +1589,7 @@
 
       정책을 설정하는 경우 'tls1', 'tls1.1', 'tls1.2' 중 하나로 설정할 수 있으며, 버전을 설정하면 <ph name="PRODUCT_NAME" />에서 지정된 버전보다 낮은 SSL/TLS 버전은 사용되지 않습니다. 인식할 수 없는 값은 무시됩니다.</translation>
 <translation id="34160070798637152">기기 전체 네트워크 구성을 제어합니다.</translation>
-<translation id="3417130629744653218">웹사이트가 사용 가능한 결제 수단을 쿼리하도록 허용합니다.</translation>
+<translation id="3417130629744653218">웹사이트가 사용 가능한 결제 수단을 쿼리하도록 허용</translation>
 <translation id="3417418267404583991">이 정책을 true로 설정하거나 구성하지 않으면 <ph name="PRODUCT_OS_NAME" />은(는) 게스트 로그인을 사용합니다. 게스트 로그인은 익명 사용자 세션이며 비밀번호가 필요없습니다.
 
       이 정책을 false로 설정하면, <ph name="PRODUCT_OS_NAME" />은(는) 게스트 세션을 시작하지 않습니다.</translation>
@@ -1945,13 +1945,13 @@
           정책이 설정되면 사용자가 변경하거나 재정의할 수 없습니다.
 
           설정되지 않으면 처음에는 로그인 화면에서 가상 키보드가 사용되지 않지만 사용자가 언제든지 사용 설정할 수 있습니다.</translation>
-<translation id="3913530489429898348"><ph name="PRODUCT_NAME" />에서 인쇄를 위해 <ph name="CLOUD_PRINT_NAME" />에 문서를 제출하도록 허용합니다.  참고: 이렇게 하면 <ph name="PRODUCT_NAME" />의 <ph name="CLOUD_PRINT_NAME" /> 지원 기능만 영향을 받으며  사용자는 웹사이트에서 인쇄 작업을 계속해서 제출할 수 있습니다.
+<translation id="3913530489429898348"><ph name="PRODUCT_NAME" />에서 인쇄를 위해 <ph name="CLOUD_PRINT_NAME" />에 문서를 보낼 수 있도록 허용합니다.  참고: 이렇게 하면 <ph name="PRODUCT_NAME" />의 <ph name="CLOUD_PRINT_NAME" /> 지원 기능만 영향을 받으며  사용자는 웹사이트에서 인쇄 작업을 계속해서 보낼 수 있습니다.
 
       이 설정을 사용하거나 설정이 구성되어 있지 않으면 사용자는 <ph name="PRODUCT_NAME" /> 인쇄 대화상자에서 <ph name="CLOUD_PRINT_NAME" />(으)로 인쇄할 수 있습니다.
 
       설정을 사용 중지하면 사용자는 <ph name="PRODUCT_NAME" /> 인쇄 대화상자에서 <ph name="CLOUD_PRINT_NAME" />(으)로 인쇄할 수 없습니다.
 
-      <ph name="CLOUD_PRINT_NAME" /> 목적지를 검색 가능한 상태로 유지하려면 정책이 true로 설정되고 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />이(가) <ph name="POLICY_PRINTERTYPEDENYLIST" /> 정책에 포함되지 않아야 합니다.</translation>
+      <ph name="CLOUD_PRINT_NAME" /> 대상을 검색 가능한 상태로 유지하려면 정책이 true로 설정되고 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />이(가) <ph name="POLICY_PRINTERTYPEDENYLIST" /> 정책에 포함되지 않아야 합니다.</translation>
 <translation id="391531815696899618">True로 설정하면 <ph name="PRODUCT_OS_NAME" /> 파일 앱에서 Google 드라이브 동기화를 사용 중지합니다. 이런 경우 Google 드라이브에 데이터가 업로드되지 않습니다.
 
           설정하지 않거나 False로 설정하면 파일을 Google 드라이브에 전송할 수 있습니다.</translation>
@@ -2563,7 +2563,7 @@
 <translation id="4978405676361550165">‘OffHours’ 정책이 설정된 경우, 정의된 기간 동안 지정된 기기 정책이 무시됩니다(이러한 정책의 기본 설정이 사용됨). 기기 정책은 Chrome에 의해 ‘OffHours’ 기간이 시작 또는 종료되는 모든 이벤트가 발생할 때마다 다시 적용됩니다. ‘OffHours’ 시간이 종료되고 기기 정책 설정이 변경되면(예: 사용자가 허용되지 않는 계정으로 로그인한 경우) 사용자는 알림을 수신하고 강제로 로그아웃됩니다.</translation>
 <translation id="4980635395568992380">데이터 유형:</translation>
 <translation id="4980794848194997251">이 정책은 브라우저에서 혼합 콘텐츠(HTTPS 사이트의 HTTP 콘텐츠)가 처리되는 방식을 관리합니다.
-       정책이 true로 설정되거나 설정되지 않으면 오디오 및 동영상이 혼합된 콘텐츠는 HTTPS로 자동 업그레이드되며(즉, 리소스를 HTTPS로 사용할 수 없는 경우 대체 요소 없이 URL이 HTTPS로 변환됨), 이미지 혼합 콘텐츠의 경우 URL 입력란에 '안전하지 않음' 경고가 표시됩니다.
+       정책이 true로 설정되거나 설정되지 않으면 오디오 및 동영상이 혼합된 콘텐츠는 HTTPS로 자동 업그레이드되며(즉, 리소스를 HTTPS로 사용할 수 없는 경우 대체 방법을 시도하지 않고 URL이 HTTPS로 변환됨), 이미지 혼합 콘텐츠의 경우 URL 입력란에 '안전하지 않음' 경고가 표시됩니다.
        정책이 false로 설정되면 오디오 및 동영상의 자동 업그레이드가 사용 중지되며 이미지에도 경고가 표시되지 않습니다.
        이 정책은 오디오, 동영상, 이미지 외 유형의 혼합 콘텐츠에 영향을 주지 않습니다.</translation>
 <translation id="4983201894483989687">오래된 플러그인 실행 허용</translation>
@@ -4164,8 +4164,8 @@
 <translation id="7583419926951418342">이 정책은 Google 관리 콘솔에 브라우저 작동 정보를 업로드하는 <ph name="PRODUCT_NAME" /> 클라우드 보고 기능을 관리합니다.
 
       정책이 설정되지 않거나 false로 설정되면 데이터가 수집되거나 업로드되지 않습니다.
-      true로 설정되면 데이터가 수집되며 Google 관리 콘솔에 업로드됩니다.
-      업로드되는 데이터를 관리하려면 그룹 Chrome 보고 확장 프로그램의 정책을 사용하세요.
+      true로 설정되면 데이터가 수집되어 Google 관리 콘솔에 업로드됩니다.
+      업로드되는 데이터를 관리하려면 Chrome Reporting Extension 그룹의 정책을 사용하세요.
 
       <ph name="PRODUCT_NAME" />의 경우 이 정책은 기기가 <ph name="CLOUD_MANAGEMENT_ENROLLMENT_TOKEN" />에 등록되어 있는 경우에만 적용됩니다.
       <ph name="PRODUCT_OS_NAME" />의 경우 정책이 항상 적용됩니다.</translation>
@@ -4860,13 +4860,13 @@
 
       모든 프린터 유형을 거부 목록에 포함하면 인쇄가 사실상 사용 중지됩니다. 문서를 인쇄하기 위해 보낼 프린터가 없어지기 때문입니다.
 
-      거부 목록에 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />을(를) 포함하면 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 정책을 false로 설정하는 것과 동일한 효과가 나타납니다. <ph name="CLOUD_PRINT_NAME" /> 목적지를 검색 가능한 상태로 유지하려면 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 정책이 true로 설정되고 거부 목록에 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />이(가) 포함되지 않아야 합니다.
+      거부 목록에 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />을(를) 포함하면 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 정책을 false로 설정하는 것과 동일한 효과가 나타납니다. <ph name="CLOUD_PRINT_NAME" /> 대상을 검색 가능한 상태로 유지하려면 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 정책이 true로 설정되고 거부 목록에 <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />이(가) 포함되지 않아야 합니다.
 
       정책이 설정되지 않거나 빈 목록으로 설정되어 있는 경우 모든 프린터 유형을 검색할 수 있습니다.
 
-      확장 프로그램 프린터는 인쇄 제공업체 목적지라고도 하며, <ph name="PRODUCT_NAME" /> 확장 프로그램에 속한 모든 목적지를 포함합니다.
+      확장 프로그램 프린터는 인쇄 제공업체 대상이라고도 하며, <ph name="PRODUCT_NAME" /> 확장 프로그램에 속한 모든 대상을 포함합니다.
 
-      로컬 프린터는 기본 인쇄 목적지라고도 하며, 로컬 컴퓨터에서 사용 가능한 인쇄 목적지와 공유 네트워크 프린터를 포함합니다.</translation>
+      로컬 프린터는 기본 인쇄 대상이라고도 하며, 로컬 컴퓨터에서 사용 가능한 인쇄 대상과 공유 네트워크 프린터를 포함합니다.</translation>
 <translation id="8752541111574086388">이 정책은 지원이 중단되었으며 <ph name="PRODUCT_OS_NAME" /> 버전 82에서 삭제될 예정입니다. 대신 <ph name="POWER_MANAGEMENT_IDLE_SETTINGS_POLICY_NAME" /> 정책을 사용하세요.
 
           배터리 전원을 사용할 때 사용자의 입력 없이 어느 정도의 시간이 지나면 경고 대화상자가 표시될지 지정합니다.
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb
index 0646456..6918478 100644
--- a/components/policy/resources/policy_templates_nl.xtb
+++ b/components/policy/resources/policy_templates_nl.xtb
@@ -4124,7 +4124,7 @@
       Wanneer dit beleid niet wordt ingesteld, of wordt ingesteld op '0', wordt de URL onmiddellijk in een alternatieve browser geopend als je naar de URL navigeert.
 
       Wanneer dit beleid is ingesteld op een getal, toont Chrome gedurende dat aantal milliseconden een melding en wordt vervolgens de alternatieve browser geopend.</translation>
-<translation id="7583419926951418342">Met dit beleid wordt cloudrapportage voor <ph name="PRODUCT_NAME" /> beheerd waarvoor informatie over de browseractiviteit naar de Google-beheerdersconsole wordt geüpload.
+<translation id="7583419926951418342">Dit beleid beheert cloudrapportage voor <ph name="PRODUCT_NAME" /> waarmee informatie over de browseractiviteit naar de Google-beheerdersconsole wordt geüpload.
 
       Als dit beleid niet is ingesteld of als het is ingesteld op 'False', worden er geen gegevens verzameld of geüpload.
       Als dit beleid is ingesteld op 'True', worden de gegevens verzameld en geüpload naar de Google-beheerdersconsole.
@@ -4804,7 +4804,7 @@
 
       Als je alle printertypen op de weigeringslijst zet, schakel je in feite de afdrukfunctie uit. Er zijn dan geen bestemmingen beschikbaar waar een document naartoe kan worden gestuurd om af te drukken.
 
-      Als je <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> op de weigeringslijst zet, heeft dit hetzelfde effect als het beleid <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> instellen op False. Je kunt ervoor zorgen dat <ph name="CLOUD_PRINT_NAME" />-bestemmingen vindbaar blijven door het beleid<ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> in te stellen op True en <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> niet op de weigeringslijst te zetten.
+      Als je <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> op de weigeringslijst zet, heeft dit hetzelfde effect als het beleid <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> instellen op False. Je kunt ervoor zorgen dat <ph name="CLOUD_PRINT_NAME" />-bestemmingen vindbaar blijven door het beleid <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> in te stellen op True en <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> niet op de weigeringslijst te zetten.
 
       Als het beleid niet is ingesteld of is ingesteld op een lege lijst, kunnen alle printertypen worden gevonden.
 
diff --git a/components/policy/resources/policy_templates_pt-BR.xtb b/components/policy/resources/policy_templates_pt-BR.xtb
index 6f97ed7..75bcbe41 100644
--- a/components/policy/resources/policy_templates_pt-BR.xtb
+++ b/components/policy/resources/policy_templates_pt-BR.xtb
@@ -2493,8 +2493,8 @@
 <translation id="4978405676361550165">Se a política "OffHours" for definida, as políticas do dispositivo especificadas serão ignoradas (use as configurações padrão dessas políticas) durante os intervalos de tempo definidos. As políticas do dispositivo são reaplicadas pelo Chrome em todos os eventos quando o período "OffHours" começa ou termina. O usuário será notificado e forçado a se desconectar quando o período "OffHours" terminar e as configurações de política do dispositivo forem alteradas (por exemplo, quando o usuário estiver conectado com uma conta que não seja permitida).</translation>
 <translation id="4980635395568992380">Tipo do dado:</translation>
 <translation id="4980794848194997251">Esta política controla o tratamento para conteúdo misto (conteúdo HTTP em sites HTTPS) no navegador.
-       Se a política for definida como verdadeira ou não for definida, os conteúdos mistos de áudio e vídeo serão automaticamente atualizados para HTTPS (por exemplo, o URL será reescrito como HTTPS, sem o substituto se a fonte não estiver disponível em HTTPS), e um aviso de "Não seguro" será exibido na barra de URL para conteúdo misto de imagem.
-       Se a política for definida como falsa, as atualizações automáticas serão desativadas para áudio e vídeo, e nenhum aviso será exibido para imagens.
+       Se a política for definida como "verdadeira" ou não for definida, os conteúdos mistos de áudio e vídeo serão automaticamente atualizados para HTTPS (por exemplo, o URL será reescrito como HTTPS, sem o substituto se a fonte não estiver disponível em HTTPS), e um aviso de "Não seguro" será exibido na barra de URL para conteúdo misto de imagem.
+       Se a política for definida como "falsa", as atualizações automáticas serão desativadas para áudio e vídeo, e nenhum aviso será exibido para imagens.
        Esta política só afeta tipos de conteúdo misto de áudio, vídeo e imagens.</translation>
 <translation id="4983201894483989687">Permitir a execução de plug-ins que estão desatualizados</translation>
 <translation id="4986560318567565414">Caminho para mudar do navegador alternativo para o Chrome.</translation>
@@ -2534,7 +2534,7 @@
 <translation id="5067143124345820993">Lista de permissões de login de usuário</translation>
 <translation id="5073609397321802133">Se a política for definida como falsa, a página "Nova guia" não permitirá que os usuários personalizem o plano de fundo. Qualquer plano de fundo personalizado já existente será removido permanentemente, mesmo que a política seja definida como verdadeira mais tarde.
 
-      Se a política for definida como verdadeira ou não for definida, os usuários poderão personalizar o plano de fundo da página "Nova guia".</translation>
+      Se a política for definida como "verdadeira" ou não for definida, os usuários poderão personalizar o plano de fundo da página "Nova guia".</translation>
 <translation id="5075834892754086022">Se a política estiver definida, o tamanho máximo configurado para o PIN será imposto. O tamanho mínimo absoluto do PIN é 1. Valores menores que esse serão tratados como 1.
 
           Se a política não for definida, um tamanho mínimo de PIN de seis dígitos será imposto. Esse é o mínimo recomendado.</translation>
@@ -4028,10 +4028,10 @@
       Quando a política não é definida ou é definida como 0, a navegação para um URL designado o abre imediatamente em um navegador alternativo.
 
       Quando a política é definida com um número diferente de 0, o Chrome exibe uma mensagem por vários milésimos de segundo e, em seguida, abre o navegador alternativo.</translation>
-<translation id="7583419926951418342">Esta política controla relatórios de nuvem de <ph name="PRODUCT_NAME" /> que faz upload de informação sobre a operação do navegador para o Google Admin Console.
+<translation id="7583419926951418342">Esta política controla relatórios de nuvem do <ph name="PRODUCT_NAME" />, que faz upload de informação sobre a operação do navegador para o Google Admin Console.
 
-      Quando esta política não é definida ou é definida como falsa, os dados não são coletados nem enviados por upload.
-      Quando esta política é definida como verdadeira, os dados são coletados e enviados por upload para o Google Admin Console.
+      Quando esta política não é definida ou é definida como "falsa", os dados não são coletados nem enviados por upload.
+      Quando esta política é definida como "verdadeira", os dados são coletados e enviados por upload para o Google Admin Console.
       Para controlar quais dados são enviados, use as políticas do grupo Chrome Reporting Extension.
 
       Para o <ph name="PRODUCT_NAME" />, esta política só é eficaz quando a máquina está inscrita no <ph name="CLOUD_MANAGEMENT_ENROLLMENT_TOKEN" />.
@@ -4344,9 +4344,9 @@
 <translation id="8114382167597081590">Não aplicar o Modo restrito no YouTube</translation>
 <translation id="8117921351531866504">Permite que você defina se os sites têm permissão de verificar se os usuários salvaram formas de pagamento.
 
-      Se esta política é definida como desativada, sites que usam a API PaymentRequest.canMakePayment ou PaymentRequest.hasEnrolledInstrument serão informados de que não há formas de pagamento disponíveis.
+      Se esta política for definida como "desativada", sites que usam a API PaymentRequest.canMakePayment ou PaymentRequest.hasEnrolledInstrument serão informados de que não há formas de pagamento disponíveis.
 
-      Se a configuração está ativada ou não está definida, os sites têm permissão de verificar se o usuário salvou formas de pagamento.</translation>
+      Se a configuração estiver ativada ou não estiver definida, os sites terão permissão para verificar se o usuário salvou formas de pagamento.</translation>
 <translation id="8118665053362250806">Definir tamanho do cache de disco da mídia</translation>
 <translation id="8124468781472887384">Política de acesso à configuração de impressoras do dispositivo.</translation>
 <translation id="8138009212169037227">Esta política controla a permissão de fornecimento dos dados da política e do horário de busca dela.
@@ -4707,7 +4707,7 @@
       Se esta configuração estiver desativada, não será possível excluir o histórico de navegação e de download.</translation>
 <translation id="8749803771700374502">Se o tipo da impressora estiver na lista de proibições, não será possível descobrir esse equipamento ou buscar suas funcionalidades.
 
-      Colocar todos os tipos de impressora na lista de proibições desativa a impressão de modo eficaz, uma vez que não haveria destinos disponíveis para enviar um documento para impressão.
+      Colocar todos os tipos de impressora na lista de proibições desativa a impressão de modo eficaz porque não há destinos disponíveis para enviar um documento para impressão.
 
       Incluir <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> na lista de proibições tem o mesmo efeito que definir a política <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> como falsa. Para que os destinos da <ph name="CLOUD_PRINT_NAME" /> continuem disponíveis, é necessário que a política <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> seja definida como verdadeira e que <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> não esteja na lista de proibições.
 
diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb
index db874c0..5080988 100644
--- a/components/policy/resources/policy_templates_ru.xtb
+++ b/components/policy/resources/policy_templates_ru.xtb
@@ -1554,7 +1554,7 @@
 
       Правилу можно задать одно из следующих значений: tls1, tls1.1 или tls1.2. После того как вы установите любое из них, <ph name="PRODUCT_NAME" /> не будет использовать более старые версии SSL/TLS. Неподдерживаемые значения будут игнорироваться.</translation>
 <translation id="34160070798637152">Определяет конфигурацию сети для устройства.</translation>
-<translation id="3417130629744653218">Разрешение для сайтов запрашивать доступные способы оплаты</translation>
+<translation id="3417130629744653218">Разрешить сайтам запрашивать доступные способы оплаты</translation>
 <translation id="3417418267404583991">Если эти правила заданы (по умолчанию), в <ph name="PRODUCT_OS_NAME" /> будет разрешен вход в учетной записи гостя. Гостевой сеанс полностью анонимен и не требует ввода пароля.
 
       Если эти правила не установлены, в <ph name="PRODUCT_OS_NAME" /> будет невозможно открыть гостевой сеанс.</translation>
@@ -3527,7 +3527,7 @@
 <translation id="6652197835259177259">Настройки локально управляемых профилей</translation>
 <translation id="6658245400435704251">Время (в секундах), которое может пройти от появления обновления на сервере до его скачивания на устройство. Это время определяется как длительностью самого скачивания, так и частотой проверок на наличие обновлений. Задается максимальное время задержки, по истечении которого автообновление точно будет выполнено.</translation>
 <translation id="6665670272107384733">Указать, как часто требуется вводить пароль, чтобы пользоваться быстрой разблокировкой</translation>
-<translation id="6672070613706645316">Разрешение для пользователей изменять фон на странице быстрого доступа</translation>
+<translation id="6672070613706645316">Разрешить пользователям менять фон на странице быстрого доступа</translation>
 <translation id="6672630473862787247">Включить пассивную аутентификацию для обычных и гостевых сеансов, а также режима инкогнито</translation>
 <translation id="6681229465468164801">Позволяет задать список шаблонов URL для сайтов, которым запрещено запрашивать доступ к USB-устройствам.
 
@@ -4740,7 +4740,7 @@
       Если параметр отключен, удаление будет недоступно.</translation>
 <translation id="8749803771700374502">Типы принтеров, добавленные в список недопустимых, станут невидимыми, и ими нельзя будет воспользоваться.
 
-      Если добавить в список принтеры всех типов, функция печати будет недоступна, так как не останется устройств, на которые можно отправить документ.
+      Если добавить в список все типы принтеров, функция печати будет недоступна, так как не останется устройств, на которые можно отправить документ.
 
       Добавив параметр <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> в список недопустимых принтеров, вы получите тот же результат, что и при установке значения False для правила <ph name="POLICY_CLOUDPRINTSUBMITENABLED" />. Чтобы принтеры, подключенные к сервису "<ph name="CLOUD_PRINT_NAME" />", были доступны для печати, убедитесь, что для правила <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> задано значение True, а в списке недопустимых принтеров нет параметра <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />.
 
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb
index c82c6f47..bb6d11d 100644
--- a/components/policy/resources/policy_templates_tr.xtb
+++ b/components/policy/resources/policy_templates_tr.xtb
@@ -1936,11 +1936,11 @@
           Bu politikayı ayarlarsanız kullanıcılar değiştiremez veya geçersiz kılamazlar.
 
           Bu politika ayarlanmadan bırakılırsa giriş ekranında sanal klavye başlangıçta devre dışı bırakılır, ancak kullanıcılar istedikleri zaman etkinleştirebilirler.</translation>
-<translation id="3913530489429898348"><ph name="CLOUD_PRINT_NAME" /> yazıcısına yazdırmak üzere doküman göndermesi için <ph name="PRODUCT_NAME" /> ürününü etkinleştirir.  NOT: Bu sadece <ph name="PRODUCT_NAME" /> ürününde <ph name="CLOUD_PRINT_NAME" /> desteğini etkiler.  Kullanıcıların web sitelerinde yazdırma işi göndermelerini engellemez.
+<translation id="3913530489429898348"><ph name="PRODUCT_NAME" /> ürününün <ph name="CLOUD_PRINT_NAME" /> yazıcısına çıktı almak için doküman gönderebilmesine izin verir.  NOT: Bu ayar, <ph name="PRODUCT_NAME" /> ürününde sadece <ph name="CLOUD_PRINT_NAME" /> desteğini etkiler.  Kullanıcıların web sitelerinde yazdırma işi göndermelerini engellemez.
 
-      Bu ayar etkinleştirilmez veya yapılandırılmazsa kullanıcılar, <ph name="PRODUCT_NAME" /> ürününün yazdırma iletişim kutusundan <ph name="CLOUD_PRINT_NAME" /> bulutuna yazdırabilir.
+      Bu ayar etkinleştirilmez veya yapılandırılmazsa kullanıcılar, <ph name="PRODUCT_NAME" /> yazdırma iletişim kutusundan <ph name="CLOUD_PRINT_NAME" /> yazıcısına yazdırma işlemi yapabilir.
 
-      Bu ayar devre dışı bırakılırsa kullanıcılar, <ph name="PRODUCT_NAME" /> ürününün yazdırma iletişim kutusundan <ph name="CLOUD_PRINT_NAME" /> bulutuna yazdıramazlar.
+      Bu ayar devre dışı bırakılırsa kullanıcılar, <ph name="PRODUCT_NAME" /> yazdırma iletişim kutusundan <ph name="CLOUD_PRINT_NAME" /> yazıcısına yazdırma işlemi yapamaz.
 
       <ph name="CLOUD_PRINT_NAME" /> hedeflerini bulunabilir tutmak için bu politikanın true (doğru) değerine ayarlanması ve <ph name="POLICY_PRINTERTYPEDENYLIST" /> politikasına <ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" /> eklenmemesi gerekir.</translation>
 <translation id="391531815696899618">Doğru seçeneğine ayarlanırsa <ph name="PRODUCT_OS_NAME" /> Files uygulamasında Google Drive'ın senkronizasyonunu devre dışı bırakır. Bu durumda Google Drive'a veri yüklenmez.
@@ -2531,7 +2531,7 @@
       </translation>
 <translation id="4906194810004762807">Aygıt Politikası için yenileme hızı</translation>
 <translation id="4917385247580444890">Güçlü</translation>
-<translation id="4919122295221518724">Karma içerik için daha sıkı işlemi etkinleştir</translation>
+<translation id="4919122295221518724">Karma içeriğin işlenmesini daha sıkı hale getir</translation>
 <translation id="4923806312383904642">WebDriver'ın Uyumlu Olmayan Politikaları Geçersiz Kılmasına İzin Ver</translation>
 <translation id="4929721861648439998">Giriş ekranında mono ses erişilebilirlik özelliğini etkinleştirin.
 
@@ -2552,8 +2552,8 @@
 <translation id="4970855112942626932">Tarayıcıda oturum açmayı devre dışı bırak</translation>
 <translation id="4978405676361550165">"OffHours" politikası ayarlanırsa belirtilen cihaz politikaları, tanımlanan zaman aralıklarında yoksayılır (bu politikaların varsayılan ayarları kullanılır). "OffHours" döneminin başladığı veya sona erdiği her etkinlikte cihaz politikaları Chrome tarafından yeniden uygulanır. "OffHours" süresi sona erdiğinde kullanıcı bilgilendirilip çıkış yapmaya zorlanır ve cihaz politikası ayarları değiştirilir (ör. kullanıcı izin verilen bir hesapla giriş yapmadığında).</translation>
 <translation id="4980635395568992380">Veri türü:</translation>
-<translation id="4980794848194997251">Bu politika tarayıcıdaki karma içerik (HTTPS sitelerindeki HTTP içeriği) için işlemi denetler.
-       Politika true (doğru) değerine ayarlanırsa veya ayarlanmamış olarak bırakılırsa ses ve videodan oluşan karma içerik otomatik olarak HTTPS şeklinde yükseltilir (Yani kaynak HTTPS üzerinde kullanılamıyorsa URL yedek olmadan HTTPS olarak yeniden yazılır.) ve görsel karma içerik için URL çubuğunda bir "Güvenli Değil" uyarısı gösterilir.
+<translation id="4980794848194997251">Bu politika tarayıcıdaki karma içeriğin (HTTPS sitelerindeki HTTP içeriği) işlenme şeklini denetler.
+       Politika true (doğru) değerine ayarlanırsa veya ayarlanmamış olarak bırakılırsa ses ve videodan oluşan karma içerik otomatik olarak HTTPS'ye yükseltilir (Yani kaynak HTTPS üzerinde kullanılamıyorsa URL yedek olmadan HTTPS olarak yeniden yazılır.) ve görsel karma içerik için URL çubuğunda bir "Güvenli Değil" uyarısı gösterilir.
        Politika false (yanlış) değerine ayarlanırsa ses ve video için otomatik yükseltmeler devre dışı bırakılır ve görseller için herhangi bir uyarı gösterilmez.
        Bu politika ses, video ve görseller dışındaki diğer karma içerikleri etkilemez.</translation>
 <translation id="4983201894483989687">Eski eklentilerin çalıştırılmasına izin ver</translation>
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb
index 83e59e9..21fb2e4d 100644
--- a/components/policy/resources/policy_templates_vi.xtb
+++ b/components/policy/resources/policy_templates_vi.xtb
@@ -2563,7 +2563,7 @@
 <translation id="4978405676361550165">Nếu bạn đặt chính sách "OffHours" thì Chrome sẽ bỏ qua các chính sách thiết bị đã chỉ định (sử dụng cài đặt mặc định của những chính sách này) trong khoảng thời gian đã định. Chrome sẽ áp dụng lại các chính sách thiết bị đối với mọi sự kiện khi khoảng thời gian "OffHours" bắt đầu hoặc kết thúc. Người dùng sẽ được thông báo và bắt buộc phải đăng xuất khi kết thúc thời gian "OffHours" và khi các cài đặt của chính sách thiết bị thay đổi (ví dụ: khi người dùng đăng nhập bằng một tài khoản không được phép).</translation>
 <translation id="4980635395568992380">Loại dữ liệu:</translation>
 <translation id="4980794848194997251">Chính sách này kiểm soát việc xử lý nội dung hỗn hợp (nội dung HTTP trên các trang web HTTPS) trong trình duyệt.
-       Nếu bạn không đặt hoặc đặt chính sách này thành true, thì nội dung hỗn hợp là âm thanh và video sẽ được nâng cấp tự động lên HTTPS (tức là URL sẽ được viết lại dưới dạng HTTPS mà không có phiên bản dự phòng nếu không có sẵn tài nguyên qua HTTPS), còn với nội dung hỗn hợp là hình ảnh thì một cảnh báo 'Không an toàn' sẽ hiển thị trong thanh URL.
+       Nếu bạn không đặt hoặc đặt chính sách này thành true, thì nội dung hỗn hợp là âm thanh và video sẽ được nâng cấp tự động lên HTTPS (tức là URL sẽ được viết lại dưới dạng HTTPS mà không có phiên bản dự phòng nếu không có sẵn tài nguyên qua HTTPS), còn với nội dung hỗn hợp là hình ảnh thì một cảnh báo 'Không bảo mật' sẽ hiển thị trong thanh URL.
        Nếu bạn đặt chính sách này thành false, thì âm thanh và video sẽ không được nâng cấp tự động, còn với hình ảnh thì sẽ không hiển thị cảnh báo nào.
        Chính sách này không ảnh hưởng đến các loại nội dung hỗn hợp khác ngoài âm thanh, video và hình ảnh.</translation>
 <translation id="4983201894483989687">Cho phép chạy các plugin đã lỗi thời</translation>
@@ -4850,7 +4850,7 @@
 
       Nếu bạn không đặt hoặc đặt chính sách này thành danh sách trống, thì tất cả các loại máy in đều được tìm thấy.
 
-      Máy in kết nối qua tiện ích còn gọi là đích cung cấp dịch vụ in và bao gồm mọi đích thuộc tiện ích của <ph name="PRODUCT_NAME" />.
+      Máy in ở dạng tiện ích còn gọi là đích cung cấp dịch vụ in và bao gồm mọi đích thuộc tiện ích của <ph name="PRODUCT_NAME" />.
 
       Máy in cục bộ (hay còn gọi là đích in gốc) bao gồm các đích dùng được cho thiết bị cục bộ và máy in dùng chung qua mạng.</translation>
 <translation id="8752541111574086388">Xin lưu ý rằng chính sách này không được dùng nữa và sẽ bị xóa trong <ph name="PRODUCT_OS_NAME" /> phiên bản 82. Thay vào đó, vui lòng sử dụng <ph name="POWER_MANAGEMENT_IDLE_SETTINGS_POLICY_NAME" />.
diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb
index add5ac5..959a6ef5c 100644
--- a/components/policy/resources/policy_templates_zh-CN.xtb
+++ b/components/policy/resources/policy_templates_zh-CN.xtb
@@ -4284,11 +4284,11 @@
 
       如果此政策未设置,设备将默认使用24小时制的时钟格式。</translation>
 <translation id="8114382167597081590">不强制启用 YouTube 受限模式</translation>
-<translation id="8117921351531866504">让您能够设置是否允许网站检查用户有无已保存的付款方式。
+<translation id="8117921351531866504">该政策让您能够设置是否允许网站检查用户有无已保存的付款方式。
 
       如果停用了此政策,使用 PaymentRequest.canMakePayment 或 PaymentRequest.hasEnrolledInstrument API 的网站将被告知没有可用的付款方式。
 
-      如果启用了或未配置此设置,则允许网站检查用户有无已保存的付款方式。</translation>
+      如果启用了或未配置此设置,那么系统将允许网站检查用户有无已保存的付款方式。</translation>
 <translation id="8118665053362250806">设置媒体磁盘缓存大小</translation>
 <translation id="8124468781472887384">设备打印机配置访问政策。</translation>
 <translation id="8138009212169037227">此政策可控制是否报告政策数据和政策提取时间。
@@ -4635,13 +4635,13 @@
       如果已启用此设置或将此设置留空,则可以删除浏览和下载记录。
 
       如果停用了此设置,则不能删除浏览和下载记录。</translation>
-<translation id="8749803771700374502">系统将无法发现拒绝列表中列出的各类打印机,并且无法获取它们的功能。 
+<translation id="8749803771700374502">已在拒绝列表中的各类打印机将被停用,因此用户将无法发现或使用它们。
 
-      将所有打印机类型都添加到拒绝列表中可有效地停用打印功能,因为打印文件时,系统将无法找到可接收文件的目的地。
+      将所有打印机类型都添加到拒绝列表中相当于停用打印功能,因为没有任何可用来接收要打印的文档的目的地。
 
-      在拒绝列表中添加“<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />”与将 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 政策设为 False 具有同样的效果。若希望系统能够发现 <ph name="CLOUD_PRINT_NAME" />目的地,则必须确保 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 政策设为 True 且拒绝列表中不含“<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />”。
+      在拒绝列表中添加“<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />”与将 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 政策设为 false 具有同样的效果。若要使 <ph name="CLOUD_PRINT_NAME" />目的地能被用户发现,则必须确保 <ph name="POLICY_CLOUDPRINTSUBMITENABLED" /> 政策设为 true 且拒绝列表中不含“<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />”。
 
-      如果此政策未设置,或设为一个空列表,那么系统将可以发现所有类型的打印机。
+      如果此政策未设置,或设为一个空列表,那么所有打印机类型都将能被用户发现。
 
       基于扩展程序的打印机也称为打印提供程序目的地,包括 <ph name="PRODUCT_NAME" /> 扩展程序名下的所有目的地。
 
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb
index 5210ca6a..8f688efa 100644
--- a/components/policy/resources/policy_templates_zh-TW.xtb
+++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -2521,7 +2521,7 @@
 <translation id="5067143124345820993">登入使用者許可清單</translation>
 <translation id="5073609397321802133">如果將這項政策設為 False,系統將禁止使用者自訂新分頁的背景。即使日後將這項政策設為 True,系統仍會永久移除任何現有的自訂背景。
 
-      如果不設定這項政策或設為 True,使用者可以自訂新分頁的背景。</translation>
+      如果不設定這項政策或將其設為 True,使用者可以自訂新分頁的背景。</translation>
 <translation id="5075834892754086022">如果設定這項政策,系統會強制使用政策所設定的 PIN 碼長度
           下限。(PIN 碼長度的絕對下限為 1;系統會將低於 1
           的值視為 1 處理。)
@@ -4673,7 +4673,7 @@
       如果停用這項政策,則使用者無法刪除瀏覽和下載記錄項目。</translation>
 <translation id="8749803771700374502">系統不會搜尋拒絕清單上列出的印表機類型,也不會擷取這類印表機可支援的列印功能。
 
-      在拒絕清單上列出所有印表機類型的效果與停用列印功能相同,因為這樣一來,系統傳送文件進行列印時就沒有可用的目的地。
+      在拒絕清單上列出所有印表機類型的效果與停用列印功能相同,因為這樣一來,系統傳送文件進行列印時,就沒有目的地可供使用。
 
       在拒絕清單上加入「<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />」的作用等同於將「<ph name="POLICY_CLOUDPRINTSUBMITENABLED" />」政策設定為 False。如要讓系統搜尋到 <ph name="CLOUD_PRINT_NAME" /> 目的地,「<ph name="POLICY_CLOUDPRINTSUBMITENABLED" />」政策必須設為 True,且拒絕清單中不得包含「<ph name="POLICY_ENUM_PRINTERTYPEDENYLIST_CLOUD" />」。
 
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index 41f6c6b..8980214 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -1141,10 +1141,6 @@
 }
 
 void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
-  // Allow Prerendering to cancel this print request if necessary.
-  if (delegate_->CancelPrerender(render_frame()))
-    return;
-
   blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame();
   if (!IsScriptInitiatedPrintAllowed(web_frame, user_initiated))
     return;
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index a432a1e..967a03f 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -97,10 +97,6 @@
    public:
     virtual ~Delegate() {}
 
-    // Cancels prerender if it's currently in progress and returns true if the
-    // cancellation succeeded.
-    virtual bool CancelPrerender(content::RenderFrame* render_frame) = 0;
-
     // Returns the element to be printed. Returns a null WebElement if
     // a pdf plugin element can't be extracted from the frame.
     virtual blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) = 0;
diff --git a/components/printing/test/print_test_content_renderer_client.cc b/components/printing/test/print_test_content_renderer_client.cc
index 440e48e..8bf504f 100644
--- a/components/printing/test/print_test_content_renderer_client.cc
+++ b/components/printing/test/print_test_content_renderer_client.cc
@@ -18,9 +18,6 @@
  public:
   ~PrintRenderFrameHelperDelegate() override {}
 
-  bool CancelPrerender(content::RenderFrame* render_frame) override {
-    return false;
-  }
   blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override {
     return blink::WebElement();
   }
diff --git a/components/proxy_config/pref_proxy_config_tracker_impl.cc b/components/proxy_config/pref_proxy_config_tracker_impl.cc
index 82c2af04..76a2df18 100644
--- a/components/proxy_config/pref_proxy_config_tracker_impl.cc
+++ b/components/proxy_config/pref_proxy_config_tracker_impl.cc
@@ -166,9 +166,10 @@
   active_config_ = pref_config_;
 
   proxy_prefs_.Init(pref_service);
-  proxy_prefs_.Add(proxy_config::prefs::kProxy,
-                   base::Bind(&PrefProxyConfigTrackerImpl::OnProxyPrefChanged,
-                              base::Unretained(this)));
+  proxy_prefs_.Add(
+      proxy_config::prefs::kProxy,
+      base::BindRepeating(&PrefProxyConfigTrackerImpl::OnProxyPrefChanged,
+                          base::Unretained(this)));
 }
 
 PrefProxyConfigTrackerImpl::~PrefProxyConfigTrackerImpl() {
diff --git a/components/safe_browsing/proto/csd.proto b/components/safe_browsing/proto/csd.proto
index e8a0a0a..fe2bb07 100644
--- a/components/safe_browsing/proto/csd.proto
+++ b/components/safe_browsing/proto/csd.proto
@@ -148,44 +148,6 @@
   repeated string OBSOLETE_whitelist_expression = 2;
 }
 
-message ClientMalwareRequest {
-  // URL that the client visited.  The CGI parameters are stripped by the
-  // client.
-  required string url = 1;
-
-  // Field 2 is deleted and no longer in use.
-
-  // Field 3 is only used on the server.
-
-  // The referrer URL.  This field might not be set, for example, in the case
-  // where the referrer uses HTTPS.
-  optional string referrer_url = 4;
-
-  // Field 5 and 6 are only used on the server.
-
-  message UrlInfo {
-    required string ip = 1;
-
-    // The final URL for the request (final = after redirects).
-    //
-    // Only the origin portion of the URL is present.  The full URL is not
-    // available, because of https://crbug.com/973885.
-    required string url = 2;
-
-    optional string method = 3;
-    optional string referrer = 4;
-    // Resource type, the int value is a direct cast from the Type enum
-    // of ResourceType class defined in //src/webkit/commom/resource_type.h
-    optional int32 resource_type = 5;
-  }
-
-  // List of resource urls that match the malware IP list.
-  repeated UrlInfo bad_ip_url_info = 7;
-
-  // Population that the reporting user is part of.
-  optional ChromeUserPopulation population = 9;
-}
-
 // The message is used for client request to determine whether the provided URL
 // is safe for the purposes of entering user credentials for logging in.
 message LoginReputationClientRequest {
@@ -476,16 +438,6 @@
   optional int32 model_version = 3;
 }
 
-message ClientMalwareResponse {
-  required bool blacklist = 1;
-  // The confirmed blacklisted bad IP and its url, which will be shown in
-  // malware warning, if the blacklist verdict is true.
-  // This IP string could be either in IPv4 or IPv6 format, which is the same
-  // as the ones client sent to server.
-  optional string bad_ip = 2;
-  optional string bad_url = 3;
-}
-
 message ClientDownloadRequest {
   // The final URL of the download (after all redirects).
   required string url = 1;
diff --git a/components/safe_browsing/web_ui/resources/safe_browsing.html b/components/safe_browsing/web_ui/resources/safe_browsing.html
index 545a263b..bf59bf9 100644
--- a/components/safe_browsing/web_ui/resources/safe_browsing.html
+++ b/components/safe_browsing/web_ui/resources/safe_browsing.html
@@ -28,6 +28,7 @@
         <tab id="rt-lookup">RT Lookup</tab>
         <tab id="referrer-chain">Referrer Chain</tab>
         <tab id="log">Log Messages</tab>
+        <tab id="reporting">Reporting Events</tab>
       </tabs>
       <tabpanels>
         <tabpanel>
@@ -108,6 +109,12 @@
             <p id="log-messages"></p>
           </div>
         </tabpanel>
+        <tabpanel>
+          <h2>Reporting Events</h2>
+          <div class="content">
+            <p id="reporting-events"></p>
+          </div>
+        </tabpanel>
       </tabpanels>
     </tabbox>
     <script src="safe_browsing.js"></script>
diff --git a/components/safe_browsing/web_ui/resources/safe_browsing.js b/components/safe_browsing/web_ui/resources/safe_browsing.js
index b9cd778..919bf9d 100644
--- a/components/safe_browsing/web_ui/resources/safe_browsing.js
+++ b/components/safe_browsing/web_ui/resources/safe_browsing.js
@@ -120,6 +120,15 @@
       addLogMessage(message);
     });
 
+    cr.sendWithPromise('getReportingEvents', []).then((reportingEvents) => {
+      reportingEvents.forEach(function(reportingEvent) {
+        addReportingEvent(reportingEvent);
+      });
+    });
+    cr.addWebUIListener('reporting-events-update', function(reportingEvent) {
+      addReportingEvent(reportingEvent);
+    });
+
     $('get-referrer-chain-form').addEventListener('submit', addReferrerChain);
 
     // Allow tabs to be navigated to by fragment. The fragment with be of the
@@ -270,6 +279,12 @@
     appendChildWithInnerText(logDiv, eventFormatted);
   }
 
+  function addReportingEvent(result) {
+    const logDiv = $('reporting-events');
+    const eventFormatted = result['message'];
+    appendChildWithInnerText(logDiv, eventFormatted);
+  }
+
   function appendChildWithInnerText(logDiv, text) {
     if (!logDiv) {
       return;
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc
index 1d41efc..7df30fc0 100644
--- a/components/safe_browsing/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -231,6 +231,20 @@
     webui_listener->NotifyLogMessageJsListener(timestamp, message);
 }
 
+void WebUIInfoSingleton::AddToReportingEvents(const base::Value& event) {
+  if (!HasListener())
+    return;
+
+  for (auto* webui_listener : webui_instances_)
+    webui_listener->NotifyReportingEventJsListener(event);
+
+  reporting_events_.push_back(event.Clone());
+}
+
+void WebUIInfoSingleton::ClearReportingEvents() {
+  std::vector<base::Value>().swap(reporting_events_);
+}
+
 void WebUIInfoSingleton::RegisterWebUIInstance(SafeBrowsingUIHandler* webui) {
   webui_instances_.push_back(webui);
 }
@@ -1185,6 +1199,19 @@
   return std::move(result);
 }
 
+base::Value SerializeReportingEvent(const base::Value& event) {
+  base::DictionaryValue result;
+
+  std::string event_serialized;
+  JSONStringValueSerializer serializer(&event_serialized);
+  serializer.set_pretty_print(true);
+  serializer.Serialize(event);
+
+  result.SetString("message", event_serialized);
+
+  return std::move(result);
+}
+
 }  // namespace
 
 SafeBrowsingUI::SafeBrowsingUI(content::WebUI* web_ui)
@@ -1522,6 +1549,19 @@
                             base::Value(referrer_chain_serialized));
 }
 
+void SafeBrowsingUIHandler::GetReportingEvents(const base::ListValue* args) {
+  base::ListValue reporting_events;
+  for (const auto& reporting_event :
+       WebUIInfoSingleton::GetInstance()->reporting_events()) {
+    reporting_events.Append(reporting_event.Clone());
+  }
+
+  AllowJavascript();
+  std::string callback_id;
+  args->GetString(0, &callback_id);
+  ResolveJavascriptCallback(base::Value(callback_id), reporting_events);
+}
+
 void SafeBrowsingUIHandler::GetLogMessages(const base::ListValue* args) {
   const std::vector<std::pair<base::Time, std::string>>& log_messages =
       WebUIInfoSingleton::GetInstance()->log_messages();
@@ -1624,6 +1664,12 @@
                     base::Value(SerializeLogMessage(timestamp, message)));
 }
 
+void SafeBrowsingUIHandler::NotifyReportingEventJsListener(
+    const base::Value& event) {
+  AllowJavascript();
+  FireWebUIListener("reporting-events-update", SerializeReportingEvent(event));
+}
+
 void SafeBrowsingUIHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
       "getExperiments",
@@ -1686,6 +1732,10 @@
       "getReferrerChain",
       base::BindRepeating(&SafeBrowsingUIHandler::GetReferrerChain,
                           base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
+      "getReportingEvents",
+      base::BindRepeating(&SafeBrowsingUIHandler::GetReportingEvents,
+                          base::Unretained(this)));
 }
 
 void SafeBrowsingUIHandler::SetWebUIForTesting(content::WebUI* web_ui) {
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.h b/components/safe_browsing/web_ui/safe_browsing_ui.h
index 77d791b..de297bba 100644
--- a/components/safe_browsing/web_ui/safe_browsing_ui.h
+++ b/components/safe_browsing/web_ui/safe_browsing_ui.h
@@ -99,6 +99,10 @@
   // currently open chrome://safe-browsing tab was opened.
   void GetLogMessages(const base::ListValue* args);
 
+  // Get the reporting events that have been collected since the oldest
+  // currently open chrome://safe-browsing tab was opened.
+  void GetReportingEvents(const base::ListValue* args);
+
   // Register callbacks for WebUI messages.
   void RegisterMessages() override;
 
@@ -155,6 +159,10 @@
   void NotifyLogMessageJsListener(const base::Time& timestamp,
                                   const std::string& message);
 
+  // Called when any new reporting events are sent while one or more WebUI tabs
+  // are open.
+  void NotifyReportingEventJsListener(const base::Value& event);
+
   // Callback when the CookieManager has returned the cookie.
   void OnGetCookie(const std::string& callback_id,
                    const std::vector<net::CanonicalCookie>& cookies);
@@ -258,6 +266,13 @@
   static void NotifyLogMessageListeners(const base::Time& timestamp,
                                         const std::string& message);
 
+  // Add the reporting event to |reporting_events_| and send it to all the open
+  // chrome://safe-browsing tabs.
+  void AddToReportingEvents(const base::Value& event);
+
+  // Clear |reporting_events_|.
+  void ClearReportingEvents();
+
   // Register the new WebUI listener object.
   void RegisterWebUIInstance(SafeBrowsingUIHandler* webui);
 
@@ -339,6 +354,10 @@
     return log_messages_;
   }
 
+  const std::vector<base::Value>& reporting_events() {
+    return reporting_events_;
+  }
+
   network::mojom::CookieManager* GetCookieManager();
 
   void set_network_context(SafeBrowsingNetworkContext* network_context) {
@@ -408,6 +427,10 @@
   // chrome://safe-browsing tab was opened.
   std::vector<std::pair<base::Time, std::string>> log_messages_;
 
+  // List of reporting events logged since the oldest currently open
+  // chrome://safe-browsing tab was opened.
+  std::vector<base::Value> reporting_events_;
+
   // The current referrer chain provider, if any. Can be nullptr.
   ReferrerChainProvider* referrer_chain_provider_ = nullptr;
 
diff --git a/components/security_interstitials_strings_grdp/IDS_BLOCKED_INTERCEPTION_HEADING.png.sha1 b/components/security_interstitials_strings_grdp/IDS_BLOCKED_INTERCEPTION_HEADING.png.sha1
new file mode 100644
index 0000000..aa8bacb
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_BLOCKED_INTERCEPTION_HEADING.png.sha1
@@ -0,0 +1 @@
+5ac911ea653ffd4d82d7df912f6da92fe375259f
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY1.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY1.png.sha1
new file mode 100644
index 0000000..ecf68a3b
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY1.png.sha1
@@ -0,0 +1 @@
+db9e970656a155559e85c0f0b7db271a147dae4c
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY2.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY2.png.sha1
new file mode 100644
index 0000000..1cfa6ed
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_BODY2.png.sha1
@@ -0,0 +1 @@
+79d0d1aaedf594893b606f300a67b2b74f787f2d
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_HEADER.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_HEADER.png.sha1
new file mode 100644
index 0000000..7f247b8e
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_HEADER.png.sha1
@@ -0,0 +1 @@
+29491f5dba49f64ec185737d8fa31b251aa2059f
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_BUTTON_TEXT.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_BUTTON_TEXT.png.sha1
new file mode 100644
index 0000000..fea5d1f
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+8b1881c0651173c7e9ab571fefd34f7a0b7caa44
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_HEADING.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_HEADING.png.sha1
new file mode 100644
index 0000000..e03454d
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_INFOBAR_HEADING.png.sha1
@@ -0,0 +1 @@
+ff6821acb6e154778dc3f179ae4efc1bfbc40b3a
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_TITLE.png.sha1 b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_TITLE.png.sha1
new file mode 100644
index 0000000..749f02e
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_KNOWN_INTERCEPTION_TITLE.png.sha1
@@ -0,0 +1 @@
+4333116ae9f43d9d0488943f4ec60aaabf9e2344
\ No newline at end of file
diff --git a/components/storage_monitor/image_capture_device.mm b/components/storage_monitor/image_capture_device.mm
index 7d175e23..20921d66 100644
--- a/components/storage_monitor/image_capture_device.mm
+++ b/components/storage_monitor/image_capture_device.mm
@@ -224,9 +224,9 @@
       FROM_HERE,
       {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT,
        base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
-      base::Bind(&storage_monitor::RenameFile, savedPath, saveAsPath),
-      base::Bind(&storage_monitor::ReturnRenameResultToListener, _listener,
-                 name));
+      base::BindOnce(&storage_monitor::RenameFile, savedPath, saveAsPath),
+      base::BindOnce(&storage_monitor::ReturnRenameResultToListener, _listener,
+                     name));
 }
 
 // MacOS 10.14 SDK methods, not yet implemented (https://crbug.com/849689)
diff --git a/components/storage_monitor/image_capture_device_manager.h b/components/storage_monitor/image_capture_device_manager.h
index 4d94e5c4..b3051d6 100644
--- a/components/storage_monitor/image_capture_device_manager.h
+++ b/components/storage_monitor/image_capture_device_manager.h
@@ -43,9 +43,9 @@
 
   // Eject the given device. The ID passed is not the device ID, but the
   // ImageCapture UUID.
-  void EjectDevice(const std::string& uuid,
-                   base::Callback<void(StorageMonitor::EjectStatus)> callback);
-
+  void EjectDevice(
+      const std::string& uuid,
+      base::OnceCallback<void(StorageMonitor::EjectStatus)> callback);
 
  private:
   base::scoped_nsobject<ImageCaptureDeviceManagerImpl> device_browser_;
diff --git a/components/storage_monitor/image_capture_device_manager.mm b/components/storage_monitor/image_capture_device_manager.mm
index 232206f6..34e4043 100644
--- a/components/storage_monitor/image_capture_device_manager.mm
+++ b/components/storage_monitor/image_capture_device_manager.mm
@@ -155,12 +155,12 @@
 
 void ImageCaptureDeviceManager::EjectDevice(
     const std::string& uuid,
-    base::Callback<void(StorageMonitor::EjectStatus)> callback) {
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
   base::scoped_nsobject<ImageCaptureDevice> camera_device(
       [[device_browser_ deviceForUUID:uuid] retain]);
   [camera_device eject];
   [camera_device close];
-  callback.Run(StorageMonitor::EJECT_OK);
+  std::move(callback).Run(StorageMonitor::EJECT_OK);
 }
 
 // static
diff --git a/components/storage_monitor/media_storage_util.cc b/components/storage_monitor/media_storage_util.cc
index 7b3f5b1..f8100517 100644
--- a/components/storage_monitor/media_storage_util.cc
+++ b/components/storage_monitor/media_storage_util.cc
@@ -99,14 +99,14 @@
 
 // static
 void MediaStorageUtil::FilterAttachedDevices(DeviceIdSet* devices,
-                                             const base::Closure& done) {
+                                             base::OnceClosure done) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   base::PostTaskAndReply(
       FROM_HERE,
       {base::ThreadPool(), base::TaskPriority::BEST_EFFORT, base::MayBlock(),
        base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::BindOnce(&FilterAttachedDevicesOnBackgroundSequence, devices),
-      done);
+      std::move(done));
 }
 
 // TODO(kmadhusu) Write unit tests for GetDeviceInfoFromPath().
diff --git a/components/storage_monitor/media_storage_util.h b/components/storage_monitor/media_storage_util.h
index 6b0bb74..8d770ac0 100644
--- a/components/storage_monitor/media_storage_util.h
+++ b/components/storage_monitor/media_storage_util.h
@@ -37,7 +37,7 @@
 
   // Removes disconnected devices from |devices| and then calls |done|.
   static void FilterAttachedDevices(DeviceIdSet* devices,
-                                    const base::Closure& done);
+                                    base::OnceClosure done);
 
   // Given |path|, fill in |device_info|, and |relative_path|
   // (from the root of the device).
diff --git a/components/storage_monitor/mtab_watcher_linux.cc b/components/storage_monitor/mtab_watcher_linux.cc
index 1f82208..407530d 100644
--- a/components/storage_monitor/mtab_watcher_linux.cc
+++ b/components/storage_monitor/mtab_watcher_linux.cc
@@ -41,8 +41,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   bool ret = file_watcher_.Watch(
       mtab_path_, false,
-      base::Bind(&MtabWatcherLinux::OnFilePathChanged,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindRepeating(&MtabWatcherLinux::OnFilePathChanged,
+                          weak_ptr_factory_.GetWeakPtr()));
   if (!ret) {
     LOG(ERROR) << "Adding watch for " << mtab_path_.value() << " failed";
     return;
diff --git a/components/storage_monitor/mtab_watcher_linux.h b/components/storage_monitor/mtab_watcher_linux.h
index cecd92e..bd7ef28 100644
--- a/components/storage_monitor/mtab_watcher_linux.h
+++ b/components/storage_monitor/mtab_watcher_linux.h
@@ -31,7 +31,7 @@
   using MountPointDeviceMap = std::map<base::FilePath, base::FilePath>;
 
   using UpdateMtabCallback =
-      base::Callback<void(const MountPointDeviceMap& new_mtab)>;
+      base::RepeatingCallback<void(const MountPointDeviceMap& new_mtab)>;
 
   // |callback| is called on the same sequence as the rest of the class.
   // Caller is responsible for bouncing to the correct sequence.
diff --git a/components/storage_monitor/mtp_manager_client_chromeos.cc b/components/storage_monitor/mtp_manager_client_chromeos.cc
index 844dfe1b..7d1e91a2 100644
--- a/components/storage_monitor/mtp_manager_client_chromeos.cc
+++ b/components/storage_monitor/mtp_manager_client_chromeos.cc
@@ -52,17 +52,17 @@
 
 void MtpManagerClientChromeOS::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(StorageMonitor::EjectStatus)> callback) {
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
   std::string location;
   if (!GetLocationForDeviceId(device_id, &location)) {
-    callback.Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
+    std::move(callback).Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
     return;
   }
 
   // TODO(thestig): Change this to tell the MTP manager to eject the device.
 
   StorageDetached(location);
-  callback.Run(StorageMonitor::EJECT_OK);
+  std::move(callback).Run(StorageMonitor::EJECT_OK);
 }
 
 // device::mojom::MtpManagerClient override.
diff --git a/components/storage_monitor/mtp_manager_client_chromeos.h b/components/storage_monitor/mtp_manager_client_chromeos.h
index 7a1815f..2cab72f 100644
--- a/components/storage_monitor/mtp_manager_client_chromeos.h
+++ b/components/storage_monitor/mtp_manager_client_chromeos.h
@@ -33,8 +33,9 @@
   bool GetStorageInfoForPath(const base::FilePath& path,
                              StorageInfo* storage_info) const;
 
-  void EjectDevice(const std::string& device_id,
-                   base::Callback<void(StorageMonitor::EjectStatus)> callback);
+  void EjectDevice(
+      const std::string& device_id,
+      base::OnceCallback<void(StorageMonitor::EjectStatus)> callback);
 
  protected:
   // device::mojom::MtpManagerClient implementation.
diff --git a/components/storage_monitor/portable_device_watcher_win.cc b/components/storage_monitor/portable_device_watcher_win.cc
index ae44f0f0..e597770 100644
--- a/components/storage_monitor/portable_device_watcher_win.cc
+++ b/components/storage_monitor/portable_device_watcher_win.cc
@@ -568,7 +568,7 @@
 
 void PortableDeviceWatcherWin::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(StorageMonitor::EjectStatus)> callback) {
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
   // MTP devices on Windows don't have a detach API needed -- signal
   // the object as if the device is gone and tell the caller it is OK
   // to remove.
@@ -576,12 +576,12 @@
   base::string16 storage_object_id;
   if (!GetMTPStorageInfoFromDeviceId(device_id,
                                      &device_location, &storage_object_id)) {
-    callback.Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
+    std::move(callback).Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
     return;
   }
   HandleDeviceDetachEvent(device_location);
 
-  callback.Run(StorageMonitor::EJECT_OK);
+  std::move(callback).Run(StorageMonitor::EJECT_OK);
 }
 
 void PortableDeviceWatcherWin::EnumerateAttachedDevices() {
@@ -590,9 +590,9 @@
   Devices* devices = new Devices;
   base::PostTaskAndReplyWithResult(
       media_task_runner_.get(), FROM_HERE,
-      base::Bind(&EnumerateAttachedDevicesOnBlockingThread, devices),
-      base::Bind(&PortableDeviceWatcherWin::OnDidEnumerateAttachedDevices,
-                 weak_ptr_factory_.GetWeakPtr(), base::Owned(devices)));
+      base::BindOnce(&EnumerateAttachedDevicesOnBlockingThread, devices),
+      base::BindOnce(&PortableDeviceWatcherWin::OnDidEnumerateAttachedDevices,
+                     weak_ptr_factory_.GetWeakPtr(), base::Owned(devices)));
 }
 
 void PortableDeviceWatcherWin::OnDidEnumerateAttachedDevices(
@@ -614,10 +614,11 @@
   DeviceDetails* device_details = new DeviceDetails;
   base::PostTaskAndReplyWithResult(
       media_task_runner_.get(), FROM_HERE,
-      base::Bind(&HandleDeviceAttachedEventOnBlockingThread, pnp_device_id,
-                 device_details),
-      base::Bind(&PortableDeviceWatcherWin::OnDidHandleDeviceAttachEvent,
-                 weak_ptr_factory_.GetWeakPtr(), base::Owned(device_details)));
+      base::BindOnce(&HandleDeviceAttachedEventOnBlockingThread, pnp_device_id,
+                     device_details),
+      base::BindOnce(&PortableDeviceWatcherWin::OnDidHandleDeviceAttachEvent,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     base::Owned(device_details)));
 }
 
 void PortableDeviceWatcherWin::OnDidHandleDeviceAttachEvent(
diff --git a/components/storage_monitor/portable_device_watcher_win.h b/components/storage_monitor/portable_device_watcher_win.h
index 377a97c..72d3e4d 100644
--- a/components/storage_monitor/portable_device_watcher_win.h
+++ b/components/storage_monitor/portable_device_watcher_win.h
@@ -97,8 +97,9 @@
   // devices are found.
   void SetNotifications(StorageMonitor::Receiver* notifications);
 
-  void EjectDevice(const std::string& device_id,
-                   base::Callback<void(StorageMonitor::EjectStatus)> callback);
+  void EjectDevice(
+      const std::string& device_id,
+      base::OnceCallback<void(StorageMonitor::EjectStatus)> callback);
 
  private:
   friend class TestPortableDeviceWatcherWin;
diff --git a/components/storage_monitor/storage_monitor.cc b/components/storage_monitor/storage_monitor.cc
index 95674df..899cf6ee 100644
--- a/components/storage_monitor/storage_monitor.cc
+++ b/components/storage_monitor/storage_monitor.cc
@@ -83,16 +83,16 @@
   return results;
 }
 
-void StorageMonitor::EnsureInitialized(base::Closure callback) {
+void StorageMonitor::EnsureInitialized(base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (initialized_) {
     if (!callback.is_null())
-      callback.Run();
+      std::move(callback).Run();
     return;
   }
 
   if (!callback.is_null()) {
-    on_initialize_callbacks_.push_back(callback);
+    on_initialize_callbacks_.push_back(std::move(callback));
   }
 
   if (initializing_)
@@ -127,10 +127,10 @@
 
 void StorageMonitor::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(EjectStatus)> callback) {
+    base::OnceCallback<void(EjectStatus)> callback) {
   // Platform-specific implementations will override this method to
   // perform actual device ejection.
-  callback.Run(EJECT_FAILURE);
+  std::move(callback).Run(EJECT_FAILURE);
 }
 
 StorageMonitor::StorageMonitor()
@@ -151,10 +151,8 @@
 
 void StorageMonitor::MarkInitialized() {
   initialized_ = true;
-  for (auto iter = on_initialize_callbacks_.begin();
-       iter != on_initialize_callbacks_.end(); ++iter) {
-    iter->Run();
-  }
+  for (auto& callback : on_initialize_callbacks_)
+    std::move(callback).Run();
   on_initialize_callbacks_.clear();
 }
 
diff --git a/components/storage_monitor/storage_monitor.h b/components/storage_monitor/storage_monitor.h
index 12e415d..8200c65 100644
--- a/components/storage_monitor/storage_monitor.h
+++ b/components/storage_monitor/storage_monitor.h
@@ -94,7 +94,7 @@
   // |GetStorageInfoForPath| may not return the correct results. In addition,
   // registered observers will not be notified on device attachment/detachment.
   // Callbacks will run on the same sequence as the rest of the class.
-  void EnsureInitialized(base::Closure callback);
+  void EnsureInitialized(base::OnceClosure callback);
 
   // Return true if the storage monitor has already been initialized.
   bool IsInitialized() const;
@@ -134,9 +134,8 @@
   std::string GetTransientIdForDeviceId(const std::string& device_id);
   std::string GetDeviceIdForTransientId(const std::string& transient_id) const;
 
-  virtual void EjectDevice(
-      const std::string& device_id,
-      base::Callback<void(EjectStatus)> callback);
+  virtual void EjectDevice(const std::string& device_id,
+                           base::OnceCallback<void(EjectStatus)> callback);
 
  protected:
   friend class ::MediaFileSystemRegistryTest;
@@ -177,7 +176,7 @@
 
   bool initializing_;
   bool initialized_;
-  std::vector<base::Closure> on_initialize_callbacks_;
+  std::vector<base::OnceClosure> on_initialize_callbacks_;
 
   // For manipulating storage_map_ structure.
   mutable base::Lock storage_lock_;
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc
index ab86911..c6f76616 100644
--- a/components/storage_monitor/storage_monitor_chromeos.cc
+++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -145,10 +145,10 @@
   for (const auto& it : DiskMountManager::GetInstance()->mount_points()) {
     base::PostTaskAndReplyWithResult(
         blocking_task_runner.get(), FROM_HERE,
-        base::Bind(&MediaStorageUtil::HasDcim,
-                   base::FilePath(it.second.mount_path)),
-        base::Bind(&StorageMonitorCros::AddMountedPath,
-                   weak_ptr_factory_.GetWeakPtr(), it.second));
+        base::BindOnce(&MediaStorageUtil::HasDcim,
+                       base::FilePath(it.second.mount_path)),
+        base::BindOnce(&StorageMonitorCros::AddMountedPath,
+                       weak_ptr_factory_.GetWeakPtr(), it.second));
   }
 
   // Note: Relies on scheduled tasks on the |blocking_task_runner| being
@@ -217,10 +217,10 @@
           FROM_HERE,
           {base::ThreadPool(), base::MayBlock(),
            base::TaskPriority::BEST_EFFORT},
-          base::Bind(&MediaStorageUtil::HasDcim,
-                     base::FilePath(mount_info.mount_path)),
-          base::Bind(&StorageMonitorCros::AddMountedPath,
-                     weak_ptr_factory_.GetWeakPtr(), mount_info));
+          base::BindOnce(&MediaStorageUtil::HasDcim,
+                         base::FilePath(mount_info.mount_path)),
+          base::BindOnce(&StorageMonitorCros::AddMountedPath,
+                         weak_ptr_factory_.GetWeakPtr(), mount_info));
       break;
     }
     case DiskMountManager::UNMOUNTING: {
@@ -269,25 +269,25 @@
 // Callback executed when the unmount call is run by DiskMountManager.
 // Forwards result to |EjectDevice| caller.
 void NotifyUnmountResult(
-    base::Callback<void(StorageMonitor::EjectStatus)> callback,
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback,
     chromeos::MountError error_code) {
   if (error_code == chromeos::MOUNT_ERROR_NONE)
-    callback.Run(StorageMonitor::EJECT_OK);
+    std::move(callback).Run(StorageMonitor::EJECT_OK);
   else
-    callback.Run(StorageMonitor::EJECT_FAILURE);
+    std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
 }
 
 void StorageMonitorCros::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(EjectStatus)> callback) {
+    base::OnceCallback<void(EjectStatus)> callback) {
   StorageInfo::Type type;
   if (!StorageInfo::CrackDeviceId(device_id, &type, NULL)) {
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
     return;
   }
 
   if (type == StorageInfo::MTP_OR_PTP) {
-    mtp_manager_client_->EjectDevice(device_id, callback);
+    mtp_manager_client_->EjectDevice(device_id, std::move(callback));
     return;
   }
 
@@ -299,18 +299,18 @@
   }
 
   if (mount_path.empty()) {
-    callback.Run(EJECT_NO_SUCH_DEVICE);
+    std::move(callback).Run(EJECT_NO_SUCH_DEVICE);
     return;
   }
 
   DiskMountManager* manager = DiskMountManager::GetInstance();
   if (!manager) {
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
     return;
   }
 
-  manager->UnmountPath(mount_path,
-                       base::BindOnce(NotifyUnmountResult, callback));
+  manager->UnmountPath(
+      mount_path, base::BindOnce(NotifyUnmountResult, std::move(callback)));
 }
 
 device::mojom::MtpManager*
diff --git a/components/storage_monitor/storage_monitor_chromeos.h b/components/storage_monitor/storage_monitor_chromeos.h
index 5cf12ea..93049a4 100644
--- a/components/storage_monitor/storage_monitor_chromeos.h
+++ b/components/storage_monitor/storage_monitor_chromeos.h
@@ -59,7 +59,7 @@
   bool GetStorageInfoForPath(const base::FilePath& path,
                              StorageInfo* device_info) const override;
   void EjectDevice(const std::string& device_id,
-                   base::Callback<void(EjectStatus)> callback) override;
+                   base::OnceCallback<void(EjectStatus)> callback) override;
   device::mojom::MtpManager* media_transfer_protocol_manager() override;
 
  private:
diff --git a/components/storage_monitor/storage_monitor_chromeos_unittest.cc b/components/storage_monitor/storage_monitor_chromeos_unittest.cc
index 152607d..6f4c1369 100644
--- a/components/storage_monitor/storage_monitor_chromeos_unittest.cc
+++ b/components/storage_monitor/storage_monitor_chromeos_unittest.cc
@@ -99,8 +99,8 @@
     return StorageMonitorCros::GetStorageInfoForPath(path, device_info);
   }
   void EjectDevice(const std::string& device_id,
-                   base::Callback<void(EjectStatus)> callback) override {
-    StorageMonitorCros::EjectDevice(device_id, callback);
+                   base::OnceCallback<void(EjectStatus)> callback) override {
+    StorageMonitorCros::EjectDevice(device_id, std::move(callback));
   }
 
  private:
@@ -534,8 +534,8 @@
   EXPECT_CALL(*disk_mount_manager_mock_,
               UnmountPath(observer().last_attached().location(), _));
   monitor_->EjectDevice(observer().last_attached().device_id(),
-                        base::Bind(&StorageMonitorCrosTest::EjectNotify,
-                                   base::Unretained(this)));
+                        base::BindOnce(&StorageMonitorCrosTest::EjectNotify,
+                                       base::Unretained(this)));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(StorageMonitor::EJECT_OK, status_);
diff --git a/components/storage_monitor/storage_monitor_dummy.cc b/components/storage_monitor/storage_monitor_dummy.cc
index 07ef451d..90b8428 100644
--- a/components/storage_monitor/storage_monitor_dummy.cc
+++ b/components/storage_monitor/storage_monitor_dummy.cc
@@ -26,7 +26,7 @@
   }
 
   void EjectDevice(const std::string& device_id,
-                   base::Callback<void(EjectStatus)> callback) override {}
+                   base::OnceCallback<void(EjectStatus)> callback) override {}
 
   DISALLOW_COPY_AND_ASSIGN(StorageMonitorDummy);
 };
diff --git a/components/storage_monitor/storage_monitor_linux.cc b/components/storage_monitor/storage_monitor_linux.cc
index 1f2a149..b6e5f10 100644
--- a/components/storage_monitor/storage_monitor_linux.cc
+++ b/components/storage_monitor/storage_monitor_linux.cc
@@ -295,11 +295,11 @@
 
 void StorageMonitorLinux::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(EjectStatus)> callback) {
+    base::OnceCallback<void(EjectStatus)> callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   StorageInfo::Type type;
   if (!StorageInfo::CrackDeviceId(device_id, &type, nullptr)) {
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
     return;
   }
 
@@ -319,7 +319,7 @@
   }
 
   if (path.empty()) {
-    callback.Run(EJECT_NO_SUCH_DEVICE);
+    std::move(callback).Run(EJECT_NO_SUCH_DEVICE);
     return;
   }
 
@@ -328,7 +328,8 @@
   base::PostTaskAndReplyWithResult(
       FROM_HERE,
       {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-      base::Bind(&EjectPathOnBlockingTaskRunner, path, device), callback);
+      base::BindOnce(&EjectPathOnBlockingTaskRunner, path, device),
+      std::move(callback));
 }
 
 void StorageMonitorLinux::OnMtabWatcherCreated(
diff --git a/components/storage_monitor/storage_monitor_linux.h b/components/storage_monitor/storage_monitor_linux.h
index 86090f69..d6748153c 100644
--- a/components/storage_monitor/storage_monitor_linux.h
+++ b/components/storage_monitor/storage_monitor_linux.h
@@ -85,7 +85,7 @@
   bool GetStorageInfoForPath(const base::FilePath& path,
                              StorageInfo* device_info) const override;
   void EjectDevice(const std::string& device_id,
-                   base::Callback<void(EjectStatus)> callback) override;
+                   base::OnceCallback<void(EjectStatus)> callback) override;
 
   // Called when the MtabWatcher has been created.
   void OnMtabWatcherCreated(std::unique_ptr<MtabWatcherLinux> watcher);
diff --git a/components/storage_monitor/storage_monitor_mac.h b/components/storage_monitor/storage_monitor_mac.h
index d2ecb268..48627eb7 100644
--- a/components/storage_monitor/storage_monitor_mac.h
+++ b/components/storage_monitor/storage_monitor_mac.h
@@ -45,7 +45,7 @@
                              StorageInfo* device_info) const override;
 
   void EjectDevice(const std::string& device_id,
-                   base::Callback<void(EjectStatus)> callback) override;
+                   base::OnceCallback<void(EjectStatus)> callback) override;
 
  private:
   static void DiskAppearedCallback(DADiskRef disk, void* context);
diff --git a/components/storage_monitor/storage_monitor_mac.mm b/components/storage_monitor/storage_monitor_mac.mm
index 1f1745a2..434ed054 100644
--- a/components/storage_monitor/storage_monitor_mac.mm
+++ b/components/storage_monitor/storage_monitor_mac.mm
@@ -115,7 +115,7 @@
 
 struct EjectDiskOptions {
   std::string bsd_name;
-  base::Callback<void(StorageMonitor::EjectStatus)> callback;
+  base::OnceCallback<void(StorageMonitor::EjectStatus)> callback;
   base::ScopedCFTypeRef<DADiskRef> disk;
 };
 
@@ -125,11 +125,11 @@
   std::unique_ptr<EjectDiskOptions> options_deleter(
       static_cast<EjectDiskOptions*>(context));
   if (dissenter) {
-    options_deleter->callback.Run(StorageMonitor::EJECT_IN_USE);
+    std::move(options_deleter->callback).Run(StorageMonitor::EJECT_IN_USE);
     return;
   }
 
-  options_deleter->callback.Run(StorageMonitor::EJECT_OK);
+  std::move(options_deleter->callback).Run(StorageMonitor::EJECT_OK);
 }
 
 void PostUnmountCallback(DADiskRef disk,
@@ -138,7 +138,7 @@
   std::unique_ptr<EjectDiskOptions> options_deleter(
       static_cast<EjectDiskOptions*>(context));
   if (dissenter) {
-    options_deleter->callback.Run(StorageMonitor::EJECT_IN_USE);
+    std::move(options_deleter->callback).Run(StorageMonitor::EJECT_IN_USE);
     return;
   }
 
@@ -257,18 +257,18 @@
 }
 
 void StorageMonitorMac::EjectDevice(
-      const std::string& device_id,
-      base::Callback<void(EjectStatus)> callback) {
+    const std::string& device_id,
+    base::OnceCallback<void(EjectStatus)> callback) {
   StorageInfo::Type type;
   std::string uuid;
   if (!StorageInfo::CrackDeviceId(device_id, &type, &uuid)) {
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
     return;
   }
 
   if (type == StorageInfo::MAC_IMAGE_CAPTURE &&
       image_capture_device_manager_.get()) {
-    image_capture_device_manager_->EjectDevice(uuid, callback);
+    image_capture_device_manager_->EjectDevice(uuid, std::move(callback));
     return;
   }
 
@@ -283,7 +283,7 @@
   }
 
   if (bsd_name.empty()) {
-    callback.Run(EJECT_NO_SUCH_DEVICE);
+    std::move(callback).Run(EJECT_NO_SUCH_DEVICE);
     return;
   }
 
@@ -292,19 +292,19 @@
   base::ScopedCFTypeRef<DADiskRef> disk(
       DADiskCreateFromBSDName(NULL, session_, bsd_name.c_str()));
   if (!disk.get()) {
-    callback.Run(StorageMonitor::EJECT_FAILURE);
+    std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
     return;
   }
   // Get the reference to the full disk for ejecting.
   disk.reset(DADiskCopyWholeDisk(disk));
   if (!disk.get()) {
-    callback.Run(StorageMonitor::EJECT_FAILURE);
+    std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
     return;
   }
 
   EjectDiskOptions* options = new EjectDiskOptions;
   options->bsd_name = bsd_name;
-  options->callback = callback;
+  options->callback = std::move(callback);
   options->disk = std::move(disk);
   base::PostTask(FROM_HERE, {content::BrowserThread::UI},
                  base::BindOnce(EjectDisk, options));
diff --git a/components/storage_monitor/storage_monitor_unittest.cc b/components/storage_monitor/storage_monitor_unittest.cc
index 14f449a..02f3b6c 100644
--- a/components/storage_monitor/storage_monitor_unittest.cc
+++ b/components/storage_monitor/storage_monitor_unittest.cc
@@ -30,7 +30,7 @@
   EXPECT_FALSE(monitor.init_called());
 
   bool initialized = false;
-  monitor.EnsureInitialized(base::Bind(&SetLatch, &initialized));
+  monitor.EnsureInitialized(base::BindOnce(&SetLatch, &initialized));
   EXPECT_TRUE(monitor.init_called());
   EXPECT_FALSE(initialized);
   monitor.MarkInitialized();
diff --git a/components/storage_monitor/storage_monitor_win.cc b/components/storage_monitor/storage_monitor_win.cc
index add16c6..ff44f90b 100644
--- a/components/storage_monitor/storage_monitor_win.cc
+++ b/components/storage_monitor/storage_monitor_win.cc
@@ -103,19 +103,19 @@
 
 void StorageMonitorWin::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(EjectStatus)> callback) {
+    base::OnceCallback<void(EjectStatus)> callback) {
   StorageInfo::Type type;
   if (!StorageInfo::CrackDeviceId(device_id, &type, nullptr)) {
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
     return;
   }
 
   if (type == StorageInfo::MTP_OR_PTP)
-    portable_device_watcher_->EjectDevice(device_id, callback);
+    portable_device_watcher_->EjectDevice(device_id, std::move(callback));
   else if (StorageInfo::IsRemovableDevice(device_id))
-    volume_mount_watcher_->EjectDevice(device_id, callback);
+    volume_mount_watcher_->EjectDevice(device_id, std::move(callback));
   else
-    callback.Run(EJECT_FAILURE);
+    std::move(callback).Run(EJECT_FAILURE);
 }
 
 bool StorageMonitorWin::GetMTPStorageInfoFromDeviceId(
diff --git a/components/storage_monitor/storage_monitor_win.h b/components/storage_monitor/storage_monitor_win.h
index 53a170f1..d95ea87 100644
--- a/components/storage_monitor/storage_monitor_win.h
+++ b/components/storage_monitor/storage_monitor_win.h
@@ -45,9 +45,8 @@
       base::string16* device_location,
       base::string16* storage_object_id) const override;
 
-  void EjectDevice(
-      const std::string& device_id,
-      base::Callback<void(EjectStatus)> callback) override;
+  void EjectDevice(const std::string& device_id,
+                   base::OnceCallback<void(EjectStatus)> callback) override;
 
  private:
   class PortableDeviceNotifications;
diff --git a/components/storage_monitor/test_storage_monitor.cc b/components/storage_monitor/test_storage_monitor.cc
index d249e30..1a03b2d 100644
--- a/components/storage_monitor/test_storage_monitor.cc
+++ b/components/storage_monitor/test_storage_monitor.cc
@@ -64,8 +64,8 @@
 
   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
                             base::WaitableEvent::InitialState::NOT_SIGNALED);
-  monitor->EnsureInitialized(base::Bind(&base::WaitableEvent::Signal,
-                             base::Unretained(&event)));
+  monitor->EnsureInitialized(
+      base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
   while (!event.IsSignaled()) {
     base::RunLoop().RunUntilIdle();
   }
@@ -128,9 +128,9 @@
 
 void TestStorageMonitor::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(EjectStatus)> callback) {
+    base::OnceCallback<void(EjectStatus)> callback) {
   ejected_device_ = device_id;
-  callback.Run(EJECT_OK);
+  std::move(callback).Run(EJECT_OK);
 }
 
 void TestStorageMonitor::AddRemovablePath(const base::FilePath& path) {
diff --git a/components/storage_monitor/test_storage_monitor.h b/components/storage_monitor/test_storage_monitor.h
index c529a11..d68b412 100644
--- a/components/storage_monitor/test_storage_monitor.h
+++ b/components/storage_monitor/test_storage_monitor.h
@@ -60,7 +60,7 @@
 
   void EjectDevice(
       const std::string& device_id,
-      base::Callback<void(StorageMonitor::EjectStatus)> callback) override;
+      base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) override;
 
   const std::string& ejected_device() const { return ejected_device_; }
 
diff --git a/components/storage_monitor/test_volume_mount_watcher_win.cc b/components/storage_monitor/test_volume_mount_watcher_win.cc
index 0c314bd8..9318334 100644
--- a/components/storage_monitor/test_volume_mount_watcher_win.cc
+++ b/components/storage_monitor/test_volume_mount_watcher_win.cc
@@ -139,14 +139,14 @@
 
 VolumeMountWatcherWin::GetDeviceDetailsCallbackType
 TestVolumeMountWatcherWin::GetDeviceDetailsCallback() const {
-  return base::Bind(&GetMassStorageDeviceDetails);
+  return base::BindOnce(&GetMassStorageDeviceDetails);
 }
 
 VolumeMountWatcherWin::GetAttachedDevicesCallbackType
   TestVolumeMountWatcherWin::GetAttachedDevicesCallback() const {
   if (attached_devices_fake_)
-    return base::Bind(&FakeGetAttachedDevices);
-  return base::Bind(&FakeGetSingleAttachedDevice);
+    return base::BindOnce(&FakeGetAttachedDevices);
+  return base::BindOnce(&FakeGetSingleAttachedDevice);
 }
 
 }  // namespace storage_monitor
diff --git a/components/storage_monitor/volume_mount_watcher_win.cc b/components/storage_monitor/volume_mount_watcher_win.cc
index b594a63..07161848 100644
--- a/components/storage_monitor/volume_mount_watcher_win.cc
+++ b/components/storage_monitor/volume_mount_watcher_win.cc
@@ -215,7 +215,7 @@
 // See http://support.microsoft.com/kb/165721
 void EjectDeviceInThreadPool(
     const base::FilePath& device,
-    base::Callback<void(StorageMonitor::EjectStatus)> callback,
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback,
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     int iteration) {
   base::FilePath::StringType volume_name;
@@ -225,8 +225,9 @@
   // at not-just-drive-letter paths.
   if (drive_letter < L'A' || drive_letter > L'Z' ||
       device != device.DirName()) {
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_FAILURE));
     return;
   }
   base::SStringPrintf(&volume_name, L"\\\\.\\%lc:", drive_letter);
@@ -236,8 +237,9 @@
       nullptr, OPEN_EXISTING, 0, nullptr));
 
   if (!volume_handle.IsValid()) {
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_FAILURE));
     return;
   }
 
@@ -259,14 +261,15 @@
       // transient disk lock.
       task_runner->PostDelayedTask(
           FROM_HERE,
-          base::BindOnce(&EjectDeviceInThreadPool, device, callback,
+          base::BindOnce(&EjectDeviceInThreadPool, device, std::move(callback),
                          task_runner, iteration + 1),
           kLockRetryInterval);
       return;
     }
 
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_IN_USE));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_IN_USE));
     return;
   }
 
@@ -282,8 +285,9 @@
   if (!dismounted) {
     DeviceIoControl(volume_handle.Get(), FSCTL_UNLOCK_VOLUME, nullptr, 0,
                     nullptr, 0, &bytes_returned, nullptr);
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_OK));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_OK));
     return;
   }
 
@@ -293,21 +297,23 @@
   if (!DeviceIoControl(volume_handle.Get(), IOCTL_STORAGE_MEDIA_REMOVAL,
                        &pmr_buffer, sizeof(PREVENT_MEDIA_REMOVAL), nullptr, 0,
                        &bytes_returned, nullptr)) {
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_FAILURE));
     return;
   }
 
   // Physically eject or soft-eject the device.
   if (!DeviceIoControl(volume_handle.Get(), IOCTL_STORAGE_EJECT_MEDIA, nullptr,
                        0, nullptr, 0, &bytes_returned, nullptr)) {
-    base::PostTask(FROM_HERE, {BrowserThread::UI},
-                   base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
+    base::PostTask(
+        FROM_HERE, {BrowserThread::UI},
+        base::BindOnce(std::move(callback), StorageMonitor::EJECT_FAILURE));
     return;
   }
 
   base::PostTask(FROM_HERE, {BrowserThread::UI},
-                 base::BindOnce(callback, StorageMonitor::EJECT_OK));
+                 base::BindOnce(std::move(callback), StorageMonitor::EJECT_OK));
 }
 
 }  // namespace
@@ -343,8 +349,8 @@
   // the initializations here.
   base::PostTaskAndReplyWithResult(
       device_info_task_runner_.get(), FROM_HERE, GetAttachedDevicesCallback(),
-      base::Bind(&VolumeMountWatcherWin::AddDevicesOnUIThread,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&VolumeMountWatcherWin::AddDevicesOnUIThread,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void VolumeMountWatcherWin::AddDevicesOnUIThread(
@@ -366,10 +372,10 @@
 // static
 void VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd(
     const base::FilePath& device_path,
-    const GetDeviceDetailsCallbackType& get_device_details_callback,
+    GetDeviceDetailsCallbackType get_device_details_callback,
     base::WeakPtr<VolumeMountWatcherWin> volume_watcher) {
   StorageInfo info;
-  if (!get_device_details_callback.Run(device_path, &info)) {
+  if (!std::move(get_device_details_callback).Run(device_path, &info)) {
     base::PostTask(FROM_HERE, {BrowserThread::UI},
                    base::BindOnce(&VolumeMountWatcherWin::DeviceCheckComplete,
                                   volume_watcher, device_path));
@@ -395,12 +401,12 @@
 
 VolumeMountWatcherWin::GetAttachedDevicesCallbackType
     VolumeMountWatcherWin::GetAttachedDevicesCallback() const {
-  return base::Bind(&GetAttachedDevices);
+  return base::BindOnce(&GetAttachedDevices);
 }
 
 VolumeMountWatcherWin::GetDeviceDetailsCallbackType
     VolumeMountWatcherWin::GetDeviceDetailsCallback() const {
-  return base::Bind(&GetDeviceDetails);
+  return base::BindOnce(&GetDeviceDetails);
 }
 
 bool VolumeMountWatcherWin::GetDeviceInfo(const base::FilePath& device_path,
@@ -515,21 +521,22 @@
 
 void VolumeMountWatcherWin::EjectDevice(
     const std::string& device_id,
-    base::Callback<void(StorageMonitor::EjectStatus)> callback) {
+    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::FilePath device = MediaStorageUtil::FindDevicePathById(device_id);
   if (device.empty()) {
-    callback.Run(StorageMonitor::EJECT_FAILURE);
+    std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
     return;
   }
   if (device_metadata_.erase(device) == 0) {
-    callback.Run(StorageMonitor::EJECT_FAILURE);
+    std::move(callback).Run(StorageMonitor::EJECT_FAILURE);
     return;
   }
 
   device_info_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&EjectDeviceInThreadPool, device, callback,
-                                device_info_task_runner_, 0));
+      FROM_HERE,
+      base::BindOnce(&EjectDeviceInThreadPool, device, std::move(callback),
+                     device_info_task_runner_, 0));
 }
 
 }  // namespace storage_monitor
diff --git a/components/storage_monitor/volume_mount_watcher_win.h b/components/storage_monitor/volume_mount_watcher_win.h
index 0e60473..72ee5dc 100644
--- a/components/storage_monitor/volume_mount_watcher_win.h
+++ b/components/storage_monitor/volume_mount_watcher_win.h
@@ -57,15 +57,16 @@
   // removable volumes are found.
   void SetNotifications(StorageMonitor::Receiver* notifications);
 
-  void EjectDevice(const std::string& device_id,
-                   base::Callback<void(StorageMonitor::EjectStatus)> callback);
+  void EjectDevice(
+      const std::string& device_id,
+      base::OnceCallback<void(StorageMonitor::EjectStatus)> callback);
 
  protected:
-  typedef base::Callback<bool(const base::FilePath&,
-                              StorageInfo*)> GetDeviceDetailsCallbackType;
+  using GetDeviceDetailsCallbackType =
+      base::OnceCallback<bool(const base::FilePath&, StorageInfo*)>;
 
-  typedef base::Callback<std::vector<base::FilePath>(void)>
-      GetAttachedDevicesCallbackType;
+  using GetAttachedDevicesCallbackType =
+      base::OnceCallback<std::vector<base::FilePath>()>;
 
   // Handles mass storage device attach event on UI thread.
   void HandleDeviceAttachEventOnUIThread(
@@ -82,7 +83,7 @@
   // |volume_watcher| points back to the VolumeMountWatcherWin that called it.
   static void RetrieveInfoForDeviceAndAdd(
       const base::FilePath& device_path,
-      const GetDeviceDetailsCallbackType& get_device_details_callback,
+      GetDeviceDetailsCallbackType get_device_details_callback,
       base::WeakPtr<VolumeMountWatcherWin> volume_watcher);
 
   // Mark that a device we started a metadata check for has completed.
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb
index 853c2c0d..199b83188 100644
--- a/components/strings/components_strings_da.xtb
+++ b/components/strings/components_strings_da.xtb
@@ -1291,7 +1291,7 @@
 <translation id="7219179957768738017">Forbindelsen bruger <ph name="SSL_VERSION" />.</translation>
 <translation id="7220786058474068424">Behandler</translation>
 <translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
-<translation id="724691107663265825">Det site, du er på vej til, indeholder malware</translation>
+<translation id="724691107663265825">Det website, du er på vej til, indeholder malware</translation>
 <translation id="724975217298816891">Opdater dine kortoplysninger ved at indtaste udløbsdatoen og kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles dine kortoplysninger med dette website.</translation>
 <translation id="7251437084390964440">Netværkskonfigurationen overholder ikke ONC-standarden. Dele af konfiguration kan muligvis ikke importeres.
 Yderligere oplysninger:
diff --git a/components/strings/components_strings_eu.xtb b/components/strings/components_strings_eu.xtb
index 382e329..c66317e 100644
--- a/components/strings/components_strings_eu.xtb
+++ b/components/strings/components_strings_eu.xtb
@@ -5,6 +5,7 @@
 <translation id="1010200102790553230">Kargatu orria geroago</translation>
 <translation id="1015730422737071372">Eman xehetasun gehiago</translation>
 <translation id="1021110881106174305">Onartzen diren txartelak</translation>
+<translation id="1021753677514347426">Gailuan instalatu duzun edo dizuten ziurtagiri baten ondorioz gertatu da arazoa. Chromium-ek ez du jotzen fidagarritzat ziurtagiria, jakina baita sareak atzeman eta kontrolatzeko erabiltzen dela. Legezko kasu batzuetan kontrolatzen bada ere (hala nola eskoletan edo enpresaren sareetan), egoeraz jabe zaitezen nahi du Chromium-ek, nahiz eta saihestu ezin. Sarea atzitzen duen edozein arakatzaile edo aplikaziotan egiten da gainbegiratzea.</translation>
 <translation id="1032854598605920125">Biratu eskuinera</translation>
 <translation id="1036348656032585052">Desaktibatu</translation>
 <translation id="1038842779957582377">izen ezezaguna</translation>
@@ -67,6 +68,7 @@
 <translation id="1264126396475825575">Hutsegite-txostena egin da ordu honetan: <ph name="CRASH_TIME" /> (oraindik ez da kargatu, edo ez ikusi egin zaio)</translation>
 <translation id="1270502636509132238">Jasotzeko modua</translation>
 <translation id="1285320974508926690">Ez itzuli inoiz webgune hau</translation>
+<translation id="1285400217480592994">Aztertu Chrome-ren bidez deskargatzen edo kargatzen dituzun fitxategien edukia.</translation>
 <translation id="1292701964462482250">"Ordenagailuan dagoen software batek ez dio uzten Chrome-ri sarera segurtasunez konektatzen" (Windows ordenagailuak soilik)</translation>
 <translation id="1294154142200295408">Agindu-lerroaren aldaerak</translation>
 <translation id="129553762522093515">Itxitako azkenak</translation>
@@ -284,6 +286,7 @@
 <translation id="2270484714375784793">Telefono-zenbakia</translation>
 <translation id="2277103315734023688">Aurreratu</translation>
 <translation id="2283340219607151381">Gorde eta bete helbideak</translation>
+<translation id="2288422996159078444">Zer idazten duzun, zer orri ikusten dituzun edo, orokorrean, sarean egiten duzun edozer ari dira gainbegiratzen. Baliteke webguneetako edukia aldatzea zuk jakin gabe.</translation>
 <translation id="2289385804009217824">Moztu</translation>
 <translation id="2292556288342944218">Blokeatuta duzu Interneteko konexioa</translation>
 <translation id="2297722699537546652">B5 (gutun-azala)</translation>
@@ -432,6 +435,7 @@
 <translation id="2989742184762224133">Bi grapa goian</translation>
 <translation id="2991174974383378012">Webguneekin partekatzea</translation>
 <translation id="2991571918955627853">Une honetan ezin zara joan <ph name="SITE" /> webgunera, webguneak HSTS darabilelako. Sareko erroreak eta erasoak aldi baterakoak izan ohi dira; beraz, geroago funtzionatuko du orriak, segur aski.</translation>
+<translation id="2996674880327704673">Google-ren iradokizunak</translation>
 <translation id="3005723025932146533">Erakutsi gordetako kopia</translation>
 <translation id="3008447029300691911">Idatzi <ph name="CREDIT_CARD" /> txartelaren CVC kodea. Berretsi ondoren, webgune honekin partekatuko dira txartelaren xehetasunak.</translation>
 <translation id="3010559122411665027">"<ph name="ENTRY_INDEX" />" zerrenda-sarrera: <ph name="ERROR" /></translation>
@@ -444,6 +448,7 @@
 <translation id="3060227939791841287">C9 (gutun-azala)</translation>
 <translation id="3061707000357573562">Adabaki-zerbitzua</translation>
 <translation id="3064966200440839136">Ezkutuko modutik irtengo zara kanpoko aplikazio baten bidez ordaintzeko. Aurrera egin nahi duzu?</translation>
+<translation id="3086579638707268289">Webgunean egiten ari zarena gainbegiratzen ari dira</translation>
 <translation id="3095940652251934233">Statement</translation>
 <translation id="3096100844101284527">Gehitu jasotze-helbidea</translation>
 <translation id="3105172416063519923">Aktibo IDa:</translation>
@@ -493,6 +498,7 @@
 <translation id="3369192424181595722">Erlojuaren errorea</translation>
 <translation id="337363190475750230">Hornitu gabe</translation>
 <translation id="3377188786107721145">Errore bat gertatu da errorea analizatzean</translation>
+<translation id="3377736046129930310">Erabili pantailaren blokeoa txartelak bizkorrago berresteko</translation>
 <translation id="3380365263193509176">Errore ezezaguna</translation>
 <translation id="3380864720620200369">Bezeroaren IDa:</translation>
 <translation id="3387261909427947069">Ordainketa-metodoak</translation>
@@ -655,6 +661,7 @@
 <translation id="4194250254487269611">Ezin da gorde txartela une honetan</translation>
 <translation id="4196861286325780578">&amp;Berregin mugitzea</translation>
 <translation id="4203896806696719780"><ph name="BEGIN_LINK" />Suebakiaren eta birusen kontrako programaren konfigurazioak egiaztatu<ph name="END_LINK" />.</translation>
+<translation id="4214357935346142455">saioa hasteko pantailaren profila</translation>
 <translation id="4215751373031079683">7x9 (gutun-azala)</translation>
 <translation id="4220128509585149162">Hutsegiteak</translation>
 <translation id="422022731706691852">Baliteke <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webguneko erasotzaileak zu iruzurtzen saiatzea sarea arakatzea oztopatuko dizuten programak instala ditzazun. Besteak beste, hasierako orria alda lezakete edo ikusten dituzun webguneetan iragarki gehiago erakuts litzakete programok. <ph name="BEGIN_LEARN_MORE_LINK" />Lortu informazio gehiago<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -737,6 +744,7 @@
 <translation id="4515275063822566619">Chrome-tik eta zure Google-ko kontutik (<ph name="ACCOUNT_EMAIL" />) hartu dira txartelak eta helbideak. Kudeatu nahi badituzu, joan <ph name="BEGIN_LINK" />Ezarpenak<ph name="END_LINK" /> atalera.</translation>
 <translation id="4517607026994743406">Comm-10 (gutun-azala)</translation>
 <translation id="4522570452068850558">Xehetasunak</translation>
+<translation id="4524138615196389145">Aurrerantzean, berretsi txartelak bizkorrago WebAuthn erabilita</translation>
 <translation id="4524805452350978254">Kudeatu txartelak</translation>
 <translation id="455113658016510503">A9</translation>
 <translation id="4552089082226364758">Flash</translation>
@@ -848,6 +856,7 @@
 <translation id="5112422516732747637">A5</translation>
 <translation id="5115216390227830982">European-Edp</translation>
 <translation id="5115563688576182185">(64 bit)</translation>
+<translation id="5121469660360593280">Partekatu administratzailearekin Chrome-ren enpresetarako bertsioaren erabiltzaileak babesteko eginbideak aurkitutako segurtasun-gertaerei buruzko datuak. Datu horien artean baliteke hauek agertzea: bisitatzen dituzun orrien URLak, fitxategien izenak edo metadatuak, eta gailuan nahiz Chrome-n saioa hasteko erabiltzen duzun erabiltzaile-izena.</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Egiaztatu txartela</translation>
 <translation id="5135404736266831032">Kudeatu helbideak…</translation>
@@ -859,6 +868,7 @@
 <translation id="5159010409087891077">Ireki orria ezkutuko moduko leiho berri batean (⇧⌘N)</translation>
 <translation id="516920405563544094">Idatzi <ph name="CREDIT_CARD" /> txartelaren CVC kodea. Datuok berresten dituzunean, webgune honekin partekatuko dira Google-ko kontuarekin lotutako txartelaren xehetasunak.</translation>
 <translation id="5169827969064885044">Erakundearen konturako sarbidea gal zenezake, edo nortasuna lapur liezazukete. Pasahitza aldatzea gomendatzen dizu Chrome-k.</translation>
+<translation id="5170017743895942767">Chrome-ren enpresetarako bertsioaren erabiltzaileak babesteko eginbidea</translation>
 <translation id="5171045022955879922">Bilatu edo idatzi URLa</translation>
 <translation id="5171689220826475070">Fanfold-European</translation>
 <translation id="5172758083709347301">Gailua</translation>
@@ -979,6 +989,7 @@
 <translation id="5730040223043577876">Pasahitza beste webgune batzuetan ere erabili baduzu, hura berrezartzea gomendatzen du Chrome-k.</translation>
 <translation id="5737183892635480227">{NUM_CARDS,plural, =1{Gorde txartela Google-ko kontuan}other{Gorde txartelak Google-ko kontuan}}</translation>
 <translation id="5763042198335101085">Idatzi balio duen helbide elektroniko bat</translation>
+<translation id="5763703224595565476">Chrome-ren enpresetarako bertsioaren erabiltzaileak babesteko eginbidea gaitu dizu administratzaileak arakatzailean. Eginbideak zure datu batzuk atzi ditzake.</translation>
 <translation id="5765072501007116331">Entrega-metodoak eta -eskakizunak ikusteko, hautatu helbide bat</translation>
 <translation id="5778550464785688721">MIDI gailuen kontrol osoa</translation>
 <translation id="5781136890105823427">Proba gaituta dago</translation>
@@ -1058,6 +1069,7 @@
 <translation id="6094273045989040137">Egin oharpen bat</translation>
 <translation id="6104072995492677441">JIS B6</translation>
 <translation id="610911394827799129">Google-ko kontuko arakatze-historiaren bestelako datu batzuk gera litezke <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webgunean.</translation>
+<translation id="6120179357481664955">Gogoan al duzu UPI IDa?</translation>
 <translation id="6132597952260690497">Instalatutako luzapen eta pluginei buruzko informazioa</translation>
 <translation id="6146055958333702838">Egiaztatu kableak konektatuta daudela eta berrabiarazi erabiltzen ari zaren bideratzaile, modem eta sare-gailu oro.</translation>
 <translation id="614940544461990577">Konpontzeko, hauek egin ditzakezu:</translation>
@@ -1072,6 +1084,7 @@
 <translation id="6221345481584921695">Berriki Google-ren arakatze seguruak <ph name="BEGIN_LINK" />malwarea hauteman du<ph name="END_LINK" /> <ph name="SITE" /> webgunean. Seguruak izan ohi diren webguneak batzuetan malwarearekin kutsatuta egoten dira. Eduki gaiztoa <ph name="SUBRESOURCE_HOST" /> malware-banatzaile ezagunetik dator.</translation>
 <translation id="6234122620015464377">Moztu dokumentu bakoitzaren ondoren</translation>
 <translation id="6240447795304464094">Google Pay-ren logotipoa</translation>
+<translation id="6241121617266208201">Ezkutatu iradokizunak</translation>
 <translation id="6251924700383757765">Pribatutasun-gidalerroak</translation>
 <translation id="6254436959401408446">Ez dago fitxategia irekitzeko behar adina memoria</translation>
 <translation id="625755898061068298">Webgune honetako segurtasun-abisuak desgaitzea aukeratu duzu.</translation>
@@ -1118,6 +1131,7 @@
 <translation id="6409754798200046165">Webgune engainagarri batean idatzi duzu pasahitza. Pasahitza berehala aldatzea gomendatzen du Chrome-k.</translation>
 <translation id="6410264514553301377">Idatzi <ph name="CREDIT_CARD" /> txartelaren iraungitze-data eta CVC kodea</translation>
 <translation id="6415778972515849510">Google-ko kontua babesten eta pasahitza aldatzen lagun diezazuke Chromium-ek.</translation>
+<translation id="6423385022588644828">Aurrerantzean, berretsi txartelak bizkorrago Touch ID erabilita</translation>
 <translation id="6427730057873428458">Leiho-erako tolestura</translation>
 <translation id="6433490469411711332">Editatu harremanetarako informazioa</translation>
 <translation id="6433595998831338502">Konexioa baztertu du <ph name="HOST_NAME" /> webguneak.</translation>
@@ -1188,12 +1202,14 @@
 <translation id="6786747875388722282">Luzapenak</translation>
 <translation id="6790428901817661496">Erreproduzitu</translation>
 <translation id="679355240208270552">Ez ikusi egin zaio bilaketa lehenetsia ez dagoelako gaituta gidalerroen arabera.</translation>
+<translation id="6794951432696553238">Aurrerantzean, berretsi txartelak bizkorrago Windows Hello erabilita</translation>
 <translation id="681021252041861472">Derrigorrezko eremua</translation>
 <translation id="6810899417690483278">Pertsonalizazio IDa</translation>
 <translation id="6825578344716086703"><ph name="DOMAIN" /> domeinura konektatzen saiatu zara, baina zerbitzariak aurkeztu duen sinadura-algoritmoa ez da segurua (adibidez, SHA-1). Horrek esan nahi du zerbitzariak aurkeztutako segurtasun-kredentzialak faltsuak direla eta balitekeela zerbitzaria ez izatea zuk espero zenuena, hau da, posible dela erasotzaile batekin komunikatzen ari izatea.</translation>
 <translation id="6826370046007623921">Datu-galeren prebentzioa</translation>
 <translation id="6831043979455480757">Itzuli</translation>
 <translation id="6839929833149231406">Eskualdea</translation>
+<translation id="6846340164947227603">Erabili txartel birtualaren zenbakia…</translation>
 <translation id="6852204201400771460">Berriro kargatu nahi duzu aplikazioa?</translation>
 <translation id="6865412394715372076">Txartela ezin da egiaztatu une honetan</translation>
 <translation id="6868206169573555318">Eguneratzeko, abiarazi berriro</translation>
@@ -1222,6 +1238,7 @@
 <translation id="6989763994942163495">Erakutsi ezarpen aurreratuak…</translation>
 <translation id="6993898126790112050">6x9 (gutun-azala)</translation>
 <translation id="6996312675313362352">Itzuli beti <ph name="ORIGINAL_LANGUAGE" /></translation>
+<translation id="7004583254764674281">Erabili Windows Hello txartelak bizkorrago berresteko</translation>
 <translation id="7012363358306927923">China UnionPay</translation>
 <translation id="7016992613359344582">Behin edo gehiagotan kobratzen saia liteke, eta baliteke zordunketa horiek begien bistakoak ez izatea.</translation>
 <translation id="7029809446516969842">Pasahitzak</translation>
@@ -1232,6 +1249,7 @@
 <translation id="7064851114919012435">Harremanetarako informazioa</translation>
 <translation id="7075452647191940183">Eskaera handiegia da</translation>
 <translation id="7079718277001814089">Webguneak malwarea dauka</translation>
+<translation id="7081308185095828845">Eginbidea ez dago erabilgarri zure gailuan</translation>
 <translation id="7087282848513945231">Konderria</translation>
 <translation id="7090678807593890770">Bilatu <ph name="LINK" /> Google-n</translation>
 <translation id="7108338896283013870">Ezkutatu</translation>
@@ -1285,9 +1303,11 @@
 <translation id="733923710415886693">Zerbitzariaren ziurtagiria ez da ezagutarazi ziurtagirien gardentasun-gidalerroa erabilita.</translation>
 <translation id="734600844861828519">11x15</translation>
 <translation id="7346048084945669753">Kidetuta dago:</translation>
+<translation id="73479065977517481"><ph name="ENROLLMENT_DOMAIN" /> domeinuak Chrome-ren enpresetarako bertsioaren erabiltzaileak babesteko eginbidea gaitu dizu arakatzailean. Eginbideak zure datu batzuk atzi ditzake.</translation>
 <translation id="7349430561505560861">A4-Extra</translation>
 <translation id="7353601530677266744">Agindu-lerroa</translation>
 <translation id="7372973238305370288">bilaketa-emaitza</translation>
+<translation id="7374733840632556089">Gailuan instalatu duzun edo dizuten ziurtagiri baten ondorioz gertatu da arazoa. Chrome-k ez du jotzen fidagarritzat ziurtagiria, jakina baita sareak atzeman eta kontrolatzeko erabiltzen dela. Legezko kasu batzuetan kontrolatzen bada ere (hala nola eskoletan edo enpresaren sareetan), egoeraz jabe zaitezen nahi du Chrome-k, nahiz eta saihestu ezin. Sarea atzitzen duen edozein arakatzaile edo aplikaziotan egiten da gainbegiratzea.</translation>
 <translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
 <translation id="7378594059915113390">Multimedia-edukia kontrolatzeko aukerak</translation>
 <translation id="7378627244592794276">Ez</translation>
@@ -1316,6 +1336,7 @@
 <translation id="7451311239929941790"><ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /> arazoari buruz.</translation>
 <translation id="7455133967321480974">Erabili ezarpen lehenetsi orokorra (blokeatzea)</translation>
 <translation id="7460618730930299168">Bideoaren bistaratze-xehetasunak ez datoz bat hautatu dituzunekin. Aurrera egin nahi duzu?</translation>
+<translation id="7464821087936825778">Bilaketa modutik irteten</translation>
 <translation id="7473891865547856676">Ez, eskerrik asko</translation>
 <translation id="7481312909269577407">Aurrera</translation>
 <translation id="7485870689360869515">Ez da daturik aurkitu</translation>
@@ -1537,6 +1558,7 @@
 <translation id="8559762987265718583">Ezin da ezarri <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> domeinurako konexio pribatua gailuaren data eta ordua (<ph name="DATE_AND_TIME" />) okerrak direlako.</translation>
 <translation id="8564985650692024650"><ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> pasahitza beste webgune batzuetan ere erabili baduzu, hura berrezartzea gomendatzen du Chromium-ek.</translation>
 <translation id="8571890674111243710">Orria <ph name="LANGUAGE" /> hizkuntzara itzultzen…</translation>
+<translation id="8574899947864779331">Erabili Touch ID txartelak bizkorrago berresteko</translation>
 <translation id="858637041960032120">Gehitu telefono-zenbakia</translation>
 <translation id="860043288473659153">Txartelaren titularraren izena</translation>
 <translation id="8616822740383114808">"<ph name="SETTINGS_PAGE" />" orriko "<ph name="ENFORCING_SETTING" />" ezarpenak betearazten du ezarpena</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb
index d4103d0..974a42c9 100644
--- a/components/strings/components_strings_hi.xtb
+++ b/components/strings/components_strings_hi.xtb
@@ -458,7 +458,7 @@
 <translation id="3145945101586104090">उत्तर डीकोड करने में विफल</translation>
 <translation id="3150653042067488994">अस्थायी सर्वर गड़बड़ी</translation>
 <translation id="3154506275960390542">इस पेज में ऐसा फ़ॉर्म शामिल है, जो सुरक्षित रूप से सबमिट नहीं किया जा सकता है. ट्रांज़िट में होने के दौरान आपके भेजे जाने वाले डेटा को दूसरे लोग देख सकते हैं या सर्वर को मिलने वाली सामग्री में बदलाव करने के लिए कोई आक्रमणकर्ता उसे संशोधित कर सकता है.</translation>
-<translation id="3157931365184549694">पुनर्स्थापित करें</translation>
+<translation id="3157931365184549694">वापस लाएं</translation>
 <translation id="3162559335345991374">आप जिस वाई-फ़ाई का उपयोग कर रहे हैं, आपको उसके लॉगिन पेज पर जाने की ज़रूरत पड़ सकती है.</translation>
 <translation id="3167968892399408617">आप जो पेज गुप्त टैब में देखते हैं, वे आपके गुप्त टैब बंद कर देने के बाद आपके ब्राउज़र के इतिहास, कुकी संग्रह, या खोज इतिहास में नहीं रहेंगे. आपके डाउनलोड किए गए सभी फ़ाइल या बनाए गए बुकमार्क रहेंगे.</translation>
 <translation id="3169472444629675720">तलाश करें</translation>
diff --git a/components/strings/components_strings_km.xtb b/components/strings/components_strings_km.xtb
index 08bd33e..e12c00b 100644
--- a/components/strings/components_strings_km.xtb
+++ b/components/strings/components_strings_km.xtb
@@ -5,6 +5,7 @@
 <translation id="1010200102790553230">ផ្ទុកទំព័រនៅ​ពេលក្រោយ</translation>
 <translation id="1015730422737071372">ផ្តល់ព័ត៌មានលម្អិតបន្ថែម</translation>
 <translation id="1021110881106174305">បណ្ណដែលទទួលយក</translation>
+<translation id="1021753677514347426">បញ្ហា​នេះ​កើតឡើង​ដោយសារ​វិញ្ញាបនបត្រ​ដែល​អ្នក ឬ​អ្នកផ្សេង​ទៀត​បានដំឡើង​នៅលើ​ឧបករណ៍​របស់អ្នក​។ វិញ្ញាបនបត្រ​នេះ​ត្រូវបាន​ប្រើ​ដើម្បី​ឃ្លាំមើល និង​បង្អាក់​បណ្ដាញ ហើយ Chromium មិន​ទុកចិត្ត​លើ​វិញ្ញាបនបត្រ​នេះទេ​។ ទោះបីជា​មាន​ករណី​ស្របច្បាប់​មួយចំនួន ដែលអនុញ្ញាតឱ្យមានការ​ឃ្លាំមើល​ ដូចជា​នៅលើ​បណ្ដាញ​របស់​ក្រុមហ៊ុន ឬ​សាលារៀន​ក៏ដោយ ក៏ Chromium ចង់​បញ្ជាក់ឱ្យអ្នក​ដឹង​ច្បាស់ថា អ្នកអាចកំពុងត្រូវបានឃ្លាំមើល​ ទោះបីជា​អ្នក​មិនអាច​បញ្ឈប់​សកម្មភាពនេះ​បានក៏ដោយ​។ ការឃ្លាំមើល​អាច​កើតឡើង​នៅក្នុង​កម្មវិធី​រុករក​តាមអ៊ីនធឺណិត ឬ​កម្មវិធី​ទាំងឡាយ​ដែល​ចូលប្រើ​បណ្ដាញ​។</translation>
 <translation id="1032854598605920125">បង្វិលតាមទ្រនិចនាឡិកា</translation>
 <translation id="1036348656032585052">បិទ</translation>
 <translation id="1038842779957582377">ឈ្មោះមិនស្គាល់</translation>
@@ -68,6 +69,7 @@
 <translation id="1264126396475825575">របាយការណ៍គាំងបានថតនៅម៉ោង <ph name="CRASH_TIME" /> (មិនទាន់បានអាប់ឡូត ឬមិនអើពើ)</translation>
 <translation id="1270502636509132238">មធ្យោបាយ​ទៅយក</translation>
 <translation id="1285320974508926690">មិនបកប្រែគេហទំព័រនេះទៀតឡើយ</translation>
+<translation id="1285400217480592994">ស្កេន​ខ្លឹមសារ​នៃ​ឯកសារ​ដែល​អ្នក​ទាញយក ឬ​បង្ហោះ​នៅក្នុង Chrome​។</translation>
 <translation id="1292701964462482250">"កម្មវិធី​នៅលើ​កុំព្យូទ័រ​របស់អ្នក​កំពុង​បញ្ឈប់ Chrome មិន​ឱ្យ​ភ្ជាប់​ទៅ​អ៊ីនធឺណិត​​ដោយសុវត្ថិភាព" (កុំព្យូទ័រ​ Windows តែ​ប៉ុណ្ណោះ)</translation>
 <translation id="1294154142200295408">អថេរ​នៃ​អត្ថបទ​បញ្ជា</translation>
 <translation id="129553762522093515">បានបិទកន្លងទៅថ្មីៗ</translation>
@@ -286,6 +288,7 @@
 <translation id="2270484714375784793">លេខទូរស័ព្ទ</translation>
 <translation id="2277103315734023688">សា​ទៅមុខ</translation>
 <translation id="2283340219607151381">រក្សាទុក និង​បំពេញ​អាសយដ្ឋាន</translation>
+<translation id="2288422996159078444">អ្វី​ដែលអ្នក​វាយបញ្ចូល ទំព័រ​ទាំងឡាយ​ដែលអ្នក​មើល ឬ​សកម្មភាព​ផ្សេងទៀត​នៅលើ​បណ្ដាញ​កំពុង​ត្រូវបាន​ឃ្លាំមើល​។ ខ្លឹមសារ​នៅលើ​គេហទំព័រ​ផ្សេងៗ​អាចនឹង​ត្រូវបាន​ប្ដូរ​ដោយ​មិនឱ្យ​អ្នក​ដឹង​។</translation>
 <translation id="2289385804009217824">តម្រឹម</translation>
 <translation id="2292556288342944218">ការចូលប្រើអ៊ីនធឺណិតរបស់អ្នកត្រូវបានរារាំង</translation>
 <translation id="2297722699537546652">B5 (ស្រោម​សំបុត្រ)</translation>
@@ -439,6 +442,7 @@
 <translation id="2989742184762224133">កិប​ពីរគ្រាប់​ខាងលើ</translation>
 <translation id="2991174974383378012">ការចែករំលែកជាមួយគេហទំព័រ</translation>
 <translation id="2991571918955627853">អ្នក​មិន​អាច​ចូល​ទៅកាន់ <ph name="SITE" /> ឥឡូវនេះ​បានទេ ដោយសារតែគេហទំព័រ​នេះ​ប្រើ HSTS ។ ជាទូទៅបញ្ហា​បណ្តញ ឬ​ការវាយប្រហារ​​កើត​ឡើង​ជាបណ្តោះអាសន្ន ដូច្នេះ​ទំព័រ​នេះ​នឹងដំណើរការល្អឡើងវិញនៅពេលក្រោយ។</translation>
+<translation id="2996674880327704673">ការណែនាំ​ពី Google</translation>
 <translation id="3005723025932146533">បង្ហាញច្បាប់ចម្លងដែលបានរក្សាទុក</translation>
 <translation id="3008447029300691911">បញ្ចូល CVC សម្រាប់ <ph name="CREDIT_CARD" /> ។ បន្ទាប់ពីអ្នកបញ្ជាក់ហើយ ព័ត៌មានលម្អិតពីកាត់របស់អ្នកនឹងត្រូវបានចែករំលែកជាមួយគេហទំព័រនេះ។</translation>
 <translation id="3010559122411665027">ធាតុបញ្ជី "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
@@ -451,6 +455,7 @@
 <translation id="3060227939791841287">C9 (ស្រោម​សំបុត្រ)</translation>
 <translation id="3061707000357573562">Patch Service</translation>
 <translation id="3064966200440839136">កំពុង​ចាកចេញ​ពី​មុខងារ​អនាមិក ដើម្បី​បង់ប្រាក់​តាមរយៈ​កម្មវិធី​ខាងក្រៅ។ បន្ត?</translation>
+<translation id="3086579638707268289">សកម្មភាព​របស់អ្នក​នៅលើ​បណ្ដាញ​កំពុង​ត្រូវបាន​ឃ្លាំមើល</translation>
 <translation id="3095940652251934233">Statement</translation>
 <translation id="3096100844101284527">បញ្ចូល​អាសយដ្ឋាន​ទទួល</translation>
 <translation id="3105172416063519923">ID ទ្រព្យសកម្ម៖</translation>
@@ -503,6 +508,7 @@
 <translation id="3369192424181595722">កំហុសម៉ោង</translation>
 <translation id="337363190475750230">បានផ្តាច់ការផ្តល់ជូន</translation>
 <translation id="3377188786107721145">កំហុសឆ្គងការវិភាគគោលការណ៍</translation>
+<translation id="3377736046129930310">ប្រើ​ការចាក់​សោ​អេក្រង់ ដើម្បី​បញ្ជាក់​បណ្ណ​ឥណទាន​រហ័ស​ជាងមុន</translation>
 <translation id="3380365263193509176">កំហុសឆ្គងមិនស្គាល់</translation>
 <translation id="3380864720620200369">លេខសម្គាល់អតិថិជន៖</translation>
 <translation id="3387261909427947069">វិធី​បង់ប្រាក់</translation>
@@ -668,6 +674,7 @@
 <translation id="4194250254487269611">មិនអាចរក្សាទុក​បណ្ណរបស់អ្នកបានទេ​នៅពេលនេះ</translation>
 <translation id="4196861286325780578">ធ្វើការផ្លាស់ទីឡើងវិញ</translation>
 <translation id="4203896806696719780"><ph name="BEGIN_LINK" />ពិនិត្យការកំណត់រចនាសម្ព័ន្ធ firewall និងកម្មវិធីកម្ចាត់មេរោគ<ph name="END_LINK" /></translation>
+<translation id="4214357935346142455">កម្រង​ព័ត៌មាននៃ​អេក្រង់ចូលគណនី</translation>
 <translation id="4215751373031079683">7x9 (ស្រោម​សំបុត្រ)</translation>
 <translation id="4220128509585149162">គាំង</translation>
 <translation id="422022731706691852">អ្នកវាយប្រហារទៅលើ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> អាច​នឹង​ព្យាយាម​បញ្ឆោតឲ្យអ្នកដំឡើងកម្មវិធីដែល​បង្កគ្រោះថ្នាក់ដល់​កិច្ចការរុករករបស់អ្នក (ឧទាហរណ៍៖ ផ្លាស់ប្តូរទំព័រដើមរបស់អ្នក ឬបង្ហាញពាណិជ្ជកម្មបន្ថែមនៅលើទំព័រដែលអ្នកបានចូល)។ <ph name="BEGIN_LEARN_MORE_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -751,6 +758,7 @@
 <translation id="4515275063822566619">បណ្ណ និងអាសយដ្ឋានគឺបានមកពី Chrome និងគណនី Google របស់អ្នក (<ph name="ACCOUNT_EMAIL" />)។ អ្នកអាចគ្រប់គ្រងពួកវាបាននៅក្នុង <ph name="BEGIN_LINK" />ការកំណត់<ph name="END_LINK" />។</translation>
 <translation id="4517607026994743406">Comm-10 (ស្រោម​សំបុត្រ)</translation>
 <translation id="4522570452068850558">ព័ត៌មានលំអិត</translation>
+<translation id="4524138615196389145">បញ្ជាក់​បណ្ណឥណទាន​របស់អ្នក​រហ័ស​ជាងមុន​ដោយប្រើ WebAuthn ចាប់ពី​ពេលនេះ​តទៅ</translation>
 <translation id="4524805452350978254">គ្រប់គ្រង​កាត</translation>
 <translation id="455113658016510503">A9</translation>
 <translation id="4552089082226364758">Flash</translation>
@@ -862,6 +870,7 @@
 <translation id="5112422516732747637">A5</translation>
 <translation id="5115216390227830982">European-Edp</translation>
 <translation id="5115563688576182185">(64-ប៊ីត)</translation>
+<translation id="5121469660360593280">ចែករំលែក​ទិន្នន័យ​អំពី​ព្រឹត្តិការណ៍​ទាក់ទងនឹង​សុវត្ថិភាព​ដែល Chrome Enterprise User Protect បាន​រាយការណ៍ជាមួយ​អ្នកគ្រប់គ្រង​របស់អ្នក​។ នេះអាចរួមបញ្ចូលទំព័រ URL ដែលអ្នកចូលមើល ឈ្មោះឯកសារ ឬទិន្នន័យ​មេតា និងឈ្មោះអ្នកប្រើប្រាស់ ដែលអ្នកប្រើ​ ដើម្បីចូលឧបករណ៍របស់អ្នក និង Chrome។</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">ផ្ទៀងផ្ទាត់កាតរបស់អ្នក</translation>
 <translation id="5135404736266831032">គ្រប់គ្រង​អាសយដ្ឋាន...</translation>
@@ -873,6 +882,7 @@
 <translation id="5159010409087891077">បើក​ទំព័រ​នៅក្នុង​ផ្ទាំងឯកជន​ថ្មី (⇧⌘N)</translation>
 <translation id="516920405563544094">បញ្ចូល CVC សម្រាប់ <ph name="CREDIT_CARD" /> ។ បន្ទាប់​ពីអ្នក​បញ្ជាក់​ហើយ ព័ត៌មាន​លម្អិត​អំពី​កាតដែលបាន​មកពីគណនី Google របស់អ្នក​នឹងត្រូវ​បាន​ចែករំលែក​ជាមួយ​គេហទំព័រ​នេះ។</translation>
 <translation id="5169827969064885044">អ្នកអាច​បាត់បង់​សិទ្ធិចូល​ប្រើ​គណនី​​របស់ស្ថាប័នអ្នក ឬ​ជួបប្រទះ​នឹង​ការលួចយក​អត្តសញ្ញាណ។ Chrome សូមណែនាំ​ឱ្យប្ដូរ​ពាក្យសម្ងាត់​របស់អ្នក​ឥឡូវនេះ។</translation>
+<translation id="5170017743895942767">Chrome Enterprise User Protect</translation>
 <translation id="5171045022955879922">ស្វែងរក ឬវាយបញ្ចូល URL</translation>
 <translation id="5171689220826475070">Fanfold-European</translation>
 <translation id="5172758083709347301">ម៉ាស៊ីន</translation>
@@ -993,6 +1003,7 @@
 <translation id="5730040223043577876">Chrome ណែនាំឱ្យ​កំណត់​ពាក្យសម្ងាត់​របស់អ្នក​ឡើងវិញ ប្រសិនបើ​អ្នកបាន​ប្រើ​វា​ម្តងទៀត​នៅលើ​ទំព័រផ្សេង​។</translation>
 <translation id="5737183892635480227">{NUM_CARDS,plural, =1{រក្សាទុកបណ្ណនៅក្នុងគណនី Google របស់អ្នក}other{រក្សាទុកបណ្ណ​នៅក្នុងគណនី Google របស់អ្នក}}</translation>
 <translation id="5763042198335101085">បញ្ចូលអាសយដ្ឋានអ៊ីមែលដែលត្រឹមត្រូវ</translation>
+<translation id="5763703224595565476">អ្នកគ្រប់គ្រង​របស់អ្នក​បានបើក Chrome Enterprise User Protect នៅលើ​កម្មវិធី​រុករក​តាម​អ៊ីនធឺណិត​របស់អ្នក​។ Chrome Enterprise User Protect មាន​សិទ្ធិ​ចូលប្រើទិន្នន័យ​មួយចំនួន​របស់អ្នក​។</translation>
 <translation id="5765072501007116331">ដើម្បីមើលមធ្យោបាយ និងលក្ខខណ្ឌតម្រូវនៃការដឹកជញ្ជូនផ្ទាល់ សូមជ្រើសរើសអាសយដ្ឋាន</translation>
 <translation id="5778550464785688721">ការគ្រប់គ្រងពេញលេញលើឧបករណ៍ MIDI</translation>
 <translation id="5781136890105823427">បានបើក​ការពិសោធ</translation>
@@ -1072,6 +1083,7 @@
 <translation id="6094273045989040137">ចំណារ</translation>
 <translation id="6104072995492677441">JIS B6</translation>
 <translation id="610911394827799129">គណនី Google របស់អ្នកអាចមានទម្រង់ប្រវត្តិរុករកផ្សេងទៀតនៅក្នុង <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ។</translation>
+<translation id="6120179357481664955">ចងចាំ​លេខសម្គាល់ UPI របស់អ្នក​ដែរទេ​?</translation>
 <translation id="6132597952260690497">ព័ត៌មាន​អំពីកម្មវិធីជំនួយ និងកម្មវិធីបន្ថែម​ដែលបានដំឡើង</translation>
 <translation id="6146055958333702838">ពិនិត្យខ្សែបណ្តាញ បិទបើករ៉ោតទ័រ ម៉ូឌែម ឬឧបករណ៍បណ្តាញផ្សេងទៀត
     ដែលអ្នកកំពុងប្រើប្រាស់។</translation>
@@ -1087,6 +1099,7 @@
 <translation id="6221345481584921695">ការរុករកសុវត្ថិភាព Google <ph name="BEGIN_LINK" />បានរកឃើញមេរោគ<ph name="END_LINK" /> នៅលើ <ph name="SITE" />កន្លងទៅថ្មីៗនេះ។ គេហទំព័រដែលជាធម្មតាមានសុវត្ថិភាពអាចឆ្លងមេរោគនៅពេលខ្លះ។ មាតិកាព្យាបាទចេញមកពី <ph name="SUBRESOURCE_HOST" /> ជាអ្នកចែកចាយមេរោគដែលត្រូវបានស្គាល់។</translation>
 <translation id="6234122620015464377">តម្រឹម​បន្ទាប់ពី​ឯកសារ​នីមួយៗ</translation>
 <translation id="6240447795304464094">និមិត្តសញ្ញា Google Pay</translation>
+<translation id="6241121617266208201">លាក់​ការ​ណែនាំ</translation>
 <translation id="6251924700383757765">គោលការណ៍ឯកជនភាព</translation>
 <translation id="6254436959401408446">មិនមានទំហំអង្គចងចាំគ្រប់គ្រាន់ដើម្បីបើកទំព័រនេះទេ</translation>
 <translation id="625755898061068298">អ្នកមិនបានជ្រើសរើសបិទដំណើរការការព្រមានផ្នែកសុវត្ថិភាពសម្រាប់គេហទំព័រនេះទេ។</translation>
@@ -1133,6 +1146,7 @@
 <translation id="6409754798200046165">អ្នកទើបតែ​បានបញ្ចូល​ពាក្យសម្ងាត់​របស់អ្នក​ទៅក្នុង​គេហទំព័របញ្ឆោត។ Chrome សូមណែនាំ​ឱ្យប្ដូរ​ពាក្យសម្ងាត់​របស់អ្នក​ឥឡូវនេះ។</translation>
 <translation id="6410264514553301377">បញ្ចូល​កាលបរិច្ឆេទ​ផុត​កំណត់​ និង​ CVC សម្រាប់ <ph name="CREDIT_CARD" /></translation>
 <translation id="6415778972515849510">Chromium អាច​ជួយ​អ្នក​ក្នុងការការពារ​គណនី Google និង​ផ្លាស់ប្ដូរ​ពាក្យសម្ងាត់​របស់អ្នក​។</translation>
+<translation id="6423385022588644828">បញ្ជាក់​បណ្ណឥណទាន​របស់អ្នក​រហ័ស​ជាងមុន​ដោយប្រើ Touch ID ចាប់ពី​ពេលនេះ​តទៅ</translation>
 <translation id="6427730057873428458">បត់ជា​ផ្ទាំងៗមានសណ្ឋានជាទ្វារ</translation>
 <translation id="6433490469411711332">កែសម្រួលព័ត៌មានទំនាក់ទំនង</translation>
 <translation id="6433595998831338502"><ph name="HOST_NAME" /> បានបដិសេធក្នុងការតភ្ជាប់</translation>
@@ -1203,12 +1217,14 @@
 <translation id="6786747875388722282">កម្មវិធីបន្ថែម</translation>
 <translation id="6790428901817661496">លេង</translation>
 <translation id="679355240208270552">មិនត្រូវ​បាន​អើពើ​ព្រោះ​ការស្វែង​រក​លំនាំដើម​មិន​បានបើក​ដោយ​គោលការណ៍​ទេ។</translation>
+<translation id="6794951432696553238">បញ្ជាក់​បណ្ណ​ឥណទាន​របស់អ្នក​រហ័ស​ជាងមុន​ដោយប្រើ Windows Hello ចាប់ពី​ពេលនេះ​តទៅ</translation>
 <translation id="681021252041861472">កន្លែងត្រូវតែបំពេញ</translation>
 <translation id="6810899417690483278">លេខសម្គាល់​ការកែ​សម្រួល</translation>
 <translation id="6825578344716086703">អ្នកបានព្យាយាមទៅកាន់ <ph name="DOMAIN" /> ប៉ុន្តែម៉ាស៊ីនមេបានបង្ហាញវិញ្ញាបនបត្រដែលបានស៊ីញ៉េដោយប្រើនីតិវិធីដោះស្រាយការស៊ីញ៉េខ្សោយ (ដូចជា SHA-1)។ វាមានន័យថាព័ត៌មានផ្ទៀងផ្ទាត់សុវត្ថិភាពដែលម៉ាស៊ីនមេបានបង្ហាញអាចត្រូវបានក្លែងបន្លំ ហើយម៉ាស៊ីនមេនោះអាចជាម៉ាស៊ីនមេដែលអ្នកមិនបានរំពឹងទុកទេ (អ្នកប្រហែលជាកំពុងទាក់ទងជាមួយអ្នកវាយប្រហារ)។</translation>
 <translation id="6826370046007623921">ការការពារ​ការបាត់បង់​ទិន្នន័យ</translation>
 <translation id="6831043979455480757">បកប្រែ</translation>
 <translation id="6839929833149231406">តំបន់</translation>
+<translation id="6846340164947227603">ប្រើ​លេខ​បណ្ណ​ឥណទាន​និម្មិត...</translation>
 <translation id="6852204201400771460">ផ្ទុក​កម្មវិធី​ឡើងវិញ?</translation>
 <translation id="6865412394715372076">មិនអាច​ផ្ទៀងផ្ទាត់កាតនេះ​​​ឥឡូវនេះ​បានទេ</translation>
 <translation id="6868206169573555318">ចាប់ផ្ដើម​ឡើងវិញ ដើម្បី​ដំឡើងជំនាន់</translation>
@@ -1237,6 +1253,7 @@
 <translation id="6989763994942163495">បង្ហាញការកំណត់កម្រិតខ្ពស់...</translation>
 <translation id="6993898126790112050">6x9 (ស្រោម​សំបុត្រ)</translation>
 <translation id="6996312675313362352">បកប្រែ <ph name="ORIGINAL_LANGUAGE" /> ជានិច្ច</translation>
+<translation id="7004583254764674281">ប្រើ Windows Hello ដើម្បី​បញ្ជាក់​បណ្ណ​ឥណទាន​រហ័ស​ជាងមុន</translation>
 <translation id="7012363358306927923">China UnionPay</translation>
 <translation id="7016992613359344582">ការគិតប្រាក់ទាំងនេះអាចធ្វើឡើងម្ដង ឬច្រើន​ដង ហើយអាចនឹងមិនមាន​ការបញ្ជាក់ច្បាស់លាស់នោះទេ។</translation>
 <translation id="7029809446516969842">ពាក្យសម្ងាត់</translation>
@@ -1247,6 +1264,7 @@
 <translation id="7064851114919012435">ព័ត៌មានទំនាក់ទំនង</translation>
 <translation id="7075452647191940183">សំណើមាន​ទំហំធំពេក</translation>
 <translation id="7079718277001814089">ទំព័រនេះមានផ្ទុកមេរោគ</translation>
+<translation id="7081308185095828845">មិនអាច​ប្រើ​មុខងារ​នេះ​នៅលើ​ឧបករណ៍​របស់អ្នក​បានទេ</translation>
 <translation id="7087282848513945231">ប្រទេស</translation>
 <translation id="7090678807593890770">ស្វែងរក <ph name="LINK" /> នៅលើ Google</translation>
 <translation id="7108338896283013870">លាក់</translation>
@@ -1300,9 +1318,11 @@
 <translation id="733923710415886693">វិញ្ញាបនបត្រម៉ាស៊ីនមេមិនត្រូវបានបង្ហាញឲ្យដឹងតាមរយៈគោលការណ៍តម្លាភាពវិញ្ញាបនបត្រ។</translation>
 <translation id="734600844861828519">11x15</translation>
 <translation id="7346048084945669753">បានភ្ជាប់៖</translation>
+<translation id="73479065977517481"><ph name="ENROLLMENT_DOMAIN" /> បាន​បើក Chrome Enterprise User Protect នៅលើ​កម្មវិធី​រុករក​តាម​អ៊ីនធឺណិត​របស់អ្នក​។ Chrome Enterprise User Protect មាន​សិទ្ធិ​ចូលប្រើទិន្នន័យ​មួយចំនួន​របស់អ្នក​។</translation>
 <translation id="7349430561505560861">A4-Extra</translation>
 <translation id="7353601530677266744">អត្ថបទបញ្ជា</translation>
 <translation id="7372973238305370288">លទ្ធផលស្វែងរក</translation>
+<translation id="7374733840632556089">បញ្ហា​នេះ​កើតឡើង​ដោយសារ​វិញ្ញាបនបត្រ​ដែល​អ្នក ឬ​អ្នកផ្សេង​ទៀត​បានដំឡើង​នៅលើ​ឧបករណ៍​របស់អ្នក​។ វិញ្ញាបនបត្រ​នេះ​ត្រូវបាន​ប្រើ​ ដើម្បី​ឃ្លាំមើល និង​បង្អាក់​បណ្ដាញ ហើយ Chrome មិន​ទុកចិត្ត​លើ​វិញ្ញាបនបត្រ​នេះទេ​។ ទោះបីជា​មាន​ករណី​ស្របច្បាប់​មួយចំនួន ដែលអនុញ្ញាតឱ្យមានការ​ឃ្លាំមើល​ ដូចជា​នៅលើ​បណ្ដាញ​របស់​ក្រុមហ៊ុន ឬ​សាលារៀន​ក៏ដោយ ក៏ Chrome ចង់​បញ្ជាក់ឱ្យអ្នក​ដឹង​ច្បាស់ថា អ្នកអាចកំពុងត្រូវបានឃ្លាំមើល​ ទោះបីជា​អ្នក​មិនអាច​បញ្ឈប់​សកម្មភាពនេះ​បានក៏ដោយ​។ ការឃ្លាំមើល​អាច​កើតឡើង​នៅក្នុង​កម្មវិធី​រុករក​តាមអ៊ីនធឺណិត ឬ​កម្មវិធី​ទាំងឡាយ​ដែល​ចូលប្រើ​បណ្ដាញ​។</translation>
 <translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
 <translation id="7378594059915113390">ការគ្រប់គ្រង​មេឌៀ</translation>
 <translation id="7378627244592794276">ទេ</translation>
@@ -1331,6 +1351,7 @@
 <translation id="7451311239929941790"><ph name="BEGIN_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LINK" />អំពីបញ្ហានេះ</translation>
 <translation id="7455133967321480974">ប្រើលំនាំដើមជាសកល (រារាំង)</translation>
 <translation id="7460618730930299168">ការបញ្ចាំងមានភាពខុសគ្នាពី​អ្វីដែលអ្នកបាន​ជ្រើសរើស។ បន្ត?</translation>
+<translation id="7464821087936825778">កំពុង​ចាកចេញ​ពី​មុខងារ​ស្វែងរក</translation>
 <translation id="7473891865547856676">ទេ អរគុណ</translation>
 <translation id="7481312909269577407">ទៅមុខ</translation>
 <translation id="7485870689360869515">គ្មានទិន្នន័យត្រូវបានរកឃើញទេ។</translation>
@@ -1553,6 +1574,7 @@
 <translation id="8559762987265718583">ការភ្ជាប់ឯកជនទៅ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> មិនអាចធ្វើឡើងទេ ពីព្រោះកាលបរិច្ឆេទ និងម៉ោងឧបករណ៍របស់អ្នក (<ph name="DATE_AND_TIME" />)មិនត្រឹមត្រូវ។</translation>
 <translation id="8564985650692024650">Chromium ណែនាំឱ្យ​កំណត់​ពាក្យសម្ងាត់ <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> របស់អ្នក​ឡើងវិញ ប្រសិនបើ​អ្នកបាន​ប្រើ​វាម្តងទៀត​នៅលើ​ទំព័រផ្សេង។</translation>
 <translation id="8571890674111243710">កំពុងបកប្រែទំព័រទៅ <ph name="LANGUAGE" />...</translation>
+<translation id="8574899947864779331">ប្រើ Touch ID ដើម្បី​បញ្ជាក់​បណ្ណឥណទាន​រហ័ស​ជាងមុន</translation>
 <translation id="858637041960032120">បន្ថែមលេខទូរស័ព្ទ</translation>
 <translation id="860043288473659153">ឈ្មោះ​ម្ចាស់​កាត</translation>
 <translation id="8616822740383114808">ការកំណត់​នេះ​ត្រូវបាន​អនុវត្ត​ដោយ "<ph name="ENFORCING_SETTING" />" នៅក្នុង "<ph name="SETTINGS_PAGE" />"</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb
index 0e0d96c..8289da5 100644
--- a/components/strings/components_strings_ko.xtb
+++ b/components/strings/components_strings_ko.xtb
@@ -1149,7 +1149,7 @@
 <translation id="6446163441502663861">Kahu(봉투)</translation>
 <translation id="6446608382365791566">자세한 정보 추가</translation>
 <translation id="6447842834002726250">쿠키</translation>
-<translation id="644931407731409778">{COUNT,plural, =1{페이지 1개}other{페이지 #개}}가 포함된 PDF 문서</translation>
+<translation id="644931407731409778">{COUNT,plural, =1{1페이지}other{#페이지}}로 이루어진 PDF 문서</translation>
 <translation id="6451458296329894277">양식 다시 제출 확인</translation>
 <translation id="6457206614190510200">새들 스티치</translation>
 <translation id="6465306955648956876">비밀번호 관리...</translation>
diff --git a/components/strings/components_strings_zu.xtb b/components/strings/components_strings_zu.xtb
index f355deb..aaaa0f3 100644
--- a/components/strings/components_strings_zu.xtb
+++ b/components/strings/components_strings_zu.xtb
@@ -5,7 +5,7 @@
 <translation id="1010200102790553230">Layisha ikhasi kamuva</translation>
 <translation id="1015730422737071372">Nikeza imininingwane engeziwe</translation>
 <translation id="1021110881106174305">Amakhadi amukelwe</translation>
-<translation id="1021753677514347426">Le nkinga yenzeka ngenxa yesitifiketi noma othile ufake kudivayisi yakho. Isitifiketi saziwa ngokusetshenziswa ukwengamela amanethiwekhi e-intercept, futhi asithembekile ku-Chromium. Ngenkathi ezinye izimo zokufinyelela zokwengamela zikhona, njengasesikoleni noma inethiwekhi yenkmpani, i-Chromium ifuna ukuqinisekisa ukuthi uyaqaphela ukuthi lokhu kuyenzeka, ngisho noma ungeke ukwazi ukukumisa. Ukwengamela kungenzeka kunoma isiphi isiphequluli noma uhlelo lokusebenza olufinyelela iwebhu.</translation>
+<translation id="1021753677514347426">Le nkinga yenzeka ngenxa yesitifiketi noma othile ufake kudivayisi yakho. Isitifiketi saziwa ngokusetshenziswa ukwengamela amanethiwekhi e-intercept, futhi asithembekile ku-Chromium. Ngenkathi ezinye izimo zokufinyelela zokwengamela zikhona, njengasesikoleni noma inethiwekhi yenkampani, i-Chromium ifuna ukuqinisekisa ukuthi uyaqaphela ukuthi lokhu kuyenzeka, ngisho noma ungeke ukwazi ukukumisa. Ukwengamela kungenzeka kunoma isiphi isiphequluli noma uhlelo lokusebenza olufinyelela iwebhu.</translation>
 <translation id="1032854598605920125">Zungezisa ngokulandela iwashi</translation>
 <translation id="1036348656032585052">Vala</translation>
 <translation id="1038842779957582377">igama elingaziwa</translation>
@@ -863,7 +863,7 @@
 <translation id="5112422516732747637">A5</translation>
 <translation id="5115216390227830982">European-Edp</translation>
 <translation id="5115563688576182185">(64-bhithi)</translation>
-<translation id="5121469660360593280">Yabelana ngedatha mayelana nemicimbi yokuphepha ezimakiwe nge-Chrome Enterprise User Protect ngomlawuli wakho. Lokhu kungafaka ama-URL amakhasi owavakashele, amagama amafayela noma ethemathada, kanye negama lomsebenzisi olisebenzisela ukungena ngfemvume kudivayisi yakho naku-Chrome.</translation>
+<translation id="5121469660360593280">Yabelana ngedatha mayelana nemicimbi yokuphepha ezimakiwe nge-Chrome Enterprise User Protect ngomlawuli wakho. Lokhu kungafaka ama-URL amakhasi owavakashele, amagama amafayela noma ethemathada, kanye negama lomsebenzisi olisebenzisela ukungena ngemvume kudivayisi yakho naku-Chrome.</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Qinisekisa ikhadi lakho</translation>
 <translation id="5135404736266831032">Phatha amakheli...</translation>
@@ -1210,7 +1210,7 @@
 <translation id="6786747875388722282">Izandiso</translation>
 <translation id="6790428901817661496">Dlala</translation>
 <translation id="679355240208270552">Kuzithsiwe ngoba usesho oluzenzakalelayo alinikiwe amandla inqubomgomo.</translation>
-<translation id="6794951432696553238">Qinisekisa amakhad akho ngokushesha ngokusebenzisa i-Windows Hello kusuka manje</translation>
+<translation id="6794951432696553238">Qinisekisa amakhadi akho ngokushesha ngokusebenzisa i-Windows Hello kusuka manje</translation>
 <translation id="681021252041861472">Inkambu edingekile</translation>
 <translation id="6810899417690483278">Yenza ngezfiso i-ID</translation>
 <translation id="6825578344716086703">Uzame ukufika ku-<ph name="DOMAIN" />, kodwa iseva iphrezente isitifiketi esisayiniwe kusetshenziswa i-algorithm yesiginesha ebuthaka. Lokhu kusho ukuthi izifakazelo zokuvikela eziphrezentwe yiseva kungenzeka zenziwe ngomkhonyovu, futhi iseva kungenzeka kungabi yiseva oyilindele (kungenzeka ukuthi uxhumeka nomhlaseli).</translation>
@@ -1246,7 +1246,7 @@
 <translation id="6989763994942163495">Bonisa izilungiselelo ezithuthukisiwe...</translation>
 <translation id="6993898126790112050">6x9 (Envelope)</translation>
 <translation id="6996312675313362352">Hlala uhumusha isi-<ph name="ORIGINAL_LANGUAGE" /></translation>
-<translation id="7004583254764674281">Sebenzisa i-Windows Hello ukuqinisekisa amkhadi ngokushesha</translation>
+<translation id="7004583254764674281">Sebenzisa i-Windows Hello ukuqinisekisa amakhadi ngokushesha</translation>
 <translation id="7012363358306927923">I-China UnionPay</translation>
 <translation id="7016992613359344582">Lawo mashaji angahle abe isikhathi esisodwa noma avele kaningi futhi kungenzeka angacaci.</translation>
 <translation id="7029809446516969842">Amaphasiwedi</translation>
@@ -1315,7 +1315,7 @@
 <translation id="7349430561505560861">A4-Extra</translation>
 <translation id="7353601530677266744">Umugqa womyalo</translation>
 <translation id="7372973238305370288">umphumela wosesho</translation>
-<translation id="7374733840632556089">Le nkinga yenzeka ngenxa yesitifiketi noma othile ufake kudivayisi yakho. Isitifiketi saziwa ngokusetshenziswa ukwengamela amanethiwekhi e-intercept, futhi asithembekile ku-Chrome. Ngenkathi ezinye izimo zokufinyelela zokwengamela zikhona, njengasesikoleni noma inethiwekhi yenkmpani, i-Chrome ifuna ukuqinisekisa ukuthi uyaqaphela ukuthi lokhu kuyenzeka, ngisho noma ungeke ukwazi ukukumisa. Ukwengamela kungenzeka kunoma isiphi isiphequluli noma uhlelo lokusebenza olufinyelela iwebhu.</translation>
+<translation id="7374733840632556089">Le nkinga yenzeka ngenxa yesitifiketi noma othile ufake kudivayisi yakho. Isitifiketi saziwa ngokusetshenziswa ukwengamela amanethiwekhi e-intercept, futhi asithembekile ku-Chrome. Ngenkathi ezinye izimo zokufinyelela zokwengamela zikhona, njengasesikoleni noma inethiwekhi yenkampani, i-Chrome ifuna ukuqinisekisa ukuthi uyaqaphela ukuthi lokhu kuyenzeka, ngisho noma ungeke ukwazi ukukumisa. Ukwengamela kungenzeka kunoma isiphi isiphequluli noma uhlelo lokusebenza olufinyelela iwebhu.</translation>
 <translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
 <translation id="7378594059915113390">Izilawuli zemidiya</translation>
 <translation id="7378627244592794276">Cha</translation>
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc
index c574c937..ebcc9652 100644
--- a/components/sync/driver/about_sync_util.cc
+++ b/components/sync/driver/about_sync_util.cc
@@ -186,22 +186,23 @@
   std::vector<std::unique_ptr<Section>> sections_;
 };
 
-std::string GetDisableReasonsString(int disable_reasons) {
-  if (disable_reasons == syncer::SyncService::DISABLE_REASON_NONE) {
+std::string GetDisableReasonsString(
+    SyncService::DisableReasonSet disable_reasons) {
+  if (disable_reasons.Empty()) {
     return "None";
   }
   std::vector<std::string> reason_strings;
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_PLATFORM_OVERRIDE))
     reason_strings.push_back("Platform override");
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_ENTERPRISE_POLICY))
     reason_strings.push_back("Enterprise policy");
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_NOT_SIGNED_IN))
     reason_strings.push_back("Not signed in");
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_USER_CHOICE)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_USER_CHOICE))
     reason_strings.push_back("User choice");
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR))
     reason_strings.push_back("Unrecoverable error");
-  if (disable_reasons & syncer::SyncService::DISABLE_REASON_PAUSED)
+  if (disable_reasons.Has(SyncService::DISABLE_REASON_PAUSED))
     reason_strings.push_back("Paused");
   return base::JoinString(reason_strings, ", ");
 }
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc
index 0b110d14..b2c8fdc 100644
--- a/components/sync/driver/fake_sync_service.cc
+++ b/components/sync/driver/fake_sync_service.cc
@@ -28,7 +28,8 @@
   return nullptr;
 }
 
-int FakeSyncService::GetDisableReasons() const {
+syncer::SyncService::DisableReasonSet FakeSyncService::GetDisableReasons()
+    const {
   return DISABLE_REASON_NOT_SIGNED_IN;
 }
 
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h
index bda0069..7efdd43 100644
--- a/components/sync/driver/fake_sync_service.h
+++ b/components/sync/driver/fake_sync_service.h
@@ -26,7 +26,7 @@
   // SyncService implementation.
   syncer::SyncUserSettings* GetUserSettings() override;
   const syncer::SyncUserSettings* GetUserSettings() const override;
-  int GetDisableReasons() const override;
+  DisableReasonSet GetDisableReasons() const override;
   TransportState GetTransportState() const override;
   CoreAccountInfo GetAuthenticatedAccountInfo() const override;
   bool IsAuthenticatedAccountPrimary() const override;
diff --git a/components/sync/driver/mock_sync_service.h b/components/sync/driver/mock_sync_service.h
index 0cb24b7..fd29559 100644
--- a/components/sync/driver/mock_sync_service.h
+++ b/components/sync/driver/mock_sync_service.h
@@ -33,7 +33,7 @@
   // SyncService implementation.
   syncer::SyncUserSettings* GetUserSettings() override;
   const syncer::SyncUserSettings* GetUserSettings() const override;
-  MOCK_CONST_METHOD0(GetDisableReasons, int());
+  MOCK_CONST_METHOD0(GetDisableReasons, DisableReasonSet());
   MOCK_CONST_METHOD0(GetTransportState, TransportState());
   MOCK_CONST_METHOD0(IsLocalSyncEnabled, bool());
   MOCK_CONST_METHOD0(GetAuthenticatedAccountInfo, CoreAccountInfo());
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc
index 441f3df7..11150a8 100644
--- a/components/sync/driver/profile_sync_service.cc
+++ b/components/sync/driver/profile_sync_service.cc
@@ -76,20 +76,22 @@
   SYNC_INITIAL_STATE_LIMIT
 };
 
-void RecordSyncInitialState(int disable_reasons, bool first_setup_complete) {
+void RecordSyncInitialState(SyncService::DisableReasonSet disable_reasons,
+                            bool first_setup_complete) {
   SyncInitialState sync_state = CAN_START;
-  if (disable_reasons & ProfileSyncService::DISABLE_REASON_NOT_SIGNED_IN) {
+  if (disable_reasons.Has(ProfileSyncService::DISABLE_REASON_NOT_SIGNED_IN)) {
     sync_state = NOT_SIGNED_IN;
-  } else if (disable_reasons &
-             ProfileSyncService::DISABLE_REASON_ENTERPRISE_POLICY) {
+  } else if (disable_reasons.Has(
+                 ProfileSyncService::DISABLE_REASON_ENTERPRISE_POLICY)) {
     sync_state = NOT_ALLOWED_BY_POLICY;
-  } else if (disable_reasons &
-             ProfileSyncService::DISABLE_REASON_PLATFORM_OVERRIDE) {
+  } else if (disable_reasons.Has(
+                 ProfileSyncService::DISABLE_REASON_PLATFORM_OVERRIDE)) {
     // This case means Android's "MasterSync" toggle. However, that is not
     // plumbed into ProfileSyncService until after this method, so we never get
     // here. See http://crbug.com/568771.
     sync_state = NOT_ALLOWED_BY_PLATFORM;
-  } else if (disable_reasons & ProfileSyncService::DISABLE_REASON_USER_CHOICE) {
+  } else if (disable_reasons.Has(
+                 ProfileSyncService::DISABLE_REASON_USER_CHOICE)) {
     if (first_setup_complete) {
       sync_state = NOT_REQUESTED;
     } else {
@@ -385,9 +387,10 @@
   // USER_CHOICE (i.e. the Sync feature toggle) and PLATFORM_OVERRIDE (i.e.
   // Android's "MasterSync" toggle) do not prevent starting up the Sync
   // transport.
-  const int kDisableReasonMask =
-      ~(DISABLE_REASON_USER_CHOICE | DISABLE_REASON_PLATFORM_OVERRIDE);
-  return (GetDisableReasons() & kDisableReasonMask) == DISABLE_REASON_NONE;
+  auto disable_reasons = GetDisableReasons();
+  disable_reasons.RemoveAll(SyncService::DisableReasonSet(
+      DISABLE_REASON_USER_CHOICE, DISABLE_REASON_PLATFORM_OVERRIDE));
+  return disable_reasons.Empty();
 }
 
 void ProfileSyncService::OnProtocolEvent(const ProtocolEvent& event) {
@@ -682,35 +685,35 @@
   return user_settings_.get();
 }
 
-int ProfileSyncService::GetDisableReasons() const {
+SyncService::DisableReasonSet ProfileSyncService::GetDisableReasons() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // If Sync is disabled via command line flag, then ProfileSyncService
   // shouldn't even be instantiated.
   DCHECK(switches::IsSyncAllowedByFlag());
 
-  int result = DISABLE_REASON_NONE;
+  DisableReasonSet result;
   if (!user_settings_->IsSyncAllowedByPlatform()) {
-    result = result | DISABLE_REASON_PLATFORM_OVERRIDE;
+    result.Put(DISABLE_REASON_PLATFORM_OVERRIDE);
   }
   if (sync_prefs_.IsManaged() || sync_disabled_by_admin_) {
-    result = result | DISABLE_REASON_ENTERPRISE_POLICY;
+    result.Put(DISABLE_REASON_ENTERPRISE_POLICY);
   }
   // Local sync doesn't require sign-in.
   if (!IsSignedIn() && !IsLocalSyncEnabled()) {
-    result = result | DISABLE_REASON_NOT_SIGNED_IN;
+    result.Put(DISABLE_REASON_NOT_SIGNED_IN);
   }
   // When local sync is on sync should be considered requsted or otherwise it
   // will not resume after the policy or the flag has been removed.
   if (!user_settings_->IsSyncRequested() && !IsLocalSyncEnabled()) {
-    result = result | DISABLE_REASON_USER_CHOICE;
+    result.Put(DISABLE_REASON_USER_CHOICE);
   }
   if (unrecoverable_error_reason_ != ERROR_REASON_UNSET) {
-    result = result | DISABLE_REASON_UNRECOVERABLE_ERROR;
+    result.Put(DISABLE_REASON_UNRECOVERABLE_ERROR);
   }
   if (base::FeatureList::IsEnabled(switches::kStopSyncInPausedState)) {
     if (auth_manager_->IsSyncPaused()) {
-      result = result | DISABLE_REASON_PAUSED;
+      result.Put(DISABLE_REASON_PAUSED);
     }
   }
   return result;
diff --git a/components/sync/driver/profile_sync_service.h b/components/sync/driver/profile_sync_service.h
index 7bc3dfb..2266d4d 100644
--- a/components/sync/driver/profile_sync_service.h
+++ b/components/sync/driver/profile_sync_service.h
@@ -116,7 +116,7 @@
   // SyncService implementation
   SyncUserSettings* GetUserSettings() override;
   const SyncUserSettings* GetUserSettings() const override;
-  int GetDisableReasons() const override;
+  DisableReasonSet GetDisableReasons() const override;
   TransportState GetTransportState() const override;
   bool IsLocalSyncEnabled() const override;
   CoreAccountInfo GetAuthenticatedAccountInfo() const override;
diff --git a/components/sync/driver/profile_sync_service_startup_unittest.cc b/components/sync/driver/profile_sync_service_startup_unittest.cc
index ae072aab..991dfa1 100644
--- a/components/sync/driver/profile_sync_service_startup_unittest.cc
+++ b/components/sync/driver/profile_sync_service_startup_unittest.cc
@@ -164,9 +164,10 @@
   // Should not actually start, rather just clean things up and wait
   // to be enabled.
   sync_service()->Initialize();
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN |
-                SyncService::DISABLE_REASON_USER_CHOICE,
-            sync_service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+                                    SyncService::DISABLE_REASON_USER_CHOICE),
+      sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
 
@@ -180,8 +181,9 @@
   sync_service()->GetUserSettings()->SetSyncRequested(true);
   auto sync_blocker = sync_service()->GetSetupInProgressHandle();
   EXPECT_FALSE(sync_service()->IsEngineInitialized());
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
-            sync_service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN),
+      sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
 
@@ -190,7 +192,7 @@
   // Now we're signed in, so the engine can start. Engine initialization is
   // immediate in this test, so we bypass the INITIALIZING state.
   EXPECT_TRUE(sync_service()->IsEngineInitialized());
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE,
+  EXPECT_EQ(SyncService::DisableReasonSet(),
             sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
             sync_service()->GetTransportState());
@@ -274,7 +276,8 @@
   // state. It'll take either a browser restart or a full sign-out+sign-in to
   // get out of this.
   EXPECT_TRUE(sync_service()->HasUnrecoverableError());
-  EXPECT_EQ(SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR),
             sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
@@ -471,7 +474,8 @@
   EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
       .Times(0);
   sync_service()->Initialize();
-  EXPECT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY),
             sync_service()->GetDisableReasons());
 }
 
@@ -492,7 +496,7 @@
   // this test).
   sync_service()->Initialize();
   EXPECT_TRUE(sync_service()->IsEngineInitialized());
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE,
+  EXPECT_EQ(SyncService::DisableReasonSet(),
             sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             sync_service()->GetTransportState());
@@ -506,7 +510,8 @@
   EXPECT_CALL(*data_type_manager, Stop(DISABLE_SYNC));
 
   sync_prefs()->SetManagedForTest(true);
-  ASSERT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+  ASSERT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY),
             sync_service()->GetDisableReasons());
   EXPECT_FALSE(sync_service()->IsEngineInitialized());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
@@ -527,7 +532,7 @@
 
   sync_prefs()->SetManagedForTest(false);
 
-  ASSERT_EQ(SyncService::DISABLE_REASON_NONE,
+  ASSERT_EQ(SyncService::DisableReasonSet(),
             sync_service()->GetDisableReasons());
 
   EXPECT_TRUE(sync_service()->IsEngineInitialized());
@@ -559,7 +564,8 @@
   ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
   sync_service()->Initialize();
   EXPECT_TRUE(sync_service()->HasUnrecoverableError());
-  EXPECT_EQ(SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR),
             sync_service()->GetDisableReasons());
 }
 
@@ -576,7 +582,8 @@
 
   auto sync_blocker = sync_service()->GetSetupInProgressHandle();
   sync_blocker.reset();
-  EXPECT_EQ(SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR),
             sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
@@ -605,17 +612,19 @@
 
   // There is no signed-in user, so also nobody has decided that Sync should be
   // started.
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN |
-                SyncService::DISABLE_REASON_USER_CHOICE,
-            sync_service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+                                    SyncService::DISABLE_REASON_USER_CHOICE),
+      sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             sync_service()->GetTransportState());
 
   // Sign in. Now Sync-the-transport could start, but gets deferred by default.
   // Sync-the-feature still doesn't start until the user says they want it.
   SimulateTestUserSignin();
-  EXPECT_EQ(SyncService::DISABLE_REASON_USER_CHOICE,
-            sync_service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
+      sync_service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::START_DEFERRED,
             sync_service()->GetTransportState());
   EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
diff --git a/components/sync/driver/profile_sync_service_unittest.cc b/components/sync/driver/profile_sync_service_unittest.cc
index f8895af..df35ca2 100644
--- a/components/sync/driver/profile_sync_service_unittest.cc
+++ b/components/sync/driver/profile_sync_service_unittest.cc
@@ -349,7 +349,7 @@
       .WillOnce(
           ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback()));
   InitializeForNthSync();
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 }
@@ -362,7 +362,7 @@
       .WillOnce(
           ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback()));
   InitializeForNthSync();
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 }
@@ -383,7 +383,7 @@
       /*selected_types=*/UserSelectableTypeSet::All());
   service()->Initialize();
 
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
 
   // Sync should immediately start up in transport mode.
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
@@ -421,7 +421,8 @@
   SignIn();
   CreateService(ProfileSyncService::AUTO_START);
   InitializeForNthSync();
-  EXPECT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY),
             service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
@@ -434,8 +435,9 @@
                           std::make_unique<base::Value>(true));
   CreateService(ProfileSyncService::AUTO_START);
   InitializeForNthSync();
-  EXPECT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY |
-                SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+                SyncService::DISABLE_REASON_NOT_SIGNED_IN),
             service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
@@ -443,8 +445,9 @@
   // Remove the policy. Now only missing sign-in is preventing startup.
   prefs()->SetManagedPref(prefs::kSyncManaged,
                           std::make_unique<base::Value>(false));
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN),
+      service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
 
@@ -465,14 +468,15 @@
   CreateService(ProfileSyncService::AUTO_START);
   InitializeForNthSync();
 
-  ASSERT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
   prefs()->SetManagedPref(prefs::kSyncManaged,
                           std::make_unique<base::Value>(true));
 
-  EXPECT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY),
             service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
@@ -510,8 +514,9 @@
   EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
       .WillOnce(ReturnNewFakeSyncEngine());
   service()->GetUserSettings()->SetSyncRequested(false);
-  EXPECT_EQ(SyncService::DISABLE_REASON_USER_CHOICE,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
+      service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   EXPECT_FALSE(service()->IsSyncFeatureActive());
@@ -519,7 +524,7 @@
 
   // Request start. Now Sync-the-feature should start again.
   service()->GetUserSettings()->SetSyncRequested(true);
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   EXPECT_TRUE(service()->IsSyncFeatureActive());
@@ -535,7 +540,7 @@
   SyncPrefs sync_prefs(prefs());
 
   ASSERT_TRUE(sync_prefs.IsSyncRequested());
-  ASSERT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   ASSERT_TRUE(service()->IsSyncFeatureActive());
@@ -545,8 +550,9 @@
 
   service()->GetUserSettings()->SetSyncRequested(false);
   EXPECT_FALSE(sync_prefs.IsSyncRequested());
-  EXPECT_EQ(SyncService::DISABLE_REASON_USER_CHOICE,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
+      service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   EXPECT_FALSE(service()->IsSyncFeatureActive());
@@ -554,7 +560,7 @@
 
   service()->GetUserSettings()->SetSyncRequested(true);
   EXPECT_TRUE(sync_prefs.IsSyncRequested());
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   EXPECT_TRUE(service()->IsSyncFeatureActive());
@@ -569,7 +575,7 @@
   SignIn();
   InitializeForNthSync();
 
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
   EXPECT_EQ(identity_manager()->GetPrimaryAccountId(),
@@ -585,8 +591,9 @@
       signin_metrics::SignoutDelete::IGNORE_METRIC);
   // Wait for PSS to be notified that the primary account has gone away.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN),
+      service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
   EXPECT_EQ(CoreAccountId(), identity_provider()->GetActiveAccountId());
@@ -1168,17 +1175,19 @@
 #if defined(OS_CHROMEOS)
   // ChromeOS does not support signout.
   EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
-  EXPECT_EQ(SyncService::DISABLE_REASON_USER_CHOICE,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
+      service()->GetDisableReasons());
   // Since ChromeOS doesn't support signout and so the account is still there
   // and available, Sync will restart in standalone transport mode.
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 #else
   EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
-  EXPECT_EQ(SyncService::DISABLE_REASON_NOT_SIGNED_IN |
-                SyncService::DISABLE_REASON_USER_CHOICE,
-            service()->GetDisableReasons());
+  EXPECT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
+                                    SyncService::DISABLE_REASON_USER_CHOICE),
+      service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
   EXPECT_TRUE(service()->GetLastSyncedTimeForDebugging().is_null());
@@ -1194,14 +1203,15 @@
                           std::make_unique<base::Value>(false));
   CreateServiceWithLocalSyncBackend();
   InitializeForNthSync();
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
   prefs()->SetManagedPref(prefs::kSyncManaged,
                           std::make_unique<base::Value>(true));
 
-  EXPECT_EQ(SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
+  EXPECT_EQ(SyncService::DisableReasonSet(
+                SyncService::DISABLE_REASON_ENTERPRISE_POLICY),
             service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::DISABLED,
             service()->GetTransportState());
@@ -1213,7 +1223,7 @@
                           std::make_unique<base::Value>(false));
 
   service()->GetUserSettings()->SetSyncRequested(true);
-  EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 }
@@ -1356,8 +1366,9 @@
   // Temporarily disable sync without turning it off.
   service()->GetUserSettings()->SetSyncRequested(false);
   ASSERT_FALSE(service()->GetUserSettings()->IsSyncRequested());
-  ASSERT_EQ(SyncService::DISABLE_REASON_USER_CHOICE,
-            service()->GetDisableReasons());
+  ASSERT_EQ(
+      SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
+      service()->GetDisableReasons());
 
   // Verify that sync service does not provide demographics when it is
   // temporarily disabled.
@@ -1405,7 +1416,7 @@
   identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
   ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
             service()->GetAuthError().state());
-  ASSERT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+  ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
 
   // Verify that sync service does not provide demographics when sync is paused.
   UserDemographicsResult user_demographics_result =
@@ -1452,7 +1463,8 @@
   identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
   ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
             service()->GetAuthError().state());
-  ASSERT_EQ(SyncService::DISABLE_REASON_PAUSED, service()->GetDisableReasons());
+  ASSERT_EQ(SyncService::DisableReasonSet(SyncService::DISABLE_REASON_PAUSED),
+            service()->GetDisableReasons());
 
   // Verify that sync service does not provide demographics when sync is paused.
   UserDemographicsResult user_demographics_result =
diff --git a/components/sync/driver/sync_service.cc b/components/sync/driver/sync_service.cc
index d76205b..eb8b71b6 100644
--- a/components/sync/driver/sync_service.cc
+++ b/components/sync/driver/sync_service.cc
@@ -35,8 +35,7 @@
 }
 
 bool SyncService::CanSyncFeatureStart() const {
-  return GetDisableReasons() == DISABLE_REASON_NONE &&
-         IsAuthenticatedAccountPrimary();
+  return GetDisableReasons().Empty() && IsAuthenticatedAccountPrimary();
 }
 
 bool SyncService::IsEngineInitialized() const {
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h
index a35f0ea..ab36d32e0 100644
--- a/components/sync/driver/sync_service.h
+++ b/components/sync/driver/sync_service.h
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/sync/base/enum_set.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/user_demographics.h"
 #include "components/sync/driver/sync_service_observer.h"
@@ -121,33 +122,37 @@
  public:
   // The set of reasons due to which Sync-the-feature can be disabled. Note that
   // Sync-the-transport might still start up even in the presence of (some)
-  // disable reasons. Meant to be used as a bitmask.
+  // disable reasons. Meant to be used as a enum set.
   enum DisableReason {
-    DISABLE_REASON_NONE = 0,
     // Sync is disabled via platform-level override (e.g. Android's "MasterSync"
     // toggle).
-    DISABLE_REASON_PLATFORM_OVERRIDE = 1 << 0,
+    DISABLE_REASON_PLATFORM_OVERRIDE,
+    DISABLE_REASON_FIRST = DISABLE_REASON_PLATFORM_OVERRIDE,
     // Sync is disabled by enterprise policy, either browser policy (through
     // prefs) or account policy received from the Sync server.
-    DISABLE_REASON_ENTERPRISE_POLICY = 1 << 1,
+    DISABLE_REASON_ENTERPRISE_POLICY,
     // Sync can't start because there is no authenticated user.
-    DISABLE_REASON_NOT_SIGNED_IN = 1 << 2,
+    DISABLE_REASON_NOT_SIGNED_IN,
     // Sync is suppressed by user choice, either via the feature toggle in
     // Chrome settings (which exists on Android and iOS), a platform-level
     // toggle (e.g. Android's "ChromeSync" toggle), or a “Reset Sync” operation
     // from the dashboard. This is also set if there's simply no signed-in user
     // (in addition to DISABLE_REASON_NOT_SIGNED_IN).
-    DISABLE_REASON_USER_CHOICE = 1 << 3,
+    DISABLE_REASON_USER_CHOICE,
     // Sync has encountered an unrecoverable error. It won't attempt to start
     // again until either the browser is restarted, or the user fully signs out
     // and back in again.
-    DISABLE_REASON_UNRECOVERABLE_ERROR = 1 << 4,
+    DISABLE_REASON_UNRECOVERABLE_ERROR,
     // Sync is paused because the user signed out on the web. This is different
     // from NOT_SIGNED_IN: In this case, there *is* still a primary account, but
     // it doesn't have valid credentials.
-    DISABLE_REASON_PAUSED = 1 << 5,
+    DISABLE_REASON_PAUSED,
+    DISABLE_REASON_LAST = DISABLE_REASON_PAUSED,
   };
 
+  using DisableReasonSet =
+      EnumSet<DisableReason, DISABLE_REASON_FIRST, DISABLE_REASON_LAST>;
+
   // The overall state of Sync-the-transport, in ascending order of
   // "activeness". Note that this refers to the transport layer, which may be
   // active even if Sync-the-feature is turned off.
@@ -196,11 +201,11 @@
   // DisableReason enum entries.
   // Note: This refers to Sync-the-feature. Sync-the-transport may be running
   // even in the presence of disable reasons.
-  virtual int GetDisableReasons() const = 0;
+  virtual DisableReasonSet GetDisableReasons() const = 0;
   // Helper that returns whether GetDisableReasons() contains the given |reason|
   // (possibly among others).
   bool HasDisableReason(DisableReason reason) const {
-    return GetDisableReasons() & reason;
+    return GetDisableReasons().Has(reason);
   }
 
   // Returns the overall state of the SyncService transport layer. See the enum
diff --git a/components/sync/driver/sync_service_utils_unittest.cc b/components/sync/driver/sync_service_utils_unittest.cc
index 8f14e05..f378079b 100644
--- a/components/sync/driver/sync_service_utils_unittest.cc
+++ b/components/sync/driver/sync_service_utils_unittest.cc
@@ -28,7 +28,7 @@
 
   // Once sync gets allowed (e.g. policy is updated), uploading should not be
   // disabled anymore (though not necessarily active yet).
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetTransportState(
       syncer::SyncService::TransportState::START_DEFERRED);
 
@@ -39,7 +39,7 @@
 TEST(SyncServiceUtilsTest,
      UploadToGoogleInitializingUntilConfiguredAndActiveAndSyncCycleComplete) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetTransportState(
       syncer::SyncService::TransportState::START_DEFERRED);
   service.SetPreferredDataTypes(ProtocolTypes());
@@ -63,7 +63,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForModelType) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
   service.SetNonEmptyLastCycleSnapshot();
 
@@ -86,7 +86,7 @@
 TEST(SyncServiceUtilsTest,
      UploadToGoogleDisabledForModelTypeThatFailedToStart) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
   service.SetNonEmptyLastCycleSnapshot();
 
@@ -107,7 +107,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfLocalSyncEnabled) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
@@ -127,7 +127,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledOnPersistentAuthError) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
@@ -167,7 +167,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfCustomPassphraseInUse) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
@@ -197,7 +197,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForSecondaryAccount) {
   TestSyncService service;
-  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
+  service.SetDisableReasons(SyncService::DisableReasonSet());
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
index 7db4d68..295e0bd 100644
--- a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
+++ b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
@@ -31,7 +31,7 @@
   void EnableSync() {
     identity_test_env_.MakePrimaryAccountAvailable("foo@gmail.com");
     sync_service_.SetIsAuthenticatedAccountPrimary(true);
-    sync_service_.SetDisableReasons(SyncService::DISABLE_REASON_NONE);
+    sync_service_.SetDisableReasons(SyncService::DisableReasonSet());
   }
 
   void SetInvalidCredentialsAuthError() {
diff --git a/components/sync/driver/test_sync_service.cc b/components/sync/driver/test_sync_service.cc
index adcc6d15..17a8960 100644
--- a/components/sync/driver/test_sync_service.cc
+++ b/components/sync/driver/test_sync_service.cc
@@ -46,7 +46,7 @@
 
 TestSyncService::~TestSyncService() = default;
 
-void TestSyncService::SetDisableReasons(int disable_reasons) {
+void TestSyncService::SetDisableReasons(DisableReasonSet disable_reasons) {
   disable_reasons_ = disable_reasons;
 }
 
@@ -154,7 +154,7 @@
   return &user_settings_;
 }
 
-int TestSyncService::GetDisableReasons() const {
+SyncService::DisableReasonSet TestSyncService::GetDisableReasons() const {
   return disable_reasons_;
 }
 
diff --git a/components/sync/driver/test_sync_service.h b/components/sync/driver/test_sync_service.h
index 7a23387..e0129a4 100644
--- a/components/sync/driver/test_sync_service.h
+++ b/components/sync/driver/test_sync_service.h
@@ -27,7 +27,7 @@
   TestSyncService();
   ~TestSyncService() override;
 
-  void SetDisableReasons(int disable_reasons);
+  void SetDisableReasons(DisableReasonSet disable_reasons);
   void SetTransportState(TransportState transport_state);
   void SetLocalSyncEnabled(bool local_sync_enabled);
   void SetAuthenticatedAccountInfo(const CoreAccountInfo& account_info);
@@ -59,7 +59,7 @@
   // SyncService implementation.
   syncer::SyncUserSettings* GetUserSettings() override;
   const syncer::SyncUserSettings* GetUserSettings() const override;
-  int GetDisableReasons() const override;
+  DisableReasonSet GetDisableReasons() const override;
   TransportState GetTransportState() const override;
   bool IsLocalSyncEnabled() const override;
   CoreAccountInfo GetAuthenticatedAccountInfo() const override;
@@ -115,7 +115,7 @@
  private:
   TestSyncUserSettings user_settings_;
 
-  int disable_reasons_ = DISABLE_REASON_NONE;
+  DisableReasonSet disable_reasons_;
   TransportState transport_state_ = TransportState::ACTIVE;
   bool local_sync_enabled_ = false;
   CoreAccountInfo account_info_;
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc
index 68b8a6a..d49faad 100644
--- a/components/sync/driver/test_sync_user_settings.cc
+++ b/components/sync/driver/test_sync_user_settings.cc
@@ -23,11 +23,11 @@
 }
 
 void TestSyncUserSettings::SetSyncRequested(bool requested) {
-  int disable_reasons = service_->GetDisableReasons();
+  SyncService::DisableReasonSet disable_reasons = service_->GetDisableReasons();
   if (requested) {
-    disable_reasons &= ~SyncService::DISABLE_REASON_USER_CHOICE;
+    disable_reasons.Remove(SyncService::DISABLE_REASON_USER_CHOICE);
   } else {
-    disable_reasons |= SyncService::DISABLE_REASON_USER_CHOICE;
+    disable_reasons.Put(SyncService::DISABLE_REASON_USER_CHOICE);
   }
   service_->SetDisableReasons(disable_reasons);
 }
@@ -38,11 +38,11 @@
 }
 
 void TestSyncUserSettings::SetSyncAllowedByPlatform(bool allowed) {
-  int disable_reasons = service_->GetDisableReasons();
+  SyncService::DisableReasonSet disable_reasons = service_->GetDisableReasons();
   if (allowed) {
-    disable_reasons &= ~SyncService::DISABLE_REASON_PLATFORM_OVERRIDE;
+    disable_reasons.Remove(SyncService::DISABLE_REASON_PLATFORM_OVERRIDE);
   } else {
-    disable_reasons |= SyncService::DISABLE_REASON_PLATFORM_OVERRIDE;
+    disable_reasons.Put(SyncService::DISABLE_REASON_PLATFORM_OVERRIDE);
   }
   service_->SetDisableReasons(disable_reasons);
 }
diff --git a/components/sync/engine/net/http_bridge.cc b/components/sync/engine/net/http_bridge.cc
index e1a1793..e600e1e 100644
--- a/components/sync/engine/net/http_bridge.cc
+++ b/components/sync/engine/net/http_bridge.cc
@@ -28,7 +28,6 @@
 #include "net/http/http_response_headers.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/static_http_user_agent_settings.h"
-#include "net/url_request/url_request_status.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "third_party/zlib/google/compression_utils.h"
 
@@ -383,12 +382,10 @@
 
   if (fetch_state_.request_succeeded)
     LogTimeout(false);
-  base::UmaHistogramSparse(
-      "Sync.URLFetchResponse",
-      fetch_state_.request_succeeded
-          ? fetch_state_.http_status_code
-          : net::URLRequestStatus::FromError(fetch_state_.net_error_code)
-                .ToNetError());
+  base::UmaHistogramSparse("Sync.URLFetchResponse",
+                           fetch_state_.request_succeeded
+                               ? fetch_state_.http_status_code
+                               : fetch_state_.net_error_code);
   UMA_HISTOGRAM_LONG_TIMES("Sync.URLFetchTime",
                            fetch_state_.end_time - fetch_state_.start_time);
 
diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc
index 532ffe15..fe452ae 100644
--- a/components/sync/engine_impl/sync_scheduler_impl.cc
+++ b/components/sync/engine_impl/sync_scheduler_impl.cc
@@ -10,11 +10,13 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "components/sync/base/logging.h"
+#include "components/sync/base/model_type.h"
 #include "components/sync/engine/sync_engine_switches.h"
 #include "components/sync/engine_impl/backoff_delay_provider.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -26,6 +28,17 @@
 
 namespace {
 
+// Indicates whether |configuration_params| corresponds to Nigori only
+// configuration (which happens if initial sync for Nigori isn't completed).
+// If |configuration_params| is null, returns false.
+bool IsNigoriOnlyConfiguration(
+    const ConfigurationParams* configuration_params) {
+  if (!configuration_params) {
+    return false;
+  }
+  return configuration_params->types_to_download == ModelTypeSet(NIGORI);
+}
+
 bool IsConfigRelatedUpdateOriginValue(
     sync_pb::SyncEnums::GetUpdatesOrigin origin) {
   switch (origin) {
@@ -524,6 +537,29 @@
         WaitInterval::EXPONENTIAL_BACKOFF, next_delay);
     SDVLOG(2) << "Sync cycle failed.  Will back off for "
               << wait_interval_->length.InMilliseconds() << "ms.";
+
+    MaybeRecordNigoriOnlyConfigurationFailedHistograms();
+  }
+}
+
+void SyncSchedulerImpl::MaybeRecordNigoriOnlyConfigurationFailedHistograms() {
+  if (!IsNigoriOnlyConfiguration(pending_configure_params_.get())) {
+    return;
+  }
+  if (!nigori_configuration_failed_recorded) {
+    UMA_HISTOGRAM_BOOLEAN(
+        "Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailed",
+        !cycle_context_->connection_manager()->HasInvalidAccessToken());
+    nigori_configuration_failed_recorded = true;
+  }
+  // Guaranteed by calling side.
+  DCHECK(wait_interval_);
+  if (!nigori_configuration_failed_with_5s_backoff_recorded &&
+      wait_interval_->length.InSeconds() > 5) {
+    UMA_HISTOGRAM_BOOLEAN(
+        "Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailedWith5SecBackoff",
+        !cycle_context_->connection_manager()->HasInvalidAccessToken());
+    nigori_configuration_failed_with_5s_backoff_recorded = true;
   }
 }
 
diff --git a/components/sync/engine_impl/sync_scheduler_impl.h b/components/sync/engine_impl/sync_scheduler_impl.h
index 5b8e749c..108cb0d9 100644
--- a/components/sync/engine_impl/sync_scheduler_impl.h
+++ b/components/sync/engine_impl/sync_scheduler_impl.h
@@ -130,6 +130,8 @@
   // Helper function for Do{Nudge,Configuration,Poll}SyncCycleJob.
   void HandleFailure(const ModelNeutralState& model_neutral_state);
 
+  void MaybeRecordNigoriOnlyConfigurationFailedHistograms();
+
   // Invoke the Syncer to perform a poll job.
   void DoPollSyncCycleJob();
 
@@ -281,6 +283,11 @@
   // Used to prevent changing nudge delays by the server in integration tests.
   bool force_short_nudge_delay_for_test_ = false;
 
+  // Indicates whether HasInvalidAccessTokenWhenNigoriOnlyConfigurationFailed*
+  // histograms already recorded.
+  bool nigori_configuration_failed_recorded = false;
+  bool nigori_configuration_failed_with_5s_backoff_recorded = false;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_{this};
diff --git a/components/sync/protocol/OWNERS b/components/sync/protocol/OWNERS
index 37add468..ce5d0cb 100644
--- a/components/sync/protocol/OWNERS
+++ b/components/sync/protocol/OWNERS
@@ -2,5 +2,3 @@
 mastiz@chromium.org
 treib@chromium.org
 tschumann@chromium.org
-
-per-file sharing_*=file://chrome/browser/sharing/OWNERS
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni
index 981f2f0a..f63552e 100644
--- a/components/sync/protocol/protocol_sources.gni
+++ b/components/sync/protocol/protocol_sources.gni
@@ -49,12 +49,6 @@
   "security_event_specifics",
   "send_tab_to_self_specifics",
   "session_specifics",
-  "sharing_click_to_call_message",
-  "sharing_message",
-  "sharing_peer_connection_messages",
-  "sharing_remote_copy_message",
-  "sharing_shared_clipboard_message",
-  "sharing_sms_fetch_message",
   "sync",
   "sync_enums",
   "synced_notification_app_info_specifics",
diff --git a/components/viz/common/resources/resource_format.h b/components/viz/common/resources/resource_format.h
index e5f18e2..2695d84 100644
--- a/components/viz/common/resources/resource_format.h
+++ b/components/viz/common/resources/resource_format.h
@@ -25,7 +25,7 @@
   R16_EXT,
   RGBX_8888,
   BGRX_8888,
-  RGBX_1010102,
+  RGBA_1010102,
   BGRX_1010102,
   YVU_420,
   YUV_420_BIPLANAR,
diff --git a/components/viz/common/resources/resource_format_utils.cc b/components/viz/common/resources/resource_format_utils.cc
index 7c132c11..1ec1213 100644
--- a/components/viz/common/resources/resource_format_utils.cc
+++ b/components/viz/common/resources/resource_format_utils.cc
@@ -39,7 +39,7 @@
     case RGBX_8888:
     case ETC1:
       return kRGB_888x_SkColorType;
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
       return kRGBA_1010102_SkColorType;
 
@@ -74,7 +74,7 @@
     case RGBA_8888:
     case RGBX_8888:
     case BGRX_8888:
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
     case P010:
       return 32;
@@ -117,7 +117,7 @@
     case R16_EXT:
     case RGBX_8888:
     case BGRX_8888:
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
     case YVU_420:
     case YUV_420_BIPLANAR:
@@ -146,7 +146,7 @@
       GL_UNSIGNED_SHORT,                   // R16_EXT
       GL_UNSIGNED_BYTE,                    // RGBX_8888
       GL_ZERO,                             // BGRX_8888
-      GL_UNSIGNED_INT_2_10_10_10_REV_EXT,  // RGBX_1010102
+      GL_UNSIGNED_INT_2_10_10_10_REV_EXT,  // RGBA_1010102
       GL_ZERO,                             // BGRX_1010102
       GL_ZERO,                             // YVU_420
       GL_ZERO,                             // YUV_420_BIPLANAR
@@ -176,7 +176,7 @@
       GL_RED_EXT,    // R16_EXT
       GL_RGB,        // RGBX_8888
       GL_ZERO,       // BGRX_8888
-      GL_RGBA,       // RGBX_1010102
+      GL_RGBA,       // RGBA_1010102
       GL_ZERO,       // BGRX_1010102
       GL_ZERO,       // YVU_420
       GL_ZERO,       // YUV_420_BIPLANAR
@@ -227,7 +227,7 @@
       GL_LUMINANCE,  // R16_EXT
       GL_RGB,        // RGBX_8888
       GL_RGB,        // BGRX_8888
-      GL_ZERO,       // RGBX_1010102
+      GL_ZERO,       // RGBA_1010102
       GL_ZERO,       // BGRX_1010102
       GL_ZERO,       // YVU_420
       GL_ZERO,       // YUV_420_BIPLANAR
@@ -262,8 +262,8 @@
       return gfx::BufferFormat::RGBX_8888;
     case BGRX_8888:
       return gfx::BufferFormat::BGRX_8888;
-    case RGBX_1010102:
-      return gfx::BufferFormat::RGBX_1010102;
+    case RGBA_1010102:
+      return gfx::BufferFormat::RGBA_1010102;
     case BGRX_1010102:
       return gfx::BufferFormat::BGRX_1010102;
     case YVU_420:
@@ -315,7 +315,7 @@
     case RGBX_8888:
     case ETC1:
       return GL_RGB8_OES;
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
       return GL_RGB10_A2_EXT;
     case BGR_565:
@@ -349,7 +349,7 @@
     case RG_88:
     case RGBX_8888:
     case BGRX_8888:
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
     case YVU_420:
     case YUV_420_BIPLANAR:
@@ -378,7 +378,7 @@
     case RG_88:
     case RGBX_8888:
     case BGRX_8888:
-    case RGBX_1010102:
+    case RGBA_1010102:
     case BGRX_1010102:
     case YVU_420:
     case YUV_420_BIPLANAR:
@@ -411,8 +411,8 @@
       return RGBX_8888;
     case gfx::BufferFormat::BGRX_8888:
       return BGRX_8888;
-    case gfx::BufferFormat::RGBX_1010102:
-      return RGBX_1010102;
+    case gfx::BufferFormat::RGBA_1010102:
+      return RGBA_1010102;
     case gfx::BufferFormat::BGRX_1010102:
       return BGRX_1010102;
     case gfx::BufferFormat::YVU_420:
@@ -465,7 +465,7 @@
       return VK_FORMAT_R8G8B8A8_UNORM;
     case BGRX_8888:
       return VK_FORMAT_B8G8R8A8_UNORM;
-    case RGBX_1010102:
+    case RGBA_1010102:
       return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
     case BGRX_1010102:
       return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
@@ -504,7 +504,7 @@
       return wgpu::TextureFormat::RG8Unorm;
     case RGBA_F16:
       return wgpu::TextureFormat::RGBA16Float;
-    case RGBX_1010102:
+    case RGBA_1010102:
       return wgpu::TextureFormat::RGB10A2Unorm;
     case RGBA_4444:
     case RGB_565:
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 1c7d0e62..f2345436 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -60,10 +60,10 @@
     "display/output_surface_frame.h",
     "display/overlay_candidate.cc",
     "display/overlay_candidate.h",
-    "display/overlay_candidate_list.cc",
-    "display/overlay_candidate_list.h",
     "display/overlay_processor_interface.cc",
     "display/overlay_processor_interface.h",
+    "display/overlay_processor_stub.cc",
+    "display/overlay_processor_stub.h",
     "display/program_binding.cc",
     "display/program_binding.h",
     "display/renderer_utils.cc",
@@ -251,17 +251,10 @@
     libs = [ "IOSurface.framework" ]
   }
 
-  if (is_linux || is_android || use_ozone) {
-    sources += [
-      "display/overlay_candidate_validator_strategy.cc",
-      "display/overlay_candidate_validator_strategy.h",
-      "display/overlay_processor_using_strategy.cc",
-      "display/overlay_processor_using_strategy.h",
-    ]
-  }
-
   if (is_android || use_ozone) {
     sources += [
+      "display/overlay_processor_using_strategy.cc",
+      "display/overlay_processor_using_strategy.h",
       "display/overlay_strategy_fullscreen.cc",
       "display/overlay_strategy_fullscreen.h",
       "display/overlay_strategy_single_on_top.cc",
@@ -277,10 +270,10 @@
     sources += [
       "display/overlay_processor_android.cc",
       "display/overlay_processor_android.h",
+      "display/overlay_processor_surface_control.cc",
+      "display/overlay_processor_surface_control.h",
       "display_embedder/gl_output_surface_android.cc",
       "display_embedder/gl_output_surface_android.h",
-      "display_embedder/overlay_candidate_validator_surface_control.cc",
-      "display_embedder/overlay_candidate_validator_surface_control.h",
       "frame_sinks/external_begin_frame_source_android.cc",
       "frame_sinks/external_begin_frame_source_android.h",
       "gl/throw_uncaught_exception.cc",
@@ -536,8 +529,8 @@
 
   if (is_android) {
     sources += [
+      "display/overlay_processor_surface_control_unittest.cc",
       "display/overlay_unittest.cc",
-      "display_embedder/overlay_candidate_validator_surface_control_unittest.cc",
       "frame_sinks/external_begin_frame_source_android_unittest.cc",
     ]
   }
diff --git a/components/viz/service/display/DEPS b/components/viz/service/display/DEPS
index 7c4078c..2e1e34bb 100644
--- a/components/viz/service/display/DEPS
+++ b/components/viz/service/display/DEPS
@@ -25,6 +25,7 @@
   "+third_party/skia",
   "+ui/latency",
   "+ui/gfx/video_types.h",
+  "+ui/gl/android/android_surface_control_compat.h",
   "+ui/gl/ca_renderer_layer_params.h",
   "+ui/gl/dc_renderer_layer_params.h",
   "+ui/gl/trace_util.h",
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc
index eeb2880..c4e744a 100644
--- a/components/viz/service/display/direct_renderer.cc
+++ b/components/viz/service/display/direct_renderer.cc
@@ -307,7 +307,7 @@
     output_surface_->Reshape(
         reshape_surface_size_, reshape_device_scale_factor_,
         reshape_device_color_space_, reshape_has_alpha_, reshape_use_stencil_);
-    overlay_processor_->SetValidatorViewportSize(reshape_surface_size_);
+    overlay_processor_->SetViewportSize(reshape_surface_size_);
     did_reshape = true;
   }
 
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h
index 6a44fc5d8..4b79c9de 100644
--- a/components/viz/service/display/direct_renderer.h
+++ b/components/viz/service/display/direct_renderer.h
@@ -15,7 +15,7 @@
 #include "build/build_config.h"
 #include "components/viz/common/quads/tile_draw_quad.h"
 #include "components/viz/service/display/display_resource_provider.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
+#include "components/viz/service/display/overlay_candidate.h"
 #include "components/viz/service/display/overlay_processor_interface.h"
 #include "components/viz/service/viz_service_export.h"
 #include "gpu/command_buffer/common/texture_in_use_response.h"
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc
index 90d05e2..ebf7465 100644
--- a/components/viz/service/display/gl_renderer_unittest.cc
+++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -53,13 +53,11 @@
 #elif defined(OS_MACOSX)
 #include "components/viz/service/display/overlay_processor_mac.h"
 #elif defined(OS_ANDROID) || defined(USE_OZONE)
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
 #include "components/viz/service/display/overlay_processor_using_strategy.h"
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
 #include "components/viz/service/display/overlay_strategy_underlay.h"
 #else  // Default
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
-#include "components/viz/service/display/overlay_processor_using_strategy.h"
+#include "components/viz/service/display/overlay_processor_stub.h"
 #endif
 
 using testing::_;
@@ -2282,30 +2280,15 @@
              OverlayCandidateList* candidates,
              std::vector<gfx::Rect>* content_bounds));
   };
-  class Validator : public OverlayCandidateValidatorStrategy {
-   public:
-    OverlayProcessorUsingStrategy::StrategyList InitializeStrategies(
-        OverlayProcessorUsingStrategy* processor) override {
-      OverlayProcessorUsingStrategy::StrategyList strategies;
-      return strategies;
-    }
 
-    MOCK_CONST_METHOD0(NeedsSurfaceOccludingDamageRect, bool());
+  bool IsOverlaySupported() const override { return true; }
 
-    // A list of possible overlay candidates is presented to this function.
-    // The expected result is that those candidates that can be in a separate
-    // plane are marked with |overlay_handled| set to true, otherwise they are
-    // to be traditionally composited. Candidates with |overlay_handled| set to
-    // true must also have their |display_rect| converted to integer
-    // coordinates if necessary.
-    void CheckOverlaySupport(const PrimaryPlane* primary_plane,
-                             OverlayCandidateList* surfaces) override {}
-  };
-
-  void InitializeStrategies() override {
-    strategies_.push_back(std::make_unique<Strategy>());
-  }
-
+  // A list of possible overlay candidates is presented to this function.
+  // The expected result is that those candidates that can be in a separate
+  // plane are marked with |overlay_handled| set to true, otherwise they are
+  // to be traditionally composited. Candidates with |overlay_handled| set to
+  // true must also have their |display_rect| converted to integer
+  // coordinates if necessary.
   void CheckOverlaySupport(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
       OverlayCandidateList* surfaces) override {}
@@ -2315,18 +2298,16 @@
     return *(static_cast<Strategy*>(strategy));
   }
 
-  TestOverlayProcessor()
-      : OverlayProcessorUsingStrategy(
-            nullptr,
-            std::make_unique<TestOverlayProcessor::Validator>()) {
-    InitializeStrategies();
+  MOCK_CONST_METHOD0(NeedsSurfaceOccludingDamageRect, bool());
+  TestOverlayProcessor() : OverlayProcessorUsingStrategy() {
+    strategies_.push_back(std::make_unique<Strategy>());
   }
   ~TestOverlayProcessor() override = default;
 };
 #else  // Default to no overlay.
-class TestOverlayProcessor : public OverlayProcessorUsingStrategy {
+class TestOverlayProcessor : public OverlayProcessorStub {
  public:
-  TestOverlayProcessor() : OverlayProcessorUsingStrategy(nullptr, nullptr) {}
+  TestOverlayProcessor() : OverlayProcessorStub() {}
   ~TestOverlayProcessor() override = default;
 };
 #endif
@@ -2480,18 +2461,13 @@
 #if defined(OS_ANDROID) || defined(USE_OZONE)
 class SingleOverlayOnTopProcessor : public OverlayProcessorUsingStrategy {
  public:
-  SingleOverlayOnTopProcessor()
-      : OverlayProcessorUsingStrategy(
-            nullptr,
-            std::unique_ptr<OverlayCandidateValidatorStrategy>()) {
-    InitializeStrategies();
-  }
-
-  void InitializeStrategies() override {
+  SingleOverlayOnTopProcessor() : OverlayProcessorUsingStrategy() {
     strategies_.push_back(std::make_unique<OverlayStrategySingleOnTop>(this));
     strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(this));
   }
+
   bool NeedsSurfaceOccludingDamageRect() const override { return true; }
+  bool IsOverlaySupported() const override { return true; }
 
   void CheckOverlaySupport(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
@@ -3103,14 +3079,7 @@
 
   explicit ContentBoundsOverlayProcessor(
       const std::vector<gfx::Rect>& content_bounds)
-      : OverlayProcessorUsingStrategy(
-            nullptr,
-            std::unique_ptr<OverlayCandidateValidatorStrategy>()),
-        content_bounds_(content_bounds) {
-    InitializeStrategies();
-  }
-
-  void InitializeStrategies() override {
+      : OverlayProcessorUsingStrategy(), content_bounds_(content_bounds) {
     strategies_.push_back(
         std::make_unique<Strategy>(std::move(content_bounds_)));
   }
@@ -3119,6 +3088,7 @@
   // Empty mock methods since this test set up uses strategies, which are only
   // for ozone and android.
   MOCK_CONST_METHOD0(NeedsSurfaceOccludingDamageRect, bool());
+  bool IsOverlaySupported() const override { return true; }
 
   // A list of possible overlay candidates is presented to this function.
   // The expected result is that those candidates that can be in a separate
diff --git a/components/viz/service/display/overlay_candidate.h b/components/viz/service/display/overlay_candidate.h
index 52d644a..65e5cd0 100644
--- a/components/viz/service/display/overlay_candidate.h
+++ b/components/viz/service/display/overlay_candidate.h
@@ -140,6 +140,8 @@
                                 OverlayCandidate* candidate);
 };
 
+using OverlayCandidateList = std::vector<OverlayCandidate>;
+
 }  // namespace viz
 
 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_H_
diff --git a/components/viz/service/display/overlay_candidate_list.cc b/components/viz/service/display/overlay_candidate_list.cc
deleted file mode 100644
index 262911c5..0000000
--- a/components/viz/service/display/overlay_candidate_list.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display/overlay_candidate_list.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "base/logging.h"
-#include "build/build_config.h"
-#include "cc/base/math_util.h"
-#include "components/viz/common/quads/stream_video_draw_quad.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/vector3d_f.h"
-#include "ui/gfx/video_types.h"
-
-namespace viz {
-
-OverlayCandidateList::OverlayCandidateList() = default;
-
-OverlayCandidateList::OverlayCandidateList(const OverlayCandidateList& other) =
-    default;
-
-OverlayCandidateList::OverlayCandidateList(OverlayCandidateList&& other) =
-    default;
-
-OverlayCandidateList::~OverlayCandidateList() = default;
-
-OverlayCandidateList& OverlayCandidateList::operator=(
-    const OverlayCandidateList& other) = default;
-
-OverlayCandidateList& OverlayCandidateList::operator=(
-    OverlayCandidateList&& other) = default;
-
-void OverlayCandidateList::AddPromotionHint(const OverlayCandidate& candidate) {
-  promotion_hint_info_map_[candidate.resource_id] = candidate.display_rect;
-}
-
-void OverlayCandidateList::AddToPromotionHintRequestorSetIfNeeded(
-    const DisplayResourceProvider* resource_provider,
-    const DrawQuad* quad) {
-  if (quad->material != DrawQuad::Material::kStreamVideoContent)
-    return;
-  ResourceId id = StreamVideoDrawQuad::MaterialCast(quad)->resource_id();
-  if (!resource_provider->DoesResourceWantPromotionHint(id))
-    return;
-  promotion_hint_requestor_set_.insert(id);
-}
-
-std::vector<std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>>
-OverlayCandidateList::ConvertLocalPromotionToMailboxKeyed(
-    DisplayResourceProvider* resource_provider,
-    base::flat_set<gpu::Mailbox>* promotion_denied,
-    base::flat_map<gpu::Mailbox, gfx::Rect>* possible_promotions) {
-  DCHECK(empty() || size() == 1u);
-  std::vector<
-      std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>>
-      locks;
-  for (auto& request : promotion_hint_requestor_set_) {
-    // If we successfully promote one candidate, then that promotion hint should
-    // be sent later when we schedule the overlay.
-    if (!empty() && front().resource_id == request)
-      continue;
-
-    locks.emplace_back(
-        std::make_unique<DisplayResourceProvider::ScopedReadLockSharedImage>(
-            resource_provider, request));
-    auto iter = promotion_hint_info_map_.find(request);
-    if (iter != promotion_hint_info_map_.end()) {
-      // This is a possible promotion.
-      possible_promotions->emplace(locks.back()->mailbox(),
-                                   gfx::ToEnclosedRect(iter->second));
-    } else {
-      promotion_denied->insert(locks.back()->mailbox());
-    }
-  }
-  return locks;
-}
-}  // namespace viz
diff --git a/components/viz/service/display/overlay_candidate_list.h b/components/viz/service/display/overlay_candidate_list.h
deleted file mode 100644
index 5c66ce9d0..0000000
--- a/components/viz/service/display/overlay_candidate_list.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_LIST_H_
-#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_LIST_H_
-
-#include <map>
-#include <vector>
-
-#include "base/containers/flat_map.h"
-#include "build/build_config.h"
-#include "components/viz/common/resources/resource_id.h"
-#include "components/viz/service/display/display_resource_provider.h"
-#include "components/viz/service/display/overlay_candidate.h"
-#include "components/viz/service/viz_service_export.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/overlay_transform.h"
-#include "ui/gfx/transform.h"
-
-namespace viz {
-// This class defines a list of overlay candidates with extra information about
-// Android Classic video overlay information.
-// TODO(weiliangc): Do not inherit std::vector.
-class VIZ_SERVICE_EXPORT OverlayCandidateList
-    : public std::vector<OverlayCandidate> {
- public:
-  OverlayCandidateList();
-  OverlayCandidateList(const OverlayCandidateList&);
-  OverlayCandidateList(OverlayCandidateList&&);
-  ~OverlayCandidateList();
-
-  OverlayCandidateList& operator=(const OverlayCandidateList&);
-  OverlayCandidateList& operator=(OverlayCandidateList&&);
-
-  // [id] == candidate's |display_rect| for all promotable resources.
-  using PromotionHintInfoMap = std::map<ResourceId, gfx::RectF>;
-
-  // For android, this provides a set of resources that could be promoted to
-  // overlay, if one backs them with a SurfaceView.
-  PromotionHintInfoMap promotion_hint_info_map_;
-
-  // Set of resources that have requested a promotion hint that also have quads
-  // that use them.
-  ResourceIdSet promotion_hint_requestor_set_;
-  // base::flat_set<DisplayResourceProvider::ScopedReadLockSharedImage>
-  //     promotion_requestors_shared_image_;
-
-  // Helper to insert |candidate| into |promotion_hint_info_|.
-  void AddPromotionHint(const OverlayCandidate& candidate);
-
-  // Add |quad| to |promotion_hint_requestors_| if it is requesting a hint.
-  void AddToPromotionHintRequestorSetIfNeeded(
-      const DisplayResourceProvider* resource_provider,
-      const DrawQuad* quad);
-
-  std::vector<
-      std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>>
-  ConvertLocalPromotionToMailboxKeyed(
-      DisplayResourceProvider* resource_provider,
-      base::flat_set<gpu::Mailbox>* promotion_denied,
-      base::flat_map<gpu::Mailbox, gfx::Rect>* possible_promotions);
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_LIST_H_
diff --git a/components/viz/service/display/overlay_candidate_validator_strategy.cc b/components/viz/service/display/overlay_candidate_validator_strategy.cc
deleted file mode 100644
index cb5220f..0000000
--- a/components/viz/service/display/overlay_candidate_validator_strategy.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "build/build_config.h"
-#include "components/viz/common/display/renderer_settings.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-#if defined(OS_ANDROID)
-#include "components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h"
-#include "gpu/config/gpu_feature_info.h"
-#endif
-
-namespace viz {
-std::unique_ptr<OverlayCandidateValidatorStrategy>
-OverlayCandidateValidatorStrategy::Create(
-    gpu::SurfaceHandle surface_handle,
-    const OutputSurface::Capabilities& capabilities,
-    const RendererSettings& renderer_settings) {
-  if (surface_handle == gpu::kNullSurfaceHandle)
-    return nullptr;
-
-#if defined(OS_ANDROID)
-  if (capabilities.supports_surfaceless) {
-    return std::make_unique<OverlayCandidateValidatorSurfaceControl>();
-  }
-  return nullptr;
-#else  // Default
-  return nullptr;
-#endif
-}
-
-gfx::Rect
-OverlayCandidateValidatorStrategy::GetOverlayDamageRectForOutputSurface(
-    const OverlayCandidate& candidate) const {
-  return ToEnclosedRect(candidate.display_rect);
-}
-
-OverlayCandidateValidatorStrategy::OverlayCandidateValidatorStrategy() =
-    default;
-OverlayCandidateValidatorStrategy::~OverlayCandidateValidatorStrategy() =
-    default;
-
-}  // namespace viz
diff --git a/components/viz/service/display/overlay_candidate_validator_strategy.h b/components/viz/service/display/overlay_candidate_validator_strategy.h
deleted file mode 100644
index d328085..0000000
--- a/components/viz/service/display/overlay_candidate_validator_strategy.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_VALIDATOR_STRATEGY_H_
-#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_VALIDATOR_STRATEGY_H_
-
-#include <vector>
-
-#include "components/viz/service/display/overlay_processor_using_strategy.h"
-
-namespace viz {
-class RendererSettings;
-
-// This class can be used to answer questions about possible overlay
-// configurations for a particular output device.
-// TODO(weiliangc): Its functionalities should be merged into subclass of
-// OverlayProcessor.
-class VIZ_SERVICE_EXPORT OverlayCandidateValidatorStrategy {
- public:
-  static std::unique_ptr<OverlayCandidateValidatorStrategy> Create(
-      gpu::SurfaceHandle surface_handle,
-      const OutputSurface::Capabilities& capabilities,
-      const RendererSettings& renderer_settings);
-
-  virtual ~OverlayCandidateValidatorStrategy();
-
-  // A primary plane is generated when the output surface's buffer is supplied
-  // by |BufferQueue|. This is considered as an overlay plane.
-  using PrimaryPlane = OverlayProcessorInterface::OutputSurfaceOverlayPlane;
-
-  // Populates a list of strategies that may work with this validator. Should be
-  // called at most once.
-  virtual OverlayProcessorUsingStrategy::StrategyList InitializeStrategies(
-      OverlayProcessorUsingStrategy* processor) = 0;
-
-  // A list of possible overlay candidates is presented to this function.
-  // The expected result is that those candidates that can be in a separate
-  // plane are marked with |overlay_handled| set to true, otherwise they are
-  // to be traditionally composited. Candidates with |overlay_handled| set to
-  // true must also have their |display_rect| converted to integer
-  // coordinates  in physical display coordinates if necessary. When the output
-  // surface uses a buffer from |BufferQueue|, it generates a |primary_plane|.
-  // The |primary_plane| is always handled, but its information needs to be
-  // passed to the hardware overlay system though this function.
-  virtual void CheckOverlaySupport(const PrimaryPlane* primary_plane,
-                                   OverlayCandidateList* surfaces) = 0;
-
-  // Returns the overlay damage rect covering the main plane rendered by the
-  // OutputSurface. This rect is in the same space where the OutputSurface
-  // renders the content for the main plane, including the display transform if
-  // needed. Should only be called after the overlays are processed.
-  virtual gfx::Rect GetOverlayDamageRectForOutputSurface(
-      const OverlayCandidate& candidate) const;
-
-  // Returns true if the platform supports hw overlays and surface occluding
-  // damage rect needs to be computed since it will be used by overlay
-  // processor.
-  virtual bool NeedsSurfaceOccludingDamageRect() const = 0;
-
-  // Set the overlay display transform and viewport size. Value only used for
-  // Android Surface Control.
-  virtual void SetDisplayTransform(gfx::OverlayTransform transform) {}
-  virtual void SetViewportSize(const gfx::Size& size) {}
-
-  // This is used to adjust properties of the |primary_plane|, which is the
-  // overlay candidate for the output surface. This is called after we process
-  // for overlay. Surface Control uses this function to adjust the display
-  // transform and display rect.
-  virtual void AdjustOutputSurfaceOverlay(PrimaryPlane* output_surface_plane) {}
-
- protected:
-  OverlayCandidateValidatorStrategy();
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_VALIDATOR_STRATEGY_H_
diff --git a/components/viz/service/display/overlay_processor_android.cc b/components/viz/service/display/overlay_processor_android.cc
index 55b3022..5507760a 100644
--- a/components/viz/service/display/overlay_processor_android.cc
+++ b/components/viz/service/display/overlay_processor_android.cc
@@ -4,38 +4,34 @@
 
 #include "components/viz/service/display/overlay_processor_android.h"
 
-#include "components/viz/service/display/overlay_candidate_list.h"
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
+#include "components/viz/common/quads/stream_video_draw_quad.h"
+#include "components/viz/service/display/display_resource_provider.h"
 #include "components/viz/service/display/overlay_strategy_underlay.h"
+#include "components/viz/service/display/skia_output_surface.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
 namespace viz {
-
 OverlayProcessorAndroid::OverlayProcessorAndroid(
     SkiaOutputSurface* skia_output_surface,
     bool enable_overlay)
-    : OverlayProcessorUsingStrategy(
-          skia_output_surface,
-          std::unique_ptr<OverlayCandidateValidatorStrategy>()),
+    : OverlayProcessorUsingStrategy(),
+      skia_output_surface_(skia_output_surface),
       overlay_enabled_(enable_overlay) {
-  if (overlay_enabled_)
-    InitializeStrategies();
+  if (overlay_enabled_) {
+    // For Android, we do not have the ability to skip an overlay, since the
+    // texture is already in a SurfaceView.  Ideally, we would honor a 'force
+    // overlay' flag that FromDrawQuad would also check.
+    // For now, though, just skip the opacity check.  We really have no idea if
+    // the underlying overlay is opaque anyway; the candidate is referring to
+    // a dummy resource that has no relation to what the overlay contains.
+    // https://crbug.com/842931 .
+    strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(
+        this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
+  }
 }
 
 OverlayProcessorAndroid::~OverlayProcessorAndroid() {}
 
-void OverlayProcessorAndroid::InitializeStrategies() {
-  // For Android, we do not have the ability to skip an overlay, since the
-  // texture is already in a SurfaceView.  Ideally, we would honor a 'force
-  // overlay' flag that FromDrawQuad would also check.
-  // For now, though, just skip the opacity check.  We really have no idea if
-  // the underlying overlay is opaque anyway; the candidate is referring to
-  // a dummy resource that has no relation to what the overlay contains.
-  // https://crbug.com/842931 .
-  strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(
-      this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
-}
-
 bool OverlayProcessorAndroid::IsOverlaySupported() const {
   return overlay_enabled_;
 }
@@ -47,6 +43,10 @@
 void OverlayProcessorAndroid::CheckOverlaySupport(
     const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
     OverlayCandidateList* candidates) {
+  // For pre-SurfaceControl Android we should not have output surface as overlay
+  // plane.
+  DCHECK(!primary_plane);
+
   // There should only be at most a single overlay candidate: the
   // video quad.
   // There's no check that the presented candidate is really a video frame for
@@ -59,7 +59,7 @@
 
     // This quad either will be promoted, or would be if it were backed by a
     // SurfaceView.  Record that it should get a promotion hint.
-    candidates->AddPromotionHint(candidate);
+    promotion_hint_info_map_[candidate.resource_id] = candidate.display_rect;
 
     if (candidate.is_backed_by_surface_texture) {
       // This quad would be promoted if it were backed by a SurfaceView.  Since
@@ -71,6 +71,13 @@
         gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
     candidate.overlay_handled = true;
     candidate.plane_z_order = -1;
+
+    // This quad will be promoted.  We clear the promotable hints here, since
+    // we can only promote a single quad.  Otherwise, somebody might try to
+    // back one of the promotable quads with a SurfaceView, and either it or
+    // |candidate| would have to fall back to a texture.
+    promotion_hint_info_map_.clear();
+    promotion_hint_info_map_[candidate.resource_id] = candidate.display_rect;
   }
 }
 gfx::Rect OverlayProcessorAndroid::GetOverlayDamageRectForOutputSurface(
@@ -78,4 +85,76 @@
   return ToEnclosedRect(overlay.display_rect);
 }
 
+void OverlayProcessorAndroid::NotifyOverlayPromotion(
+    DisplayResourceProvider* resource_provider,
+    const CandidateList& candidates,
+    const QuadList& quad_list) {
+  // No need to notify overlay promotion if not any resource wants promotion
+  // hints.
+  if (!resource_provider->DoAnyResourcesWantPromotionHints())
+    return;
+
+  // |promotion_hint_requestor_set_| is calculated here, so it should be empty
+  // to begin with.
+  DCHECK(promotion_hint_requestor_set_.empty());
+
+  for (auto* quad : quad_list) {
+    if (quad->material != DrawQuad::Material::kStreamVideoContent)
+      continue;
+    ResourceId id = StreamVideoDrawQuad::MaterialCast(quad)->resource_id();
+    if (!resource_provider->DoesResourceWantPromotionHint(id))
+      continue;
+    promotion_hint_requestor_set_.insert(id);
+  }
+
+  if (skia_output_surface_) {
+    NotifyOverlayPromotionUsingSkiaOutputSurface(resource_provider, candidates);
+  } else {
+    resource_provider->SendPromotionHints(promotion_hint_info_map_,
+                                          promotion_hint_requestor_set_);
+  }
+  promotion_hint_info_map_.clear();
+  promotion_hint_requestor_set_.clear();
+}
+
+void OverlayProcessorAndroid::NotifyOverlayPromotionUsingSkiaOutputSurface(
+    DisplayResourceProvider* resource_provider,
+    const OverlayCandidateList& candidate_list) {
+  base::flat_set<gpu::Mailbox> promotion_denied;
+  base::flat_map<gpu::Mailbox, gfx::Rect> possible_promotions;
+
+  DCHECK(candidate_list.empty() || candidate_list.size() == 1u);
+
+  std::vector<
+      std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>>
+      locks;
+  for (auto& request : promotion_hint_requestor_set_) {
+    // If we successfully promote one candidate, then that promotion hint
+    // should be sent later when we schedule the overlay.
+    if (!candidate_list.empty() &&
+        candidate_list.front().resource_id == request)
+      continue;
+
+    locks.emplace_back(
+        std::make_unique<DisplayResourceProvider::ScopedReadLockSharedImage>(
+            resource_provider, request));
+    auto iter = promotion_hint_info_map_.find(request);
+    if (iter != promotion_hint_info_map_.end()) {
+      // This is a possible promotion.
+      possible_promotions.emplace(locks.back()->mailbox(),
+                                  gfx::ToEnclosedRect(iter->second));
+    } else {
+      promotion_denied.insert(locks.back()->mailbox());
+    }
+  }
+
+  std::vector<gpu::SyncToken> locks_sync_tokens;
+  for (auto& read_lock : locks)
+    locks_sync_tokens.push_back(read_lock->sync_token());
+
+  skia_output_surface_->SendOverlayPromotionNotification(
+      std::move(locks_sync_tokens), std::move(promotion_denied),
+      std::move(possible_promotions));
+}
+
 }  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_android.h b/components/viz/service/display/overlay_processor_android.h
index f1dd42f..3bfa77f 100644
--- a/components/viz/service/display/overlay_processor_android.h
+++ b/components/viz/service/display/overlay_processor_android.h
@@ -24,7 +24,6 @@
   OverlayProcessorAndroid(SkiaOutputSurface* skia_output_surface,
                           bool enable_overlay);
   ~OverlayProcessorAndroid() override;
-  void InitializeStrategies() override;
 
   bool IsOverlaySupported() const override;
 
@@ -32,7 +31,7 @@
 
   // Override OverlayProcessorUsingStrategy.
   void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
-  void SetValidatorViewportSize(const gfx::Size& size) override {}
+  void SetViewportSize(const gfx::Size& size) override {}
 
   void CheckOverlaySupport(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
@@ -41,7 +40,27 @@
       const OverlayCandidate& overlay) const override;
 
  private:
+  void NotifyOverlayPromotion(DisplayResourceProvider* resource_provider,
+                              const OverlayCandidateList& candidate_list,
+                              const QuadList& quad_list) override;
+
+  SkiaOutputSurface* const skia_output_surface_;
   const bool overlay_enabled_;
+
+  // [id] == candidate's |display_rect| for all promotable resources.
+  using PromotionHintInfoMap = std::map<ResourceId, gfx::RectF>;
+
+  // For android, this provides a set of resources that could be promoted to
+  // overlay, if one backs them with a SurfaceView.
+  PromotionHintInfoMap promotion_hint_info_map_;
+
+  // Set of resources that have requested a promotion hint that also have quads
+  // that use them.
+  ResourceIdSet promotion_hint_requestor_set_;
+
+  void NotifyOverlayPromotionUsingSkiaOutputSurface(
+      DisplayResourceProvider* resource_provider,
+      const OverlayCandidateList& candidate_list);
 };
 }  // namespace viz
 
diff --git a/components/viz/service/display/overlay_processor_interface.cc b/components/viz/service/display/overlay_processor_interface.cc
index 4e46b204d..4144595 100644
--- a/components/viz/service/display/overlay_processor_interface.cc
+++ b/components/viz/service/display/overlay_processor_interface.cc
@@ -12,16 +12,14 @@
 #elif defined(OS_WIN)
 #include "components/viz/service/display/overlay_processor_win.h"
 #elif defined(OS_ANDROID)
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
 #include "components/viz/service/display/overlay_processor_android.h"
-#include "components/viz/service/display/overlay_processor_using_strategy.h"
+#include "components/viz/service/display/overlay_processor_surface_control.h"
 #elif defined(USE_OZONE)
 #include "components/viz/service/display/overlay_processor_ozone.h"
 #include "ui/ozone/public/overlay_manager_ozone.h"
 #include "ui/ozone/public/ozone_platform.h"
 #else
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
-#include "components/viz/service/display/overlay_processor_using_strategy.h"
+#include "components/viz/service/display/overlay_processor_stub.h"
 #endif
 
 namespace viz {
@@ -110,10 +108,8 @@
 #elif defined(OS_ANDROID)
   if (capabilities.supports_surfaceless) {
     // This is for Android SurfaceControl case.
-    auto validator = OverlayCandidateValidatorStrategy::Create(
-        surface_handle, capabilities, renderer_settings);
-    return base::WrapUnique(new OverlayProcessorUsingStrategy(
-        skia_output_surface, std::move(validator)));
+    bool overlay_enabled = surface_handle != gpu::kNullSurfaceHandle;
+    return std::make_unique<OverlayProcessorSurfaceControl>(overlay_enabled);
   } else {
     bool overlay_enabled = surface_handle != gpu::kNullSurfaceHandle;
     // When SurfaceControl is enabled, any resource backed by an
@@ -127,12 +123,7 @@
                                                      overlay_enabled);
   }
 #else  // Default
-  // TODO(weiliangc): Add a stub class for the default case for platforms where
-  // we could not overlay.
-  auto validator = OverlayCandidateValidatorStrategy::Create(
-      surface_handle, capabilities, renderer_settings);
-  return base::WrapUnique(new OverlayProcessorUsingStrategy(
-      skia_output_surface, std::move(validator)));
+  return std::make_unique<OverlayProcessorStub>();
 #endif
 }
 
diff --git a/components/viz/service/display/overlay_processor_interface.h b/components/viz/service/display/overlay_processor_interface.h
index 1c4f6aa..149b2094 100644
--- a/components/viz/service/display/overlay_processor_interface.h
+++ b/components/viz/service/display/overlay_processor_interface.h
@@ -30,7 +30,6 @@
 
 namespace viz {
 class OutputSurface;
-class OverlayCandidateList;
 class RendererSettings;
 
 // This class is called inside the DirectRenderer to separate the contents that
@@ -129,7 +128,7 @@
 
   // These two functions are used by Android SurfaceControl.
   virtual void SetDisplayTransformHint(gfx::OverlayTransform transform) {}
-  virtual void SetValidatorViewportSize(const gfx::Size& size) {}
+  virtual void SetViewportSize(const gfx::Size& size) {}
 
  protected:
   OverlayProcessorInterface() {}
diff --git a/components/viz/service/display/overlay_processor_mac.cc b/components/viz/service/display/overlay_processor_mac.cc
index 9aae73aa..62ca44d 100644
--- a/components/viz/service/display/overlay_processor_mac.cc
+++ b/components/viz/service/display/overlay_processor_mac.cc
@@ -11,7 +11,6 @@
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/service/display/display_resource_provider.h"
 #include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
 namespace viz {
diff --git a/components/viz/service/display/overlay_processor_ozone.cc b/components/viz/service/display/overlay_processor_ozone.cc
index 19d07de..2a86b3e 100644
--- a/components/viz/service/display/overlay_processor_ozone.cc
+++ b/components/viz/service/display/overlay_processor_ozone.cc
@@ -4,7 +4,6 @@
 
 #include "components/viz/service/display/overlay_processor_ozone.h"
 
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "components/viz/service/display/overlay_strategy_fullscreen.h"
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
 #include "components/viz/service/display/overlay_strategy_underlay.h"
@@ -55,42 +54,38 @@
     bool overlay_enabled,
     std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
     std::vector<OverlayStrategy> available_strategies)
-    : OverlayProcessorUsingStrategy(
-          nullptr,
-          std::unique_ptr<OverlayCandidateValidatorStrategy>()),
+    : OverlayProcessorUsingStrategy(),
       overlay_enabled_(overlay_enabled),
       overlay_candidates_(std::move(overlay_candidates)),
       available_strategies_(std::move(available_strategies)) {
-  if (overlay_enabled_)
-    InitializeStrategies();
-}
-
-OverlayProcessorOzone::~OverlayProcessorOzone() = default;
-
-void OverlayProcessorOzone::InitializeStrategies() {
-  for (OverlayStrategy strategy : available_strategies_) {
-    switch (strategy) {
-      case OverlayStrategy::kFullscreen:
-        strategies_.push_back(
-            std::make_unique<OverlayStrategyFullscreen>(this));
-        break;
-      case OverlayStrategy::kSingleOnTop:
-        strategies_.push_back(
-            std::make_unique<OverlayStrategySingleOnTop>(this));
-        break;
-      case OverlayStrategy::kUnderlay:
-        strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(this));
-        break;
-      case OverlayStrategy::kUnderlayCast:
-        strategies_.push_back(
-            std::make_unique<OverlayStrategyUnderlayCast>(this));
-        break;
-      default:
-        NOTREACHED();
+  if (overlay_enabled_) {
+    for (OverlayStrategy strategy : available_strategies_) {
+      switch (strategy) {
+        case OverlayStrategy::kFullscreen:
+          strategies_.push_back(
+              std::make_unique<OverlayStrategyFullscreen>(this));
+          break;
+        case OverlayStrategy::kSingleOnTop:
+          strategies_.push_back(
+              std::make_unique<OverlayStrategySingleOnTop>(this));
+          break;
+        case OverlayStrategy::kUnderlay:
+          strategies_.push_back(
+              std::make_unique<OverlayStrategyUnderlay>(this));
+          break;
+        case OverlayStrategy::kUnderlayCast:
+          strategies_.push_back(
+              std::make_unique<OverlayStrategyUnderlayCast>(this));
+          break;
+        default:
+          NOTREACHED();
+      }
     }
   }
 }
 
+OverlayProcessorOzone::~OverlayProcessorOzone() = default;
+
 bool OverlayProcessorOzone::IsOverlaySupported() const {
   return overlay_enabled_;
 }
diff --git a/components/viz/service/display/overlay_processor_ozone.h b/components/viz/service/display/overlay_processor_ozone.h
index 9f272ae..747987a 100644
--- a/components/viz/service/display/overlay_processor_ozone.h
+++ b/components/viz/service/display/overlay_processor_ozone.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_OZONE_H_
 #define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_OZONE_H_
 
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
+#include "components/viz/service/display/overlay_processor_using_strategy.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/public/overlay_candidates_ozone.h"
 
@@ -19,7 +19,6 @@
       std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
       std::vector<OverlayStrategy> available_strategies);
   ~OverlayProcessorOzone() override;
-  void InitializeStrategies() override;
 
   bool IsOverlaySupported() const override;
 
@@ -27,13 +26,13 @@
 
   // Override OverlayProcessorUsingStrategy.
   void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
-  void SetValidatorViewportSize(const gfx::Size& size) override {}
+  void SetViewportSize(const gfx::Size& size) override {}
 
   void CheckOverlaySupport(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
       OverlayCandidateList* surfaces) override;
   gfx::Rect GetOverlayDamageRectForOutputSurface(
-      const OverlayCandidate& overlay) const override;
+      const OverlayCandidate& candidate) const override;
 
  private:
   const bool overlay_enabled_;
diff --git a/components/viz/service/display/overlay_processor_stub.cc b/components/viz/service/display/overlay_processor_stub.cc
new file mode 100644
index 0000000..7990838
--- /dev/null
+++ b/components/viz/service/display/overlay_processor_stub.cc
@@ -0,0 +1,18 @@
+// 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 "components/viz/service/display/overlay_processor_stub.h"
+
+namespace viz {
+bool OverlayProcessorStub::IsOverlaySupported() const {
+  return false;
+}
+gfx::Rect OverlayProcessorStub::GetAndResetOverlayDamage() {
+  return gfx::Rect();
+}
+bool OverlayProcessorStub::NeedsSurfaceOccludingDamageRect() const {
+  return false;
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_stub.h b/components/viz/service/display/overlay_processor_stub.h
new file mode 100644
index 0000000..92069a7
--- /dev/null
+++ b/components/viz/service/display/overlay_processor_stub.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_STUB_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_STUB_H_
+
+#include "components/viz/service/display/overlay_processor_interface.h"
+
+namespace viz {
+// This is a stub class that implements OverlayProcessorInterface that is used
+// for platforms that don't support overlays.
+class VIZ_SERVICE_EXPORT OverlayProcessorStub
+    : public OverlayProcessorInterface {
+ public:
+  OverlayProcessorStub() : OverlayProcessorInterface() {}
+  ~OverlayProcessorStub() override {}
+
+  // Overrides OverlayProcessorInterface's pure virtual functions.
+  bool IsOverlaySupported() const final;
+  gfx::Rect GetAndResetOverlayDamage() final;
+  bool NeedsSurfaceOccludingDamageRect() const final;
+  void ProcessForOverlays(
+      DisplayResourceProvider* resource_provider,
+      RenderPassList* render_passes,
+      const SkMatrix44& output_color_matrix,
+      const FilterOperationsMap& render_pass_filters,
+      const FilterOperationsMap& render_pass_backdrop_filters,
+      OutputSurfaceOverlayPlane* output_surface_plane,
+      CandidateList* overlay_candidates,
+      gfx::Rect* damage_rect,
+      std::vector<gfx::Rect>* content_bounds) final {}
+  void AdjustOutputSurfaceOverlay(
+      base::Optional<OutputSurfaceOverlayPlane>* output_surface_plane) final {}
+  void SetDisplayTransformHint(gfx::OverlayTransform transform) final {}
+  void SetViewportSize(const gfx::Size& size) final {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(OverlayProcessorStub);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_STUB_H_
diff --git a/components/viz/service/display/overlay_processor_surface_control.cc b/components/viz/service/display/overlay_processor_surface_control.cc
new file mode 100644
index 0000000..187af48c
--- /dev/null
+++ b/components/viz/service/display/overlay_processor_surface_control.cc
@@ -0,0 +1,150 @@
+// 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 "components/viz/service/display/overlay_processor_surface_control.h"
+
+#include "components/viz/service/display/overlay_strategy_underlay.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/overlay_transform_utils.h"
+#include "ui/gl/android/android_surface_control_compat.h"
+
+namespace viz {
+namespace {
+
+gfx::RectF ClipFromOrigin(gfx::RectF input) {
+  if (input.x() < 0.f) {
+    input.set_width(input.width() + input.x());
+    input.set_x(0.f);
+  }
+
+  if (input.y() < 0) {
+    input.set_height(input.height() + input.y());
+    input.set_y(0.f);
+  }
+
+  return input;
+}
+
+}  // namespace
+
+OverlayProcessorSurfaceControl::OverlayProcessorSurfaceControl(
+    bool enable_overlay)
+    : OverlayProcessorUsingStrategy(), overlay_enabled_(enable_overlay) {
+  if (overlay_enabled_) {
+    strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(
+        this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
+  }
+}
+
+OverlayProcessorSurfaceControl::~OverlayProcessorSurfaceControl() {}
+
+bool OverlayProcessorSurfaceControl::IsOverlaySupported() const {
+  return overlay_enabled_;
+}
+
+bool OverlayProcessorSurfaceControl::NeedsSurfaceOccludingDamageRect() const {
+  return true;
+}
+
+void OverlayProcessorSurfaceControl::CheckOverlaySupport(
+    const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
+    OverlayCandidateList* candidates) {
+  DCHECK(!candidates->empty());
+
+  for (auto& candidate : *candidates) {
+    if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) {
+      candidate.overlay_handled = false;
+      return;
+    }
+
+    // Check if screen rotation matches.
+    if (candidate.transform != display_transform_) {
+      candidate.overlay_handled = false;
+      return;
+    }
+    candidate.transform = gfx::OVERLAY_TRANSFORM_NONE;
+
+    gfx::RectF orig_display_rect = candidate.display_rect;
+    gfx::RectF display_rect = orig_display_rect;
+    if (candidate.is_clipped)
+      display_rect.Intersect(gfx::RectF(candidate.clip_rect));
+    // The framework doesn't support display rects positioned at a negative
+    // offset.
+    display_rect = ClipFromOrigin(display_rect);
+    if (display_rect.IsEmpty()) {
+      candidate.overlay_handled = false;
+      return;
+    }
+
+    // The display rect above includes the |display_transform_| while the rects
+    // sent to the platform API need to be in the logical screen space.
+    const gfx::Transform display_inverse = gfx::OverlayTransformToTransform(
+        gfx::InvertOverlayTransform(display_transform_),
+        gfx::SizeF(viewport_size_));
+    display_inverse.TransformRect(&orig_display_rect);
+    display_inverse.TransformRect(&display_rect);
+
+    candidate.display_rect = gfx::RectF(gfx::ToEnclosingRect(display_rect));
+    candidate.uv_rect = cc::MathUtil::ScaleRectProportional(
+        candidate.uv_rect, orig_display_rect, candidate.display_rect);
+    candidate.overlay_handled = true;
+  }
+}
+
+void OverlayProcessorSurfaceControl::AdjustOutputSurfaceOverlay(
+    base::Optional<OutputSurfaceOverlayPlane>* output_surface_plane) {
+  // For surface control, we should always have a valid |output_surface_plane|
+  // here.
+  DCHECK(output_surface_plane && output_surface_plane->has_value());
+
+  OutputSurfaceOverlayPlane& plane = output_surface_plane->value();
+  DCHECK(gl::SurfaceControl::SupportsColorSpace(plane.color_space))
+      << "The main overlay must only use color space supported by the "
+         "device";
+
+  DCHECK_EQ(plane.transform, gfx::OVERLAY_TRANSFORM_NONE);
+  DCHECK(plane.display_rect == ClipFromOrigin(plane.display_rect));
+
+  plane.transform = display_transform_;
+  const gfx::Transform display_inverse = gfx::OverlayTransformToTransform(
+      gfx::InvertOverlayTransform(display_transform_),
+      gfx::SizeF(viewport_size_));
+  display_inverse.TransformRect(&plane.display_rect);
+  plane.display_rect = gfx::RectF(gfx::ToEnclosingRect(plane.display_rect));
+
+  // Call the base class implementation.
+  OverlayProcessorUsingStrategy::AdjustOutputSurfaceOverlay(
+      output_surface_plane);
+}
+
+gfx::Rect OverlayProcessorSurfaceControl::GetOverlayDamageRectForOutputSurface(
+    const OverlayCandidate& candidate) const {
+  // Should only be called after ProcessForOverlays on handled candidates.
+  DCHECK(candidate.overlay_handled);
+  // We transform the candidate's display rect to the logical screen space (used
+  // by the ui when preparing the frame) that the SurfaceControl expects it to
+  // be in. So in order to provide a damage rect which maps to the
+  // OutputSurface's main plane, we need to undo that transformation. But only
+  // if the overlay is in handled state, since the modification above is only
+  // applied when we mark the overlay as handled.
+  gfx::Size viewport_size_pre_display_transform(viewport_size_.height(),
+                                                viewport_size_.width());
+  auto transform = gfx::OverlayTransformToTransform(
+      display_transform_, gfx::SizeF(viewport_size_pre_display_transform));
+  gfx::RectF transformed_rect(candidate.display_rect);
+  transform.TransformRect(&transformed_rect);
+  return gfx::ToEnclosedRect(transformed_rect);
+}
+
+void OverlayProcessorSurfaceControl::SetDisplayTransformHint(
+    gfx::OverlayTransform transform) {
+  display_transform_ = transform;
+}
+
+void OverlayProcessorSurfaceControl::SetViewportSize(
+    const gfx::Size& viewport_size) {
+  viewport_size_ = viewport_size;
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_surface_control.h b/components/viz/service/display/overlay_processor_surface_control.h
new file mode 100644
index 0000000..59be65e
--- /dev/null
+++ b/components/viz/service/display/overlay_processor_surface_control.h
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_SURFACE_CONTROL_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_SURFACE_CONTROL_H_
+
+#include "components/viz/service/display/overlay_processor_using_strategy.h"
+
+namespace viz {
+
+// This is an overlay processor implementation for Android SurfaceControl.
+class VIZ_SERVICE_EXPORT OverlayProcessorSurfaceControl
+    : public OverlayProcessorUsingStrategy {
+ public:
+  explicit OverlayProcessorSurfaceControl(bool enable_overlay);
+  ~OverlayProcessorSurfaceControl() override;
+
+  bool IsOverlaySupported() const override;
+
+  bool NeedsSurfaceOccludingDamageRect() const override;
+
+  // Override OverlayProcessorUsingStrategy.
+  void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
+  void SetViewportSize(const gfx::Size& size) override;
+  void AdjustOutputSurfaceOverlay(
+      base::Optional<OutputSurfaceOverlayPlane>* output_surface_plane) override;
+  void CheckOverlaySupport(
+      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
+      OverlayCandidateList* candidates) override;
+  gfx::Rect GetOverlayDamageRectForOutputSurface(
+      const OverlayCandidate& overlay) const override;
+
+ private:
+  const bool overlay_enabled_;
+  gfx::OverlayTransform display_transform_ = gfx::OVERLAY_TRANSFORM_NONE;
+  gfx::Size viewport_size_;
+};
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_SURFACE_CONTROL_H_
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control_unittest.cc b/components/viz/service/display/overlay_processor_surface_control_unittest.cc
similarity index 66%
rename from components/viz/service/display_embedder/overlay_candidate_validator_surface_control_unittest.cc
rename to components/viz/service/display/overlay_processor_surface_control_unittest.cc
index 3764640..960abca 100644
--- a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control_unittest.cc
+++ b/components/viz/service/display/overlay_processor_surface_control_unittest.cc
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h"
+#include "components/viz/service/display/overlay_processor_surface_control.h"
 
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/test/gfx_util.h"
 
@@ -21,13 +20,13 @@
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.at(0).overlay_handled);
   EXPECT_RECTF_EQ(candidates.at(0).display_rect, gfx::RectF(10.f, 10.f));
 }
 
-TEST(OverlayCandidateValidatorSurfaceControlTest, Clipped) {
+TEST(OverlayProcessorSurfaceControlTest, Clipped) {
   OverlayCandidate candidate;
   candidate.display_rect = gfx::RectF(10.f, 10.f);
   candidate.uv_rect = gfx::RectF(1.f, 1.f);
@@ -38,15 +37,15 @@
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.at(0).overlay_handled);
   EXPECT_RECTF_EQ(candidates.at(0).display_rect,
                   gfx::RectF(2.f, 2.f, 5.f, 5.f));
   EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.2f, 0.2f, 0.5f, 0.5f));
 }
 
-TEST(OverlayCandidateValidatorSurfaceControlTest, NegativeOffset) {
+TEST(OverlayProcessorSurfaceControlTest, NegativeOffset) {
   OverlayCandidate candidate;
   candidate.display_rect = gfx::RectF(-2.f, -4.f, 10.f, 10.f);
   candidate.uv_rect = gfx::RectF(0.5f, 0.5f);
@@ -57,15 +56,15 @@
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.at(0).overlay_handled);
   EXPECT_RECTF_EQ(candidates.at(0).display_rect,
                   gfx::RectF(0.f, 0.f, 8.f, 6.f));
   EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.1f, 0.2f, 0.4f, 0.3f));
 }
 
-TEST(OverlayCandidateValidatorSurfaceControlTest, ClipAndNegativeOffset) {
+TEST(OverlayProcessorSurfaceControlTest, ClipAndNegativeOffset) {
   OverlayCandidate candidate;
   candidate.display_rect = gfx::RectF(-5.0f, -5.0f, 10.0f, 10.0f);
   candidate.uv_rect = gfx::RectF(0.5f, 0.5f, 0.5f, 0.5f);
@@ -76,8 +75,8 @@
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.at(0).overlay_handled);
   EXPECT_RECTF_EQ(candidates.at(0).display_rect,
                   gfx::RectF(0.f, 0.f, 5.f, 5.f));
@@ -85,7 +84,7 @@
                   gfx::RectF(0.75f, 0.75f, 0.25f, 0.25f));
 }
 
-TEST(OverlayCandidateValidatorSurfaceControlTest, DisplayTransformOverlay) {
+TEST(OverlayProcessorSurfaceControlTest, DisplayTransformOverlay) {
   OverlayCandidate candidate;
   candidate.display_rect = gfx::RectF(10, 10, 50, 100);
   candidate.overlay_handled = false;
@@ -93,35 +92,36 @@
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.SetViewportSize(gfx::Size(100, 200));
-  validator.SetDisplayTransform(gfx::OVERLAY_TRANSFORM_ROTATE_90);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.SetViewportSize(gfx::Size(100, 200));
+  processor.SetDisplayTransformHint(gfx::OVERLAY_TRANSFORM_ROTATE_90);
 
   // First use a different transform than the display transform, the overlay is
   // rejected.
   candidates.back().transform = gfx::OVERLAY_TRANSFORM_NONE;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_FALSE(candidates.back().overlay_handled);
 
   candidates.back().transform = gfx::OVERLAY_TRANSFORM_ROTATE_90;
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.back().overlay_handled);
   EXPECT_EQ(candidates.back().transform, gfx::OVERLAY_TRANSFORM_NONE);
   EXPECT_RECTF_EQ(candidates.back().display_rect, gfx::RectF(10, 40, 100, 50));
 }
 
-TEST(OverlayCandidateValidatorSurfaceControlTest,
-     DisplayTransformOutputSurfaceOverlay) {
+TEST(OverlayProcessorSurfaceControlTest, DisplayTransformOutputSurfaceOverlay) {
   OverlayProcessorInterface::OutputSurfaceOverlayPlane candidate;
   candidate.display_rect = gfx::RectF(100, 200);
   candidate.transform = gfx::OVERLAY_TRANSFORM_NONE;
+  base::Optional<OverlayProcessorInterface::OutputSurfaceOverlayPlane>
+      overlay_plane = candidate;
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.SetViewportSize(gfx::Size(100, 200));
-  validator.SetDisplayTransform(gfx::OVERLAY_TRANSFORM_ROTATE_90);
-  validator.AdjustOutputSurfaceOverlay(&candidate);
-  EXPECT_RECTF_EQ(candidate.display_rect, gfx::RectF(200, 100));
-  EXPECT_EQ(candidate.transform, gfx::OVERLAY_TRANSFORM_ROTATE_90);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.SetViewportSize(gfx::Size(100, 200));
+  processor.SetDisplayTransformHint(gfx::OVERLAY_TRANSFORM_ROTATE_90);
+  processor.AdjustOutputSurfaceOverlay(&overlay_plane);
+  EXPECT_RECTF_EQ(overlay_plane.value().display_rect, gfx::RectF(200, 100));
+  EXPECT_EQ(overlay_plane.value().transform, gfx::OVERLAY_TRANSFORM_ROTATE_90);
 }
 
 TEST(OverlayCandidateValidatorTest, OverlayDamageRectForOutputSurface) {
@@ -130,16 +130,16 @@
   candidate.transform = gfx::OVERLAY_TRANSFORM_ROTATE_90;
   candidate.overlay_handled = false;
 
-  OverlayCandidateValidatorSurfaceControl validator;
-  validator.SetViewportSize(gfx::Size(100, 200));
-  validator.SetDisplayTransform(gfx::OVERLAY_TRANSFORM_ROTATE_90);
+  OverlayProcessorSurfaceControl processor(true);
+  processor.SetViewportSize(gfx::Size(100, 200));
+  processor.SetDisplayTransformHint(gfx::OVERLAY_TRANSFORM_ROTATE_90);
 
   OverlayCandidateList candidates;
   candidates.push_back(candidate);
-  validator.CheckOverlaySupport(nullptr, &candidates);
+  processor.CheckOverlaySupport(nullptr, &candidates);
   EXPECT_TRUE(candidates.back().overlay_handled);
   EXPECT_RECTF_EQ(candidates.back().display_rect, gfx::RectF(10, 40, 100, 50));
-  EXPECT_EQ(validator.GetOverlayDamageRectForOutputSurface(candidates.back()),
+  EXPECT_EQ(processor.GetOverlayDamageRectForOutputSurface(candidates.back()),
             gfx::Rect(10, 10, 50, 100));
 }
 
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc
index 78421fb..5839dc0 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.cc
+++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -13,60 +13,13 @@
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/service/display/display_resource_provider.h"
 #include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
 #include "components/viz/service/display/overlay_strategy_underlay.h"
-#include "components/viz/service/display/skia_output_surface.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/transform.h"
 
 namespace viz {
 
-namespace {
-
-#if defined(OS_ANDROID)
-// Utility class to make sure that we notify resource that they're promotable
-// before returning from ProcessForOverlays.
-class SendPromotionHintsBeforeReturning {
- public:
-  SendPromotionHintsBeforeReturning(DisplayResourceProvider* resource_provider,
-                                    OverlayCandidateList* candidates,
-                                    SkiaOutputSurface* skia_output_surface)
-      : resource_provider_(resource_provider),
-        candidates_(candidates),
-        skia_output_surface_(skia_output_surface) {}
-  ~SendPromotionHintsBeforeReturning() {
-    if (skia_output_surface_) {
-      base::flat_set<gpu::Mailbox> promotion_denied;
-      base::flat_map<gpu::Mailbox, gfx::Rect> possible_promotions;
-      auto locks = candidates_->ConvertLocalPromotionToMailboxKeyed(
-          resource_provider_, &promotion_denied, &possible_promotions);
-
-      std::vector<gpu::SyncToken> locks_sync_tokens;
-      for (auto& read_lock : locks)
-        locks_sync_tokens.push_back(read_lock->sync_token());
-
-      skia_output_surface_->SendOverlayPromotionNotification(
-          std::move(locks_sync_tokens), std::move(promotion_denied),
-          std::move(possible_promotions));
-    } else {
-      resource_provider_->SendPromotionHints(
-          candidates_->promotion_hint_info_map_,
-          candidates_->promotion_hint_requestor_set_);
-    }
-  }
-
- private:
-  DisplayResourceProvider* resource_provider_;
-  OverlayCandidateList* candidates_;
-  SkiaOutputSurface* skia_output_surface_;
-
-  DISALLOW_COPY_AND_ASSIGN(SendPromotionHintsBeforeReturning);
-};
-#endif
-}  // namespace
-
 // Default implementation of whether a strategy would remove the output surface
 // as overlay plane.
 bool OverlayProcessorUsingStrategy::Strategy::RemoveOutputSurfaceAsOverlay() {
@@ -77,43 +30,22 @@
   return OverlayStrategy::kUnknown;
 }
 
-#if defined(OS_ANDROID)
-OverlayProcessorUsingStrategy::OverlayProcessorUsingStrategy(
-    SkiaOutputSurface* skia_output_surface,
-    std::unique_ptr<OverlayCandidateValidatorStrategy> overlay_validator)
-    : OverlayProcessorInterface(),
-      overlay_validator_(std::move(overlay_validator)),
-      skia_output_surface_(skia_output_surface) {
-  InitializeStrategies();
-}
-#else  // defined(USE_OZONE)
-OverlayProcessorUsingStrategy::OverlayProcessorUsingStrategy(
-    SkiaOutputSurface* skia_output_surface,
-    std::unique_ptr<OverlayCandidateValidatorStrategy> overlay_validator)
-    : OverlayProcessorInterface(),
-      overlay_validator_(std::move(overlay_validator)) {
-  InitializeStrategies();
-}
-#endif
-
-void OverlayProcessorUsingStrategy::InitializeStrategies() {
-  DCHECK(strategies_.empty());
-  if (overlay_validator_)
-    strategies_ = overlay_validator_->InitializeStrategies(this);
-}
+OverlayProcessorUsingStrategy::OverlayProcessorUsingStrategy()
+    : OverlayProcessorInterface() {}
 
 OverlayProcessorUsingStrategy::~OverlayProcessorUsingStrategy() = default;
 
-bool OverlayProcessorUsingStrategy::IsOverlaySupported() const {
-  return !!overlay_validator_;
-}
-
 gfx::Rect OverlayProcessorUsingStrategy::GetAndResetOverlayDamage() {
   gfx::Rect result = overlay_damage_rect_;
   overlay_damage_rect_ = gfx::Rect();
   return result;
 }
 
+void OverlayProcessorUsingStrategy::NotifyOverlayPromotion(
+    DisplayResourceProvider* resource_provider,
+    const CandidateList& candidates,
+    const QuadList& quad_list) {}
+
 void OverlayProcessorUsingStrategy::ProcessForOverlays(
     DisplayResourceProvider* resource_provider,
     RenderPassList* render_passes,
@@ -126,14 +58,6 @@
     gfx::Rect* damage_rect,
     std::vector<gfx::Rect>* content_bounds) {
   TRACE_EVENT0("viz", "OverlayProcessorUsingStrategy::ProcessForOverlays");
-#if defined(OS_ANDROID)
-  // Be sure to send out notifications, regardless of whether we get to
-  // processing for overlays or not.  If we don't, then we should notify that
-  // they are not promotable.
-  SendPromotionHintsBeforeReturning notifier(resource_provider, candidates,
-                                             skia_output_surface_);
-#endif
-
   DCHECK(candidates->empty());
 
   RenderPass* render_pass = render_passes->back().get();
@@ -146,6 +70,8 @@
     // being invoked.  Also reset |previous_frame_underlay_was_unoccluded_|.
     previous_frame_underlay_rect_ = gfx::Rect();
     previous_frame_underlay_was_unoccluded_ = false;
+    NotifyOverlayPromotion(resource_provider, *candidates,
+                           render_pass->quad_list);
     return;
   }
 
@@ -168,6 +94,8 @@
     previous_frame_underlay_was_unoccluded_ = false;
   }
 
+  NotifyOverlayPromotion(resource_provider, *candidates,
+                         render_pass->quad_list);
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("viz.debug.overlay_planes"),
                  "Scheduled overlay planes", candidates->size());
 }
@@ -248,12 +176,6 @@
   if (!output_surface_plane || !output_surface_plane->has_value())
     return;
 
-  // This is used by the surface control implementation to adjust the display
-  // transform and the display rect.
-  if (overlay_validator_)
-    overlay_validator_->AdjustOutputSurfaceOverlay(
-        &(output_surface_plane->value()));
-
   // If the overlay candidates cover the entire screen, the
   // |output_surface_plane| could be removed.
   if (last_successful_strategy_ &&
@@ -261,23 +183,6 @@
     output_surface_plane->reset();
 }
 
-bool OverlayProcessorUsingStrategy::NeedsSurfaceOccludingDamageRect() const {
-  return overlay_validator_ &&
-         overlay_validator_->NeedsSurfaceOccludingDamageRect();
-}
-
-void OverlayProcessorUsingStrategy::SetDisplayTransformHint(
-    gfx::OverlayTransform transform) {
-  if (overlay_validator_)
-    overlay_validator_->SetDisplayTransform(transform);
-}
-
-void OverlayProcessorUsingStrategy::SetValidatorViewportSize(
-    const gfx::Size& size) {
-  if (overlay_validator_)
-    overlay_validator_->SetViewportSize(size);
-}
-
 bool OverlayProcessorUsingStrategy::AttemptWithStrategies(
     const SkMatrix44& output_color_matrix,
     const OverlayProcessorInterface::FilterOperationsMap&
@@ -306,18 +211,8 @@
   return false;
 }
 
-void OverlayProcessorUsingStrategy::CheckOverlaySupport(
-    const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
-    OverlayCandidateList* candidate_list) {
-  if (overlay_validator_)
-    overlay_validator_->CheckOverlaySupport(primary_plane, candidate_list);
-}
-
 gfx::Rect OverlayProcessorUsingStrategy::GetOverlayDamageRectForOutputSurface(
     const OverlayCandidate& overlay) const {
-  if (overlay_validator_)
-    return overlay_validator_->GetOverlayDamageRectForOutputSurface(overlay);
-
   return ToEnclosedRect(overlay.display_rect);
 }
 }  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_using_strategy.h b/components/viz/service/display/overlay_processor_using_strategy.h
index 6782ace..6dcfff3 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.h
+++ b/components/viz/service/display/overlay_processor_using_strategy.h
@@ -23,16 +23,12 @@
 }
 
 namespace viz {
-class OverlayCandidateList;
-class OverlayCandidateValidatorStrategy;
-
 // OverlayProcessor subclass that goes through a list of strategies to determine
 // overlay candidates. THis is used by Android and Ozone platforms.
 class VIZ_SERVICE_EXPORT OverlayProcessorUsingStrategy
     : public OverlayProcessorInterface {
  public:
   using CandidateList = OverlayCandidateList;
-  using OverlayValidator = OverlayCandidateValidatorStrategy;
 
   // TODO(weiliangc): Move it to an external class.
   class VIZ_SERVICE_EXPORT Strategy {
@@ -70,21 +66,11 @@
 
   ~OverlayProcessorUsingStrategy() override;
 
-  bool IsOverlaySupported() const override;
   gfx::Rect GetAndResetOverlayDamage() final;
 
-  const OverlayValidator* GetOverlayCandidateValidator() const {
-    return overlay_validator_.get();
-  }
-
-  // Returns true if the platform supports hw overlays and surface occluding
-  // damage rect needs to be computed since it will be used by overlay
-  // processor.
-  bool NeedsSurfaceOccludingDamageRect() const override;
-
   // Override OverlayProcessor.
-  void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
-  void SetValidatorViewportSize(const gfx::Size& size) override;
+  void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
+  void SetViewportSize(const gfx::Size& size) override {}
 
   // Attempt to replace quads from the specified root render pass with overlays.
   // This must be called every frame.
@@ -106,23 +92,24 @@
   // TODO(weiliangc): Internalize the |output_surface_plane| inside the overlay
   // processor.
   void AdjustOutputSurfaceOverlay(
-      base::Optional<OutputSurfaceOverlayPlane>* output_surface_plane) final;
+      base::Optional<OutputSurfaceOverlayPlane>* output_surface_plane) override;
 
-  OverlayProcessorUsingStrategy(
-      SkiaOutputSurface* skia_output_surface,
-      std::unique_ptr<OverlayValidator> overlay_validator);
+  OverlayProcessorUsingStrategy();
 
+  // A list of possible overlay candidates is presented to this function.
+  // The expected result is that those candidates that can be in a separate
+  // plane are marked with |overlay_handled| set to true, otherwise they are
+  // to be traditionally composited. Candidates with |overlay_handled| set to
+  // true must also have their |display_rect| converted to integer
+  // coordinates if necessary.
   virtual void CheckOverlaySupport(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
-      OverlayCandidateList* candidate_list);
+      OverlayCandidateList* candidate_list) = 0;
 
  protected:
-  virtual void InitializeStrategies();
   virtual gfx::Rect GetOverlayDamageRectForOutputSurface(
       const OverlayCandidate& overlay) const;
 
-  std::unique_ptr<OverlayValidator> overlay_validator_;
-
   StrategyList strategies_;
   Strategy* last_successful_strategy_ = nullptr;
 
@@ -155,9 +142,12 @@
       OverlayCandidateList* candidates,
       std::vector<gfx::Rect>* content_bounds);
 
-#if defined(OS_ANDROID)
-  SkiaOutputSurface* skia_output_surface_;
-#endif
+  // Used by Android pre-SurfaceControl to notify promotion hints.
+  virtual void NotifyOverlayPromotion(
+      DisplayResourceProvider* resource_provider,
+      const OverlayCandidateList& candidate_list,
+      const QuadList& quad_list);
+
   DISALLOW_COPY_AND_ASSIGN(OverlayProcessorUsingStrategy);
 };
 
diff --git a/components/viz/service/display/overlay_processor_win.cc b/components/viz/service/display/overlay_processor_win.cc
index 6b33273..7d87aa3 100644
--- a/components/viz/service/display/overlay_processor_win.cc
+++ b/components/viz/service/display/overlay_processor_win.cc
@@ -11,7 +11,6 @@
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/service/display/display_resource_provider.h"
 #include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
 namespace viz {
diff --git a/components/viz/service/display/overlay_strategy_fullscreen.cc b/components/viz/service/display/overlay_strategy_fullscreen.cc
index 04c6889..dd7f6ae 100644
--- a/components/viz/service/display/overlay_strategy_fullscreen.cc
+++ b/components/viz/service/display/overlay_strategy_fullscreen.cc
@@ -6,7 +6,6 @@
 
 #include "components/viz/common/quads/draw_quad.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size_conversions.h"
 
diff --git a/components/viz/service/display/overlay_strategy_single_on_top.cc b/components/viz/service/display/overlay_strategy_single_on_top.cc
index 83cf8f5..e3da860f1 100644
--- a/components/viz/service/display/overlay_strategy_single_on_top.cc
+++ b/components/viz/service/display/overlay_strategy_single_on_top.cc
@@ -4,7 +4,6 @@
 
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
 
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
diff --git a/components/viz/service/display/overlay_strategy_underlay.cc b/components/viz/service/display/overlay_strategy_underlay.cc
index f3c23702..0fc6655c 100644
--- a/components/viz/service/display/overlay_strategy_underlay.cc
+++ b/components/viz/service/display/overlay_strategy_underlay.cc
@@ -7,7 +7,6 @@
 #include "components/viz/common/quads/draw_quad.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/service/display/display_resource_provider.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
 
 namespace viz {
 
@@ -33,19 +32,9 @@
   DCHECK(candidate_list->empty());
   RenderPass* render_pass = render_pass_list->back().get();
   QuadList& quad_list = render_pass->quad_list;
-  const bool compute_hints =
-      resource_provider->DoAnyResourcesWantPromotionHints();
 
   for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
     OverlayCandidate candidate;
-
-    // If we're computing the list of all resources that requested promotion
-    // hints, then add this candidate to the set if needed.
-    if (compute_hints) {
-      candidate_list->AddToPromotionHintRequestorSetIfNeeded(resource_provider,
-                                                             *it);
-    }
-
     if (!OverlayCandidate::FromDrawQuad(resource_provider, output_color_matrix,
                                         *it, &candidate) ||
         (opaque_mode_ == OpaqueMode::RequireOpaqueCandidates &&
@@ -89,25 +78,7 @@
       quad_list.ReplaceExistingQuadWithOpaqueTransparentSolidColor(it);
       candidate_list->swap(new_candidate_list);
 
-      // This quad will be promoted.  We clear the promotable hints here, since
-      // we can only promote a single quad.  Otherwise, somebody might try to
-      // back one of the promotable quads with a SurfaceView, and either it or
-      // |candidate| would have to fall back to a texture.
-      candidate_list->promotion_hint_info_map_.clear();
-      candidate_list->AddPromotionHint(candidate);
-      if (compute_hints) {
-        // Finish the quad list to find any other resources.
-        for (; it != quad_list.end(); ++it) {
-          candidate_list->AddToPromotionHintRequestorSetIfNeeded(
-              resource_provider, *it);
-        }
-      }
       return true;
-    } else {
-      // If |candidate| should get a promotion hint, then remember that now.
-      candidate_list->promotion_hint_info_map_.insert(
-          new_candidate_list.promotion_hint_info_map_.begin(),
-          new_candidate_list.promotion_hint_info_map_.end());
     }
   }
 
diff --git a/components/viz/service/display/overlay_strategy_underlay_cast.cc b/components/viz/service/display/overlay_strategy_underlay_cast.cc
index 3ede4fe..4d1fda11 100644
--- a/components/viz/service/display/overlay_strategy_underlay_cast.cc
+++ b/components/viz/service/display/overlay_strategy_underlay_cast.cc
@@ -11,7 +11,6 @@
 #include "components/viz/common/quads/draw_quad.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/video_hole_draw_quad.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
 #if BUILDFLAG(IS_CHROMECAST)
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index 7e783cd..9fe32161 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -29,7 +29,6 @@
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
 #include "components/viz/service/display/overlay_processor_using_strategy.h"
 #include "components/viz/service/display/overlay_strategy_fullscreen.h"
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
@@ -72,15 +71,10 @@
 class TestOverlayProcessor : public OverlayProcessorUsingStrategy {
  public:
   using PrimaryPlane = OverlayProcessorInterface::OutputSurfaceOverlayPlane;
-  TestOverlayProcessor()
-      : OverlayProcessorUsingStrategy(
-            nullptr,
-            std::unique_ptr<OverlayCandidateValidatorStrategy>()) {
-    InitializeStrategies();
-  }
+  TestOverlayProcessor() : OverlayProcessorUsingStrategy() {}
   ~TestOverlayProcessor() override = default;
 
-  void InitializeStrategies() override {}
+  bool IsOverlaySupported() const override { return true; }
   bool NeedsSurfaceOccludingDamageRect() const override { return false; }
   void CheckOverlaySupport(const PrimaryPlane* primary_plane,
                            OverlayCandidateList* surfaces) override {}
@@ -90,9 +84,6 @@
 class FullscreenOverlayProcessor : public TestOverlayProcessor {
  public:
   FullscreenOverlayProcessor() : TestOverlayProcessor() {
-    InitializeStrategies();
-  }
-  void InitializeStrategies() override {
     strategies_.push_back(std::make_unique<OverlayStrategyFullscreen>(this));
   }
   bool NeedsSurfaceOccludingDamageRect() const override { return true; }
@@ -107,7 +98,6 @@
   DefaultOverlayProcessor()
       : TestOverlayProcessor(), expected_rects_(1, gfx::RectF(kOverlayRect)) {}
 
-  void InitializeStrategies() override {}
   bool NeedsSurfaceOccludingDamageRect() const override { return true; }
   void CheckOverlaySupport(const PrimaryPlane* primary_plane,
                            OverlayCandidateList* surfaces) override {
@@ -2226,10 +2216,9 @@
   OverlayInfoRendererGL(const RendererSettings* settings,
                         OutputSurface* output_surface,
                         DisplayResourceProvider* resource_provider,
-                        bool use_validator)
+                        bool use_overlay_processor)
       : GLRenderer(settings, output_surface, resource_provider, nullptr),
-        expect_overlays_(false) {
-  }
+        expect_overlays_(false) {}
 
   MOCK_METHOD2(DoDrawQuad,
                void(const DrawQuad* quad, const gfx::QuadF* draw_region));
@@ -2305,13 +2294,13 @@
     child_resource_provider_->ShutdownAndReleaseAllResources();
   }
 
-  void Init(bool use_validator) {
+  void Init(bool use_overlay_processor) {
     renderer_ = std::make_unique<OverlayInfoRendererGL>(
         &settings_, output_surface_.get(), resource_provider_.get(),
-        use_validator);
+        use_overlay_processor);
     renderer_->Initialize();
     renderer_->SetVisible(true);
-    if (use_validator) {
+    if (use_overlay_processor) {
       renderer_->SetOverlayProcessor();
     }
   }
@@ -2352,8 +2341,8 @@
 };
 
 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
-  bool use_validator = true;
-  Init(use_validator);
+  bool use_overlay_processor = true;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
   AddExpectedRectToOverlayProcessor(gfx::RectF(kOverlayBottomRightRect));
 
@@ -2393,8 +2382,8 @@
 }
 
 TEST_F(GLRendererWithOverlaysTest, OccludedQuadInUnderlay) {
-  bool use_validator = true;
-  Init(use_validator);
+  bool use_overlay_processor = true;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -2432,8 +2421,8 @@
 }
 
 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
-  bool use_validator = false;
-  Init(use_validator);
+  bool use_overlay_processor = false;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(false);
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -2465,8 +2454,8 @@
 TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenPartialSwapEnabled) {
   provider_->TestContextGL()->set_have_post_sub_buffer(true);
   settings_.partial_swap_enabled = true;
-  bool use_validator = true;
-  Init(use_validator);
+  bool use_overlay_processor = true;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -2495,8 +2484,8 @@
 // GLRenderer skips drawing occluded quads when empty swap is enabled.
 TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenEmptySwapAllowed) {
   provider_->TestContextGL()->set_have_commit_overlay_planes(true);
-  bool use_validator = true;
-  Init(use_validator);
+  bool use_overlay_processor = true;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
 
   std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -2524,8 +2513,8 @@
 }
 
 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedWithDelay) {
-  bool use_validator = true;
-  Init(use_validator);
+  bool use_overlay_processor = true;
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
 
   ResourceId resource1 = CreateResourceInLayerTree(
@@ -2715,9 +2704,9 @@
 }
 
 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedAfterGpuQuery) {
-  bool use_validator = true;
+  bool use_overlay_processor = true;
   settings_.release_overlay_resources_after_gpu_query = true;
-  Init(use_validator);
+  Init(use_overlay_processor);
   renderer_->set_expect_overlays(true);
 
   ResourceId resource1 = CreateResourceInLayerTree(
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS
index 8db9300..096ae37 100644
--- a/components/viz/service/display_embedder/DEPS
+++ b/components/viz/service/display_embedder/DEPS
@@ -12,8 +12,6 @@
   "+components/viz/service/display/output_surface_frame.h",
   "+components/viz/service/display/output_surface.h",
   "+components/viz/service/display/overlay_candidate.h",
-  "+components/viz/service/display/overlay_candidate_list.h",
-  "+components/viz/service/display/overlay_candidate_validator_strategy.h",
   "+components/viz/service/display/renderer_utils.h",
   "+components/viz/service/display/resource_metadata.h",
   "+components/viz/service/display/shared_bitmap_manager.h",
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.cc b/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.cc
deleted file mode 100644
index fb3d267..0000000
--- a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h"
-
-#include "cc/base/math_util.h"
-#include "components/viz/service/display/overlay_candidate_list.h"
-#include "components/viz/service/display/overlay_strategy_fullscreen.h"
-#include "components/viz/service/display/overlay_strategy_single_on_top.h"
-#include "components/viz/service/display/overlay_strategy_underlay.h"
-#include "components/viz/service/display/renderer_utils.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/overlay_transform_utils.h"
-#include "ui/gl/android/android_surface_control_compat.h"
-
-namespace viz {
-namespace {
-
-gfx::RectF ClipFromOrigin(gfx::RectF input) {
-  if (input.x() < 0.f) {
-    input.set_width(input.width() + input.x());
-    input.set_x(0.f);
-  }
-
-  if (input.y() < 0) {
-    input.set_height(input.height() + input.y());
-    input.set_y(0.f);
-  }
-
-  return input;
-}
-
-}  // namespace
-
-OverlayCandidateValidatorSurfaceControl::
-    OverlayCandidateValidatorSurfaceControl() = default;
-OverlayCandidateValidatorSurfaceControl::
-    ~OverlayCandidateValidatorSurfaceControl() = default;
-
-OverlayProcessorUsingStrategy::StrategyList
-OverlayCandidateValidatorSurfaceControl::InitializeStrategies(
-    OverlayProcessorUsingStrategy* processor) {
-  OverlayProcessorUsingStrategy::StrategyList strategies;
-  strategies.push_back(std::make_unique<OverlayStrategyUnderlay>(
-      processor,
-      OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
-  return strategies;
-}
-
-bool OverlayCandidateValidatorSurfaceControl::NeedsSurfaceOccludingDamageRect()
-    const {
-  return true;
-}
-
-void OverlayCandidateValidatorSurfaceControl::CheckOverlaySupport(
-    const PrimaryPlane* primary_plane,
-    OverlayCandidateList* surfaces) {
-  DCHECK(!surfaces->empty());
-
-  for (auto& candidate : *surfaces) {
-    if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) {
-      candidate.overlay_handled = false;
-      return;
-    }
-
-    if (candidate.transform != display_transform_) {
-      candidate.overlay_handled = false;
-      return;
-    }
-    candidate.transform = gfx::OVERLAY_TRANSFORM_NONE;
-
-    gfx::RectF orig_display_rect = candidate.display_rect;
-    gfx::RectF display_rect = orig_display_rect;
-    if (candidate.is_clipped)
-      display_rect.Intersect(gfx::RectF(candidate.clip_rect));
-    // The framework doesn't support display rects positioned at a negative
-    // offset.
-    display_rect = ClipFromOrigin(display_rect);
-    if (display_rect.IsEmpty()) {
-      candidate.overlay_handled = false;
-      return;
-    }
-
-    // The display rect above includes the |display_transform_| while the rects
-    // sent to the platform API need to be in the logical screen space.
-    const gfx::Transform display_inverse = gfx::OverlayTransformToTransform(
-        gfx::InvertOverlayTransform(display_transform_),
-        gfx::SizeF(viewport_size_));
-    display_inverse.TransformRect(&orig_display_rect);
-    display_inverse.TransformRect(&display_rect);
-
-    candidate.display_rect = gfx::RectF(gfx::ToEnclosingRect(display_rect));
-    candidate.uv_rect = cc::MathUtil::ScaleRectProportional(
-        candidate.uv_rect, orig_display_rect, candidate.display_rect);
-    candidate.overlay_handled = true;
-  }
-}
-
-void OverlayCandidateValidatorSurfaceControl::AdjustOutputSurfaceOverlay(
-    PrimaryPlane* output_surface_plane) {
-  DCHECK(output_surface_plane);
-  DCHECK(
-      gl::SurfaceControl::SupportsColorSpace(output_surface_plane->color_space))
-      << "The main overlay must only use color space supported by the "
-         "device";
-
-  DCHECK_EQ(output_surface_plane->transform, gfx::OVERLAY_TRANSFORM_NONE);
-  DCHECK(output_surface_plane->display_rect ==
-         ClipFromOrigin(output_surface_plane->display_rect));
-
-  output_surface_plane->transform = display_transform_;
-  const gfx::Transform display_inverse = gfx::OverlayTransformToTransform(
-      gfx::InvertOverlayTransform(display_transform_),
-      gfx::SizeF(viewport_size_));
-  display_inverse.TransformRect(&output_surface_plane->display_rect);
-  output_surface_plane->display_rect =
-      gfx::RectF(gfx::ToEnclosingRect(output_surface_plane->display_rect));
-}
-
-void OverlayCandidateValidatorSurfaceControl::SetDisplayTransform(
-    gfx::OverlayTransform transform) {
-  display_transform_ = transform;
-}
-
-void OverlayCandidateValidatorSurfaceControl::SetViewportSize(
-    const gfx::Size& viewport_size) {
-  viewport_size_ = viewport_size;
-}
-
-gfx::Rect
-OverlayCandidateValidatorSurfaceControl::GetOverlayDamageRectForOutputSurface(
-    const OverlayCandidate& candidate) const {
-  // Should only be called after ProcessForOverlays on handled candidates.
-  DCHECK(candidate.overlay_handled);
-  // When the overlay is handled by the validator, we transform its display rect
-  // to the logical screen space (used by the ui when preparing the frame) that
-  // the SurfaceControl expects it to be in. So in order to provide a damage
-  // rect which maps to the OutputSurface's main plane, we need to undo that
-  // transformation.
-  // But only if the overlay is in handled state, since the modification above
-  // is only applied when we mark the overlay as handled.
-  gfx::Size viewport_size_pre_display_transform(viewport_size_.height(),
-                                                viewport_size_.width());
-  auto transform = gfx::OverlayTransformToTransform(
-      display_transform_, gfx::SizeF(viewport_size_pre_display_transform));
-  gfx::RectF transformed_rect(candidate.display_rect);
-  transform.TransformRect(&transformed_rect);
-  return gfx::ToEnclosedRect(transformed_rect);
-}
-
-}  // namespace viz
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h b/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h
deleted file mode 100644
index eedec7d..0000000
--- a/components/viz/service/display_embedder/overlay_candidate_validator_surface_control.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_SURFACE_CONTROL_H_
-#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_SURFACE_CONTROL_H_
-
-#include "components/viz/service/display/overlay_candidate_validator_strategy.h"
-#include "components/viz/service/viz_service_export.h"
-
-namespace viz {
-
-// Android OverlayCandidateValidator that uses surface control. Requires Android
-// Q or higher.
-class VIZ_SERVICE_EXPORT OverlayCandidateValidatorSurfaceControl
-    : public OverlayCandidateValidatorStrategy {
- public:
-  OverlayCandidateValidatorSurfaceControl();
-  ~OverlayCandidateValidatorSurfaceControl() override;
-
-  // OverlayCandidateValidator implementation.
-  OverlayProcessorUsingStrategy::StrategyList InitializeStrategies(
-      OverlayProcessorUsingStrategy* processor) override;
-  bool NeedsSurfaceOccludingDamageRect() const override;
-  void CheckOverlaySupport(const PrimaryPlane* primary_plane,
-                           OverlayCandidateList* surfaces) override;
-  void AdjustOutputSurfaceOverlay(PrimaryPlane* output_surface_plane) override;
-  void SetDisplayTransform(gfx::OverlayTransform transform) override;
-  void SetViewportSize(const gfx::Size& viewport_size) override;
-  gfx::Rect GetOverlayDamageRectForOutputSurface(
-      const OverlayCandidate& overlay) const override;
-
- private:
-  gfx::OverlayTransform display_transform_ = gfx::OVERLAY_TRANSFORM_NONE;
-  gfx::Size viewport_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(OverlayCandidateValidatorSurfaceControl);
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_SURFACE_CONTROL_H_
diff --git a/components/webdata/common/web_database_backend.cc b/components/webdata/common/web_database_backend.cc
index 0ccf50d9..53cb0ecc 100644
--- a/components/webdata/common/web_database_backend.cc
+++ b/components/webdata/common/web_database_backend.cc
@@ -50,40 +50,39 @@
 }
 
 void WebDatabaseBackend::DBWriteTaskWrapper(
-    const WebDatabaseService::WriteTask& task,
+    WebDatabaseService::WriteTask task,
     std::unique_ptr<WebDataRequest> request) {
   if (!request->IsActive())
     return;
 
-  ExecuteWriteTask(task);
+  ExecuteWriteTask(std::move(task));
   request_manager_->RequestCompleted(std::move(request), nullptr);
 }
 
-void WebDatabaseBackend::ExecuteWriteTask(
-    const WebDatabaseService::WriteTask& task) {
+void WebDatabaseBackend::ExecuteWriteTask(WebDatabaseService::WriteTask task) {
   LoadDatabaseIfNecessary();
   if (db_ && init_status_ == sql::INIT_OK) {
-    WebDatabase::State state = task.Run(db_.get());
+    WebDatabase::State state = std::move(task).Run(db_.get());
     if (state == WebDatabase::COMMIT_NEEDED)
       Commit();
   }
 }
 
 void WebDatabaseBackend::DBReadTaskWrapper(
-    const WebDatabaseService::ReadTask& task,
+    WebDatabaseService::ReadTask task,
     std::unique_ptr<WebDataRequest> request) {
   if (!request->IsActive())
     return;
 
-  std::unique_ptr<WDTypedResult> result = ExecuteReadTask(task);
+  std::unique_ptr<WDTypedResult> result = ExecuteReadTask(std::move(task));
   request_manager_->RequestCompleted(std::move(request), std::move(result));
 }
 
 std::unique_ptr<WDTypedResult> WebDatabaseBackend::ExecuteReadTask(
-    const WebDatabaseService::ReadTask& task) {
+    WebDatabaseService::ReadTask task) {
   LoadDatabaseIfNecessary();
   if (db_ && init_status_ == sql::INIT_OK) {
-    return task.Run(db_.get());
+    return std::move(task).Run(db_.get());
   }
   return nullptr;
 }
@@ -103,8 +102,8 @@
     db_->AddTable(table.get());
 
   // Unretained to avoid a ref loop since we own |db_|.
-  db_->set_error_callback(base::Bind(&WebDatabaseBackend::DatabaseErrorCallback,
-                                     base::Unretained(this)));
+  db_->set_error_callback(base::BindRepeating(
+      &WebDatabaseBackend::DatabaseErrorCallback, base::Unretained(this)));
   diagnostics_.clear();
   catastrophic_error_occurred_ = false;
   init_status_ = db_->Init(db_path_);
diff --git a/components/webdata/common/web_database_backend.h b/components/webdata/common/web_database_backend.h
index 8c93954..bedaba7 100644
--- a/components/webdata/common/web_database_backend.h
+++ b/components/webdata/common/web_database_backend.h
@@ -61,15 +61,15 @@
   // are used in cases where the request is being made from the UI thread and an
   // asyncronous callback is required to notify the client of |request|'s
   // completion.
-  void DBWriteTaskWrapper(const WebDatabaseService::WriteTask& task,
+  void DBWriteTaskWrapper(WebDatabaseService::WriteTask task,
                           std::unique_ptr<WebDataRequest> request);
-  void DBReadTaskWrapper(const WebDatabaseService::ReadTask& task,
+  void DBReadTaskWrapper(WebDatabaseService::ReadTask task,
                          std::unique_ptr<WebDataRequest> request);
 
   // Task runners to run database tasks.
-  void ExecuteWriteTask(const WebDatabaseService::WriteTask& task);
+  void ExecuteWriteTask(WebDatabaseService::WriteTask task);
   std::unique_ptr<WDTypedResult> ExecuteReadTask(
-      const WebDatabaseService::ReadTask& task);
+      WebDatabaseService::ReadTask task);
 
   const scoped_refptr<WebDataRequestManager>& request_manager() {
     return request_manager_;
diff --git a/components/webdata/common/web_database_service.cc b/components/webdata/common/web_database_service.cc
index b58314a..8bb61eb1 100644
--- a/components/webdata/common/web_database_service.cc
+++ b/components/webdata/common/web_database_service.cc
@@ -90,18 +90,19 @@
 }
 
 void WebDatabaseService::ScheduleDBTask(const base::Location& from_here,
-                                        const WriteTask& task) {
+                                        WriteTask task) {
   DCHECK(web_db_backend_);
   std::unique_ptr<WebDataRequest> request =
       web_db_backend_->request_manager()->NewRequest(nullptr);
   db_task_runner_->PostTask(
-      from_here, BindOnce(&WebDatabaseBackend::DBWriteTaskWrapper,
-                          web_db_backend_, task, std::move(request)));
+      from_here,
+      BindOnce(&WebDatabaseBackend::DBWriteTaskWrapper, web_db_backend_,
+               std::move(task), std::move(request)));
 }
 
 WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult(
     const base::Location& from_here,
-    const ReadTask& task,
+    ReadTask task,
     WebDataServiceConsumer* consumer) {
   DCHECK(consumer);
   DCHECK(web_db_backend_);
@@ -109,8 +110,9 @@
       web_db_backend_->request_manager()->NewRequest(consumer);
   WebDataServiceBase::Handle handle = request->GetHandle();
   db_task_runner_->PostTask(
-      from_here, BindOnce(&WebDatabaseBackend::DBReadTaskWrapper,
-                          web_db_backend_, task, std::move(request)));
+      from_here,
+      BindOnce(&WebDatabaseBackend::DBReadTaskWrapper, web_db_backend_,
+               std::move(task), std::move(request)));
   return handle;
 }
 
diff --git a/components/webdata/common/web_database_service.h b/components/webdata/common/web_database_service.h
index bd33a9d..c3d895f 100644
--- a/components/webdata/common/web_database_service.h
+++ b/components/webdata/common/web_database_service.h
@@ -45,8 +45,9 @@
 class WEBDATA_EXPORT WebDatabaseService
     : public base::RefCountedDeleteOnSequence<WebDatabaseService> {
  public:
-  using ReadTask = base::Callback<std::unique_ptr<WDTypedResult>(WebDatabase*)>;
-  using WriteTask = base::Callback<WebDatabase::State(WebDatabase*)>;
+  using ReadTask =
+      base::OnceCallback<std::unique_ptr<WDTypedResult>(WebDatabase*)>;
+  using WriteTask = base::OnceCallback<WebDatabase::State(WebDatabase*)>;
 
   // Types for managing DB loading callbacks.
   using DBLoadedCallback = base::OnceClosure;
@@ -79,13 +80,12 @@
   scoped_refptr<WebDatabaseBackend> GetBackend() const;
 
   // Schedule an update/write task on the DB sequence.
-  virtual void ScheduleDBTask(const base::Location& from_here,
-                              const WriteTask& task);
+  virtual void ScheduleDBTask(const base::Location& from_here, WriteTask task);
 
   // Schedule a read task on the DB sequence.
   virtual WebDataServiceBase::Handle ScheduleDBTaskWithResult(
       const base::Location& from_here,
-      const ReadTask& task,
+      ReadTask task,
       WebDataServiceConsumer* consumer);
 
   // Cancel an existing request for a task on the DB sequence.
diff --git a/components/webdata_services/web_data_service_wrapper.cc b/components/webdata_services/web_data_service_wrapper.cc
index 7e4e2ab..12d7138 100644
--- a/components/webdata_services/web_data_service_wrapper.cc
+++ b/components/webdata_services/web_data_service_wrapper.cc
@@ -120,11 +120,11 @@
 #endif
 
   profile_autofill_web_data_->GetAutofillBackend(
-      base::Bind(&InitAutofillSyncBridgesOnDBSequence, db_task_runner,
-                 profile_autofill_web_data_, application_locale));
-  profile_autofill_web_data_->GetAutofillBackend(
-      base::Bind(&InitWalletSyncBridgesOnDBSequence, db_task_runner,
-                 profile_autofill_web_data_, context_path, application_locale));
+      base::BindOnce(&InitAutofillSyncBridgesOnDBSequence, db_task_runner,
+                     profile_autofill_web_data_, application_locale));
+  profile_autofill_web_data_->GetAutofillBackend(base::BindOnce(
+      &InitWalletSyncBridgesOnDBSequence, db_task_runner,
+      profile_autofill_web_data_, context_path, application_locale));
 
   if (base::FeatureList::IsEnabled(
           autofill::features::kAutofillEnableAccountWalletStorage)) {
@@ -139,7 +139,7 @@
             account_database_, ui_task_runner, db_task_runner);
     account_autofill_web_data_->Init(
         base::BindOnce(show_error_callback, ERROR_LOADING_ACCOUNT_AUTOFILL));
-    account_autofill_web_data_->GetAutofillBackend(base::Bind(
+    account_autofill_web_data_->GetAutofillBackend(base::BindOnce(
         &InitWalletSyncBridgesOnDBSequence, db_task_runner,
         account_autofill_web_data_, context_path, application_locale));
   }
diff --git a/components/zoom/page_zoom_constants.cc b/components/zoom/page_zoom_constants.cc
index 0c9052b..9eeb1ba9 100644
--- a/components/zoom/page_zoom_constants.cc
+++ b/components/zoom/page_zoom_constants.cc
@@ -4,16 +4,26 @@
 
 #include "components/zoom/page_zoom_constants.h"
 
+#include "base/json/json_writer.h"
 #include "base/stl_util.h"
+#include "base/values.h"
 
 namespace zoom {
 
-// This list is duplicated in chrome/browser/resources/pdf/viewport.js and in
-// chrome/browser/resources/settings/appearance_page/appearance_page.js. Please
-// make sure the three match.
 const double kPresetZoomFactors[] = {0.25, 1 / 3.0, 0.5, 2 / 3.0, 0.75, 0.8,
                                      0.9, 1.0, 1.1, 1.25, 1.5, 1.75, 2.0, 2.5,
                                      3.0, 4.0, 5.0};
 const std::size_t kPresetZoomFactorsSize = base::size(kPresetZoomFactors);
 
-}  // namespace ui_zoom
+std::string GetPresetZoomFactorsAsJSON() {
+  base::Value zoom_factors(base::Value::Type::LIST);
+  for (double zoom_value : kPresetZoomFactors) {
+    zoom_factors.Append(zoom_value);
+  }
+  std::string zoom_factors_json;
+  bool success = base::JSONWriter::Write(zoom_factors, &zoom_factors_json);
+  DCHECK(success);
+  return zoom_factors_json;
+}
+
+}  // namespace zoom
diff --git a/components/zoom/page_zoom_constants.h b/components/zoom/page_zoom_constants.h
index 52c550a..d6dc714 100644
--- a/components/zoom/page_zoom_constants.h
+++ b/components/zoom/page_zoom_constants.h
@@ -6,17 +6,18 @@
 #define COMPONENTS_ZOOM_PAGE_ZOOM_CONSTANTS_H_
 
 #include <stddef.h>
-
+#include <string>
 #include <vector>
 
 namespace zoom {
 
 // Default zoom factors supported by ui_zoom.
 extern const double kPresetZoomFactors[];
-
 // Size of |kPresetZoomFactors|.
 extern const std::size_t kPresetZoomFactorsSize;
 
-}  // namespace ui_zoom
+std::string GetPresetZoomFactorsAsJSON();
+
+}  // namespace zoom
 
 #endif  // COMPONENTS_ZOOM_PAGE_ZOOM_CONSTANTS_H_
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 30f5dbbc..f73fe682d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -383,6 +383,7 @@
         aria_properties_events_.insert(node);
       } else if (ui::IsValuePatternSupported(node)) {
         FireUiaPropertyChangedEvent(UIA_ValueValuePropertyId, node);
+        FireUiaTextContainerEvent(UIA_Text_TextChangedEventId, node);
       }
       break;
     case ui::AXEventGenerator::Event::VALUE_MAX_CHANGED:
diff --git a/content/browser/android/gesture_listener_manager.cc b/content/browser/android/gesture_listener_manager.cc
index cc70e593..83a37d6 100644
--- a/content/browser/android/gesture_listener_manager.cc
+++ b/content/browser/android/gesture_listener_manager.cc
@@ -182,8 +182,8 @@
   int gesture_type = ToGestureEventType(event.GetType());
   float dip_scale = web_contents_->GetNativeView()->GetDipScale();
   return Java_GestureListenerManagerImpl_filterTapOrPressEvent(
-      env, j_obj, gesture_type, gesture.PositionInWidget().x * dip_scale,
-      gesture.PositionInWidget().y * dip_scale);
+      env, j_obj, gesture_type, gesture.PositionInWidget().x() * dip_scale,
+      gesture.PositionInWidget().y() * dip_scale);
 }
 
 // All positions and sizes (except |top_shown_pix|) are in CSS pixels.
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc
index e076df7f..9ccb828 100644
--- a/content/browser/appcache/appcache_update_job.cc
+++ b/content/browser/appcache/appcache_update_job.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
-#include "base/feature_list.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_util.h"
@@ -34,9 +33,6 @@
 const int kAppCacheFetchBufferSize = 32768;
 const size_t kMaxConcurrentUrlFetches = 2;
 
-const base::Feature kAppCacheManifestScopeChecksFeature{
-    "AppCacheManifestScopeChecks", base::FEATURE_ENABLED_BY_DEFAULT};
-
 std::string FormatUrlErrorMessage(
       const char* format, const GURL& url,
       AppCacheUpdateJob::ResultType error,
@@ -177,6 +173,9 @@
 
 }  // namespace
 
+const base::Feature kAppCacheManifestScopeChecksFeature{
+    "AppCacheManifestScopeChecks", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Helper class for collecting hosts per frontend when sending notifications
 // so that only one notification is sent for all hosts using the same frontend.
 class HostNotifier {
diff --git a/content/browser/appcache/appcache_update_job.h b/content/browser/appcache/appcache_update_job.h
index d6e4cc0..d5886da 100644
--- a/content/browser/appcache/appcache_update_job.h
+++ b/content/browser/appcache/appcache_update_job.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/containers/circular_deque.h"
+#include "base/feature_list.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -42,6 +43,8 @@
 
 class HostNotifier;
 
+CONTENT_EXPORT extern const base::Feature kAppCacheManifestScopeChecksFeature;
+
 // Application cache Update algorithm and state.
 class CONTENT_EXPORT AppCacheUpdateJob
     : public AppCacheStorage::Delegate,
diff --git a/content/browser/appcache/appcache_update_job_unittest.cc b/content/browser/appcache/appcache_update_job_unittest.cc
index b0b4a84..b7132ef 100644
--- a/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/content/browser/appcache/appcache_update_job_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/browser/appcache/appcache_group.h"
@@ -1057,6 +1058,8 @@
   }
 
   void UpgradeManifestDataChangedScopeUnchangedTest() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     MakeService();
     // URL path /files/manifest2-with-root-override has a cached scope of "/".
     // The path has a scope override of "/", so the fetched scope will be "/"
@@ -1142,6 +1145,8 @@
   }
 
   void UpgradeManifestDataChangedScopeChangedTest() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     MakeService();
     // URL path /files/manifest2 has a cached scope of "/".  The path has no
     // scope override, so the fetched scope will be "/files/" and a scope change
@@ -1218,6 +1223,8 @@
   }
 
   void UpgradeManifestDataUnchangedScopeUnchangedTest() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     MakeService();
     // URL path /files/manifest2-with-root-override has a cached scope of "/".
     // The path has a scope override of "/", so the fetched scope will be "/"
@@ -1271,6 +1278,8 @@
   }
 
   void UpgradeManifestDataUnchangedScopeChangedTest() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     MakeService();
     // URL path /files/manifest2 has a cached scope of "/".  The path has no
     // scope override, so the fetched scope will be "/files/" and a scope change
@@ -3349,6 +3358,8 @@
   // has a response info with cached Last-Modified headers, the request does not
   // include an If-Modified-Since conditioanl header.
   void IfModifiedSinceUpgradeParserVersion0Test() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     HttpHeadersRequestTestJob::Initialize(std::string(), std::string(),
                                           /*headers_allowed=*/false);
 
@@ -3415,6 +3426,8 @@
   }
 
   void IfModifiedSinceUpgradeParserVersion1Test() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT",
                                           std::string());
 
@@ -3485,6 +3498,8 @@
   // has a response info with cached ETag headers, the request does not include
   // an If-None-Match conditioanl header.
   void IfNoneMatchUpgradeParserVersion0Test() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     HttpHeadersRequestTestJob::Initialize(std::string(), std::string(),
                                           /*headers_allowed=*/false);
 
@@ -3551,6 +3566,8 @@
   }
 
   void IfNoneMatchUpgradeParserVersion1Test() {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\"");
 
     MakeService();
@@ -4391,6 +4408,8 @@
 
   void ScopeTest(const char* tested_manifest_path,
                  const TestedManifest& tested_manifest) {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     GURL manifest_url = MockHttpServer::GetMockUrl(tested_manifest_path);
 
     MakeService();
@@ -4431,6 +4450,8 @@
   void Scope304Test(const char* tested_manifest_path,
                     const std::string& previous_scope,
                     const TestedManifest& tested_manifest) {
+    base::test::ScopedFeatureList f;
+    f.InitAndEnableFeature(kAppCacheManifestScopeChecksFeature);
     GURL manifest_url = MockHttpServer::GetMockUrl(tested_manifest_path);
 
     MakeService();
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index 6dd1963..4ae7dde 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -840,8 +840,7 @@
     return;
   }
 
-  gfx::PointF original(events[0].touches[0].PositionInWidget().x,
-                       events[0].touches[0].PositionInWidget().y);
+  gfx::PointF original(events[0].touches[0].PositionInWidget());
   gfx::PointF transformed;
   RenderWidgetHostImpl* widget_host =
       FindTargetWidgetHost(original, &transformed);
@@ -858,12 +857,12 @@
     events[i].moved_beyond_slop_region = true;
     events[i].unique_touch_event_id = ui::GetNextTouchEventId();
     for (unsigned j = 0; j < events[i].touches_length; j++) {
-      blink::WebFloatPoint point = events[i].touches[j].PositionInWidget();
-      events[i].touches[j].SetPositionInWidget(point.x + delta.x(),
-                                               point.y + delta.y());
+      gfx::PointF point = events[i].touches[j].PositionInWidget();
+      events[i].touches[j].SetPositionInWidget(point.x() + delta.x(),
+                                               point.y() + delta.y());
       point = events[i].touches[j].PositionInScreen();
-      events[i].touches[j].SetPositionInScreen(point.x + delta.x(),
-                                               point.y + delta.y());
+      events[i].touches[j].SetPositionInScreen(point.x() + delta.x(),
+                                               point.y() + delta.y());
     }
   }
   EnsureInjector(widget_host)->InjectTouchEvents(events, std::move(callback));
diff --git a/content/browser/frame_host/interstitial_page_impl_browsertest.cc b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
index 6fb9bfe8..a49ad25 100644
--- a/content/browser/frame_host/interstitial_page_impl_browsertest.cc
+++ b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
@@ -204,9 +204,9 @@
     RenderFrameHostImpl* rfh =
         static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
     rfh->GetRenderWidgetHost()->ForwardMouseEvent(blink::WebMouseEvent(
-        blink::WebInputEvent::Type::kMouseUp, blink::WebFloatPoint(),
-        blink::WebFloatPoint(), blink::WebPointerProperties::Button::kBack, 0,
-        0, base::TimeTicks::Now()));
+        blink::WebInputEvent::Type::kMouseUp, gfx::PointF(), gfx::PointF(),
+        blink::WebPointerProperties::Button::kBack, 0, 0,
+        base::TimeTicks::Now()));
   }
 
  private:
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index db76b82..93fab192 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -9950,9 +9950,9 @@
       ->current_frame_host()
       ->GetRenderWidgetHost()
       ->ForwardMouseEvent(blink::WebMouseEvent(
-          blink::WebInputEvent::Type::kMouseUp, blink::WebFloatPoint(),
-          blink::WebFloatPoint(), blink::WebPointerProperties::Button::kBack, 0,
-          0, base::TimeTicks::Now()));
+          blink::WebInputEvent::Type::kMouseUp, gfx::PointF(), gfx::PointF(),
+          blink::WebPointerProperties::Button::kBack, 0, 0,
+          base::TimeTicks::Now()));
   RunUntilInputProcessed(
       root->child_at(1)->current_frame_host()->GetRenderWidgetHost());
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index b8ca1b4..00446b57 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -284,43 +284,6 @@
           ? GetContentClient()->browser()->GetUserAgent()
           : user_agent_override);
 
-  // TODO(mkwst): Extract this logic out somewhere that can be shared between
-  // Blink and //content.
-  if (IsFetchMetadataEnabled() && IsOriginSecure(url)) {
-    std::string destination;
-    switch (frame_tree_node->frame_owner_element_type()) {
-      case blink::FrameOwnerElementType::kNone:
-        destination = "document";
-        break;
-      case blink::FrameOwnerElementType::kObject:
-        destination = "object";
-        break;
-      case blink::FrameOwnerElementType::kEmbed:
-        destination = "embed";
-        break;
-      case blink::FrameOwnerElementType::kIframe:
-        destination = "iframe";
-        break;
-      case blink::FrameOwnerElementType::kFrame:
-        destination = "frame";
-        break;
-      case blink::FrameOwnerElementType::kPortal:
-        // TODO(mkwst): "Portal"'s destination isn't actually defined at the
-        // moment. Let's assume it'll be similar to a frame until we decide
-        // otherwise.
-        // https://github.com/w3c/webappsec-fetch-metadata/issues/46
-        destination = "document";
-        break;
-    }
-
-    if (IsFetchMetadataDestinationEnabled()) {
-      headers->SetHeaderIfMissing("Sec-Fetch-Dest", destination.c_str());
-    }
-
-    // `Sec-Fetch-User`, `Sec-Fetch-Site` and `Sec-Fetch-Mode` are covered by
-    // the `network::SetFetchMetadataHeaders` function.
-  }
-
   if (!render_prefs.enable_referrers) {
     *referrer =
         blink::mojom::Referrer(GURL(), network::mojom::ReferrerPolicy::kNever);
@@ -1662,19 +1625,8 @@
   }
 
   auto cross_origin_embedder_policy =
-      network::mojom::CrossOriginEmbedderPolicy::kNone;
+      response_head_->cross_origin_embedder_policy;
   if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation)) {
-    // Parse the Cross-Origin-Opener-Policy header.
-    {
-      std::string header_value;
-      if (response_head_->headers &&
-          response_head_->headers->GetNormalizedHeader(
-              "cross-origin-embedder-policy", &header_value) &&
-          header_value == "require-corp") {
-        cross_origin_embedder_policy =
-            network::mojom::CrossOriginEmbedderPolicy::kRequireCorp;
-      }
-    }
     // https://mikewest.github.io/corpp/#process-navigation-response.
     if (GetParentFrame() &&
         GetParentFrame()->cross_origin_embedder_policy() ==
diff --git a/content/browser/loader/browser_initiated_resource_request.cc b/content/browser/loader/browser_initiated_resource_request.cc
index e24fde1..e88d4aa 100644
--- a/content/browser/loader/browser_initiated_resource_request.cc
+++ b/content/browser/loader/browser_initiated_resource_request.cc
@@ -18,7 +18,6 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "services/network/public/cpp/resource_request.h"
-#include "third_party/blink/public/common/loader/request_destination.h"
 #include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
 
 namespace content {
@@ -36,33 +35,6 @@
              network::features::kFetchMetadataDestination);
 }
 
-void SetFetchMetadataHeadersForBrowserInitiatedRequest(
-    network::ResourceRequest* resource_request) {
-  if (IsFetchMetadataEnabled() && IsOriginSecure(resource_request->url)) {
-    // Sec-Fetch-Mode exposes request's mode.
-    // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header
-    resource_request->headers.SetHeaderIfMissing(
-        "Sec-Fetch-Mode", network::RequestModeToString(resource_request->mode));
-
-    if (IsFetchMetadataDestinationEnabled()) {
-      // Sec-Fetch-Dest exposes request's destination.
-      // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header
-      auto context_type = static_cast<blink::mojom::RequestContextType>(
-          resource_request->fetch_request_context_type);
-      resource_request->headers.SetHeaderIfMissing(
-          "Sec-Fetch-Dest",
-          blink::GetRequestDestinationFromContext(context_type));
-    }
-
-    // `Sec-Fetch-User` header is always false (and therefore omitted) because
-    // this currently does not support navigation requests.
-    // TODO(shimazu): support navigation requests.
-
-    // `Sec-Fetch-Site` is covered elsewhere - by the
-    // network::SetSecFetchSiteHeader function.
-  }
-}
-
 void UpdateAdditionalHeadersForBrowserInitiatedRequest(
     net::HttpRequestHeaders* headers,
     BrowserContext* browser_context,
diff --git a/content/browser/loader/browser_initiated_resource_request.h b/content/browser/loader/browser_initiated_resource_request.h
index 0f30dc4..89df8474 100644
--- a/content/browser/loader/browser_initiated_resource_request.h
+++ b/content/browser/loader/browser_initiated_resource_request.h
@@ -9,10 +9,6 @@
 class HttpRequestHeaders;
 }  // namespace net
 
-namespace network {
-struct ResourceRequest;
-}  // namespace network
-
 namespace blink {
 namespace mojom {
 class RendererPreferences;
@@ -31,11 +27,6 @@
 // experimental-web-platform-features is enabled.
 bool IsFetchMetadataDestinationEnabled();
 
-// Sets Fetch metadata headers on |resource_request| if appropriate:
-// https://w3c.github.io/webappsec-fetch-metadata
-void SetFetchMetadataHeadersForBrowserInitiatedRequest(
-    network::ResourceRequest* resource_request);
-
 // Sets request headers appropriate for browser-initiated resource requests,
 // i.e., requests for navigations and dedicated/shared/service worker
 // scripts.
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index d5ccf21..30135c0c 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -84,6 +84,7 @@
 #include "ppapi/buildflags/buildflags.h"
 #include "services/network/loader_util.h"
 #include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/request_destination.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -276,6 +277,36 @@
     }
   }
 
+  if (frame_tree_node) {
+    switch (frame_tree_node->frame_owner_element_type()) {
+      case blink::FrameOwnerElementType::kNone:
+        new_request->destination =
+            network::mojom::RequestDestination::kDocument;
+        break;
+      case blink::FrameOwnerElementType::kObject:
+        new_request->destination = network::mojom::RequestDestination::kObject;
+        break;
+      case blink::FrameOwnerElementType::kEmbed:
+        new_request->destination = network::mojom::RequestDestination::kEmbed;
+        break;
+      case blink::FrameOwnerElementType::kIframe:
+        new_request->destination = network::mojom::RequestDestination::kIframe;
+        break;
+      case blink::FrameOwnerElementType::kFrame:
+        new_request->destination = network::mojom::RequestDestination::kFrame;
+        break;
+      case blink::FrameOwnerElementType::kPortal:
+        // TODO(mkwst): "Portal"'s destination isn't actually defined at the
+        // moment. Let's assume it'll be similar to a frame until we decide
+        // otherwise.
+        // https://github.com/w3c/webappsec-fetch-metadata/issues/46
+        new_request->destination = network::mojom::RequestDestination::kIframe;
+        break;
+    }
+  } else {
+    new_request->destination = network::mojom::RequestDestination::kDocument;
+  }
+
   if (ui::PageTransitionIsWebTriggerable(
           request_info->common_params->transition)) {
     new_request->trusted_params->has_user_activation =
diff --git a/content/browser/renderer_host/input/autoscroll_browsertest.cc b/content/browser/renderer_host/input/autoscroll_browsertest.cc
index c3dca590..e3a2695 100644
--- a/content/browser/renderer_host/input/autoscroll_browsertest.cc
+++ b/content/browser/renderer_host/input/autoscroll_browsertest.cc
@@ -241,7 +241,7 @@
   const blink::WebGestureEvent* acked_scroll_update =
       scroll_update_watcher->AckedGestureEvent();
   DCHECK(acked_scroll_update);
-  DCHECK(acked_scroll_update->PositionInWidget() != blink::WebFloatPoint());
+  DCHECK(acked_scroll_update->PositionInWidget() != gfx::PointF());
 
   // End autoscroll and check that the GSE generated from autoscroll fling
   // cancelation has non-zero position in widget.
@@ -252,7 +252,7 @@
   const blink::WebGestureEvent* acked_scroll_end =
       scroll_end_watcher->AckedGestureEvent();
   DCHECK(acked_scroll_end);
-  DCHECK(acked_scroll_end->PositionInWidget() != blink::WebFloatPoint());
+  DCHECK(acked_scroll_end->PositionInWidget() != gfx::PointF());
 }
 
 // Checks that wheel scrolling works after autoscroll cancelation.
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index cd504db1..31211db6 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -340,11 +340,12 @@
     if (touch_point->state == blink::WebTouchPoint::kStateMoved) {
       const gfx::Point& last_position = global_touch_position_[touch_point->id];
       touch_point->movement_x =
-          touch_point->PositionInScreen().x - last_position.x();
+          touch_point->PositionInScreen().x() - last_position.x();
       touch_point->movement_y =
-          touch_point->PositionInScreen().y - last_position.y();
+          touch_point->PositionInScreen().y() - last_position.y();
       global_touch_position_[touch_point->id].SetPoint(
-          touch_point->PositionInScreen().x, touch_point->PositionInScreen().y);
+          touch_point->PositionInScreen().x(),
+          touch_point->PositionInScreen().y());
     } else {
       touch_point->movement_x = 0;
       touch_point->movement_y = 0;
@@ -355,8 +356,8 @@
         DCHECK(global_touch_position_.find(touch_point->id) ==
                global_touch_position_.end());
         global_touch_position_[touch_point->id] =
-            gfx::Point(touch_point->PositionInScreen().x,
-                       touch_point->PositionInScreen().y);
+            gfx::Point(touch_point->PositionInScreen().x(),
+                       touch_point->PositionInScreen().y());
       }
     }
   }
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index a1439da..0eb560b 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -1798,10 +1798,10 @@
   ASSERT_EQ(WebInputEvent::kMouseWheel, input_event->GetType());
   const WebMouseWheelEvent* synthetic_wheel =
       static_cast<const WebMouseWheelEvent*>(input_event);
-  EXPECT_EQ(20, synthetic_wheel->PositionInWidget().x);
-  EXPECT_EQ(25, synthetic_wheel->PositionInWidget().y);
-  EXPECT_EQ(20, synthetic_wheel->PositionInScreen().x);
-  EXPECT_EQ(25, synthetic_wheel->PositionInScreen().y);
+  EXPECT_EQ(20, synthetic_wheel->PositionInWidget().x());
+  EXPECT_EQ(25, synthetic_wheel->PositionInWidget().y());
+  EXPECT_EQ(20, synthetic_wheel->PositionInScreen().x());
+  EXPECT_EQ(25, synthetic_wheel->PositionInScreen().y());
   EXPECT_TRUE(synthetic_wheel->GetModifiers() &
               blink::WebInputEvent::kControlKey);
   EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseBegan, synthetic_wheel->phase);
@@ -2194,12 +2194,12 @@
     SimulateMouseEvent(type, 10, 10);
     UpdateDispatchedMessages();
     const WebMouseEvent* sent_event = GetSentWebInputEvent<WebMouseEvent>();
-    EXPECT_EQ(20, sent_event->PositionInWidget().x);
-    EXPECT_EQ(20, sent_event->PositionInWidget().y);
+    EXPECT_EQ(20, sent_event->PositionInWidget().x());
+    EXPECT_EQ(20, sent_event->PositionInWidget().y());
 
     const WebMouseEvent* filter_event = GetFilterWebInputEvent<WebMouseEvent>();
-    EXPECT_EQ(10, filter_event->PositionInWidget().x);
-    EXPECT_EQ(10, filter_event->PositionInWidget().y);
+    EXPECT_EQ(10, filter_event->PositionInWidget().x());
+    EXPECT_EQ(10, filter_event->PositionInWidget().y());
   }
 
  private:
@@ -2221,8 +2221,8 @@
 
   const WebMouseWheelEvent* sent_event =
       GetSentWebInputEvent<WebMouseWheelEvent>();
-  EXPECT_EQ(10, sent_event->PositionInWidget().x);
-  EXPECT_EQ(10, sent_event->PositionInWidget().y);
+  EXPECT_EQ(10, sent_event->PositionInWidget().x());
+  EXPECT_EQ(10, sent_event->PositionInWidget().y());
   EXPECT_EQ(20, sent_event->delta_x);
   EXPECT_EQ(20, sent_event->delta_y);
   EXPECT_EQ(2, sent_event->wheel_ticks_x);
@@ -2230,8 +2230,8 @@
 
   const WebMouseWheelEvent* filter_event =
       GetFilterWebInputEvent<WebMouseWheelEvent>();
-  EXPECT_EQ(5, filter_event->PositionInWidget().x);
-  EXPECT_EQ(5, filter_event->PositionInWidget().y);
+  EXPECT_EQ(5, filter_event->PositionInWidget().x());
+  EXPECT_EQ(5, filter_event->PositionInWidget().y());
   EXPECT_EQ(10, filter_event->delta_x);
   EXPECT_EQ(10, filter_event->delta_y);
   EXPECT_EQ(1, filter_event->wheel_ticks_x);
@@ -2258,33 +2258,33 @@
     const WebTouchEvent* sent_event = GetSentWebInputEvent<WebTouchEvent>();
     ASSERT_EQ(2u, sent_event->touches_length);
     EXPECT_EQ(state, sent_event->touches[0].state);
-    EXPECT_EQ(20, sent_event->touches[0].PositionInWidget().x);
-    EXPECT_EQ(40, sent_event->touches[0].PositionInWidget().y);
-    EXPECT_EQ(10, sent_event->touches[0].PositionInScreen().x);
-    EXPECT_EQ(20, sent_event->touches[0].PositionInScreen().y);
+    EXPECT_EQ(20, sent_event->touches[0].PositionInWidget().x());
+    EXPECT_EQ(40, sent_event->touches[0].PositionInWidget().y());
+    EXPECT_EQ(10, sent_event->touches[0].PositionInScreen().x());
+    EXPECT_EQ(20, sent_event->touches[0].PositionInScreen().y());
     EXPECT_EQ(2 * radius_x_, sent_event->touches[0].radius_x);
     EXPECT_EQ(2 * radius_x_, sent_event->touches[0].radius_y);
 
-    EXPECT_EQ(200, sent_event->touches[1].PositionInWidget().x);
-    EXPECT_EQ(400, sent_event->touches[1].PositionInWidget().y);
-    EXPECT_EQ(100, sent_event->touches[1].PositionInScreen().x);
-    EXPECT_EQ(200, sent_event->touches[1].PositionInScreen().y);
+    EXPECT_EQ(200, sent_event->touches[1].PositionInWidget().x());
+    EXPECT_EQ(400, sent_event->touches[1].PositionInWidget().y());
+    EXPECT_EQ(100, sent_event->touches[1].PositionInScreen().x());
+    EXPECT_EQ(200, sent_event->touches[1].PositionInScreen().y());
     EXPECT_EQ(2 * radius_x_, sent_event->touches[1].radius_x);
     EXPECT_EQ(2 * radius_x_, sent_event->touches[1].radius_y);
 
     const WebTouchEvent* filter_event = GetFilterWebInputEvent<WebTouchEvent>();
     ASSERT_EQ(2u, filter_event->touches_length);
-    EXPECT_EQ(10, filter_event->touches[0].PositionInWidget().x);
-    EXPECT_EQ(20, filter_event->touches[0].PositionInWidget().y);
-    EXPECT_EQ(10, filter_event->touches[0].PositionInScreen().x);
-    EXPECT_EQ(20, filter_event->touches[0].PositionInScreen().y);
+    EXPECT_EQ(10, filter_event->touches[0].PositionInWidget().x());
+    EXPECT_EQ(20, filter_event->touches[0].PositionInWidget().y());
+    EXPECT_EQ(10, filter_event->touches[0].PositionInScreen().x());
+    EXPECT_EQ(20, filter_event->touches[0].PositionInScreen().y());
     EXPECT_EQ(radius_x_, filter_event->touches[0].radius_x);
     EXPECT_EQ(radius_x_, filter_event->touches[0].radius_y);
 
-    EXPECT_EQ(100, filter_event->touches[1].PositionInWidget().x);
-    EXPECT_EQ(200, filter_event->touches[1].PositionInWidget().y);
-    EXPECT_EQ(100, filter_event->touches[1].PositionInScreen().x);
-    EXPECT_EQ(200, filter_event->touches[1].PositionInScreen().y);
+    EXPECT_EQ(100, filter_event->touches[1].PositionInWidget().x());
+    EXPECT_EQ(200, filter_event->touches[1].PositionInWidget().y());
+    EXPECT_EQ(100, filter_event->touches[1].PositionInScreen().x());
+    EXPECT_EQ(200, filter_event->touches[1].PositionInScreen().y());
     EXPECT_EQ(radius_x_, filter_event->touches[1].radius_x);
     EXPECT_EQ(radius_x_, filter_event->touches[1].radius_y);
   }
@@ -2472,10 +2472,10 @@
       const gfx::PointF& orig,
       const gfx::PointF& scaled,
       const base::Optional<gfx::SizeF>& contact_size_scaled) {
-    EXPECT_FLOAT_EQ(scaled.x(), sent_event->PositionInWidget().x);
-    EXPECT_FLOAT_EQ(scaled.y(), sent_event->PositionInWidget().y);
-    EXPECT_FLOAT_EQ(orig.x(), sent_event->PositionInScreen().x);
-    EXPECT_FLOAT_EQ(orig.y(), sent_event->PositionInScreen().y);
+    EXPECT_FLOAT_EQ(scaled.x(), sent_event->PositionInWidget().x());
+    EXPECT_FLOAT_EQ(scaled.y(), sent_event->PositionInWidget().y());
+    EXPECT_FLOAT_EQ(orig.x(), sent_event->PositionInScreen().x());
+    EXPECT_FLOAT_EQ(orig.y(), sent_event->PositionInScreen().y());
 
     base::Optional<gfx::SizeF> event_contact_size = GetContactSize(*sent_event);
     if (event_contact_size && contact_size_scaled) {
@@ -2490,10 +2490,10 @@
       const WebGestureEvent* filter_event,
       const gfx::PointF& orig,
       const base::Optional<gfx::SizeF>& contact_size) {
-    EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInWidget().x);
-    EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInWidget().y);
-    EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInScreen().x);
-    EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInScreen().y);
+    EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInWidget().x());
+    EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInWidget().y());
+    EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInScreen().x());
+    EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInScreen().y());
 
     base::Optional<gfx::SizeF> event_contact_size =
         GetContactSize(*filter_event);
diff --git a/content/browser/renderer_host/input/motion_event_web.cc b/content/browser/renderer_host/input/motion_event_web.cc
index 38b3571..35f500e4 100644
--- a/content/browser/renderer_host/input/motion_event_web.cc
+++ b/content/browser/renderer_host/input/motion_event_web.cc
@@ -96,22 +96,22 @@
 
 float MotionEventWeb::GetX(size_t pointer_index) const {
   DCHECK_LT(pointer_index, GetPointerCount());
-  return event_.touches[pointer_index].PositionInWidget().x;
+  return event_.touches[pointer_index].PositionInWidget().x();
 }
 
 float MotionEventWeb::GetY(size_t pointer_index) const {
   DCHECK_LT(pointer_index, GetPointerCount());
-  return event_.touches[pointer_index].PositionInWidget().y;
+  return event_.touches[pointer_index].PositionInWidget().y();
 }
 
 float MotionEventWeb::GetRawX(size_t pointer_index) const {
   DCHECK_LT(pointer_index, GetPointerCount());
-  return event_.touches[pointer_index].PositionInScreen().x;
+  return event_.touches[pointer_index].PositionInScreen().x();
 }
 
 float MotionEventWeb::GetRawY(size_t pointer_index) const {
   DCHECK_LT(pointer_index, GetPointerCount());
-  return event_.touches[pointer_index].PositionInScreen().y;
+  return event_.touches[pointer_index].PositionInScreen().y();
 }
 
 float MotionEventWeb::GetTouchMajor(size_t pointer_index) const {
diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc b/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
index 07d4b021..b0b9b25 100644
--- a/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
@@ -36,10 +36,10 @@
 
 #define EXPECT_GESTURE_SCROLL_BEGIN_IMPL(event)                    \
   EXPECT_EQ(WebInputEvent::kGestureScrollBegin, event->GetType()); \
-  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x);           \
-  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y);           \
-  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x);     \
-  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y);     \
+  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x());         \
+  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y());         \
+  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x());   \
+  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y());   \
   EXPECT_EQ(scroll_units, event->data.scroll_begin.delta_hint_units);
 
 #define EXPECT_GESTURE_SCROLL_BEGIN(event)                         \
@@ -75,10 +75,10 @@
 #define EXPECT_GESTURE_SCROLL_UPDATE_IMPL(event)                    \
   EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, event->GetType()); \
   EXPECT_EQ(scroll_units, event->data.scroll_update.delta_units);   \
-  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x);            \
-  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y);            \
-  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x);      \
-  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y);
+  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x());          \
+  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y());          \
+  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x());    \
+  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y());
 
 #define EXPECT_GESTURE_SCROLL_UPDATE(event)                        \
   EXPECT_GESTURE_SCROLL_UPDATE_IMPL(event);                        \
@@ -98,10 +98,10 @@
 #define EXPECT_GESTURE_SCROLL_END_IMPL(event)                    \
   EXPECT_EQ(WebInputEvent::kGestureScrollEnd, event->GetType()); \
   EXPECT_EQ(scroll_units, event->data.scroll_end.delta_units);   \
-  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x);         \
-  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y);         \
-  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x);   \
-  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y);
+  EXPECT_EQ(kWheelScrollX, event->PositionInWidget().x());       \
+  EXPECT_EQ(kWheelScrollY, event->PositionInWidget().y());       \
+  EXPECT_EQ(kWheelScrollGlobalX, event->PositionInScreen().x()); \
+  EXPECT_EQ(kWheelScrollGlobalY, event->PositionInScreen().y());
 
 #define EXPECT_GESTURE_SCROLL_END(event)                           \
   EXPECT_GESTURE_SCROLL_END_IMPL(event);                           \
diff --git a/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc b/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
index 08c29b7..3231f779 100644
--- a/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
+++ b/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
@@ -73,8 +73,8 @@
         if (!mouse_wheel_end_dispatch_timer_.IsRunning()) {
           mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
           first_wheel_location_ =
-              gfx::Vector2dF(mouse_wheel_event.PositionInWidget().x,
-                             mouse_wheel_event.PositionInWidget().y);
+              gfx::Vector2dF(mouse_wheel_event.PositionInWidget().x(),
+                             mouse_wheel_event.PositionInWidget().y());
           initial_wheel_event_ = mouse_wheel_event;
           first_scroll_update_ack_state_ =
               FirstScrollUpdateAckState::kNotArrived;
@@ -205,8 +205,8 @@
   // latching sequence is needed or not, and timer-based wheel scroll latching
   // happens only when scroll state is unknown.
   DCHECK(touchpad_scroll_phase_state_ == TOUCHPAD_SCROLL_STATE_UNKNOWN);
-  gfx::Vector2dF current_wheel_location(wheel_event.PositionInWidget().x,
-                                        wheel_event.PositionInWidget().y);
+  gfx::Vector2dF current_wheel_location(wheel_event.PositionInWidget().x(),
+                                        wheel_event.PositionInWidget().y());
   return (current_wheel_location - first_wheel_location_).LengthSquared() <
          kWheelLatchingSlopRegion * kWheelLatchingSlopRegion;
 }
diff --git a/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
index 84482d7..edf8c09 100644
--- a/content/browser/renderer_host/input/scroll_latency_browsertest.cc
+++ b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -301,10 +301,10 @@
 #if !defined(OS_ANDROID)
     // Click on the forward scrollbar button to induce a compositor thread
     // scrollbar scroll.
-    blink::WebFloatPoint scrollbar_forward_button(795, 595);
+    gfx::PointF scrollbar_forward_button(795, 595);
     blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
-        blink::WebInputEvent::kMouseDown, scrollbar_forward_button.x,
-        scrollbar_forward_button.y, 0);
+        blink::WebInputEvent::kMouseDown, scrollbar_forward_button.x(),
+        scrollbar_forward_button.y(), 0);
     mouse_event.button = blink::WebMouseEvent::Button::kLeft;
     mouse_event.SetTimeStamp(base::TimeTicks::Now());
     GetWidgetHost()->ForwardMouseEvent(mouse_event);
@@ -342,10 +342,10 @@
 #if !defined(OS_ANDROID)
     // Click on the scrollbar thumb and drag it twice to induce a compositor
     // thread scrollbar ScrollBegin and ScrollUpdate.
-    blink::WebFloatPoint scrollbar_thumb(795, 30);
+    gfx::PointF scrollbar_thumb(795, 30);
     blink::WebMouseEvent mouse_down = SyntheticWebMouseEventBuilder::Build(
-        blink::WebInputEvent::kMouseDown, scrollbar_thumb.x, scrollbar_thumb.y,
-        0);
+        blink::WebInputEvent::kMouseDown, scrollbar_thumb.x(),
+        scrollbar_thumb.y(), 0);
     mouse_down.button = blink::WebMouseEvent::Button::kLeft;
     mouse_down.SetTimeStamp(base::TimeTicks::Now());
     GetWidgetHost()->ForwardMouseEvent(mouse_down);
@@ -360,21 +360,23 @@
     RunUntilInputProcessed(GetWidgetHost());
 
     blink::WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build(
-        blink::WebInputEvent::kMouseMove, scrollbar_thumb.x,
-        scrollbar_thumb.y + 10, 0);
+        blink::WebInputEvent::kMouseMove, scrollbar_thumb.x(),
+        scrollbar_thumb.y() + 10, 0);
     mouse_move.button = blink::WebMouseEvent::Button::kLeft;
     mouse_move.SetTimeStamp(base::TimeTicks::Now());
     GetWidgetHost()->ForwardMouseEvent(mouse_move);
     RunUntilInputProcessed(GetWidgetHost());
 
-    mouse_move.SetPositionInWidget(scrollbar_thumb.x, scrollbar_thumb.y + 20);
-    mouse_move.SetPositionInScreen(scrollbar_thumb.x, scrollbar_thumb.y + 20);
+    mouse_move.SetPositionInWidget(scrollbar_thumb.x(),
+                                   scrollbar_thumb.y() + 20);
+    mouse_move.SetPositionInScreen(scrollbar_thumb.x(),
+                                   scrollbar_thumb.y() + 20);
     GetWidgetHost()->ForwardMouseEvent(mouse_move);
     RunUntilInputProcessed(GetWidgetHost());
 
     blink::WebMouseEvent mouse_up = SyntheticWebMouseEventBuilder::Build(
-        blink::WebInputEvent::kMouseUp, scrollbar_thumb.x,
-        scrollbar_thumb.y + 20, 0);
+        blink::WebInputEvent::kMouseUp, scrollbar_thumb.x(),
+        scrollbar_thumb.y() + 20, 0);
     mouse_up.button = blink::WebMouseEvent::Button::kLeft;
     mouse_up.SetTimeStamp(base::TimeTicks::Now());
     GetWidgetHost()->ForwardMouseEvent(mouse_up);
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
index 2d1e4a3..7f84fae 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -253,28 +253,26 @@
 
     if (!started_) {
       ASSERT_EQ(touch_event.GetType(), WebInputEvent::kTouchStart);
-      start_.SetPoint(touch_event.touches[0].PositionInWidget().x,
-                      touch_event.touches[0].PositionInWidget().y);
-      last_touch_point_ = gfx::PointF(start_);
+      start_ = touch_event.touches[0].PositionInWidget();
+      last_touch_point_ = start_;
       started_ = true;
     } else {
       ASSERT_NE(touch_event.GetType(), WebInputEvent::kTouchStart);
       ASSERT_NE(touch_event.GetType(), WebInputEvent::kTouchCancel);
 
-      gfx::PointF touch_point(touch_event.touches[0].PositionInWidget().x,
-                              touch_event.touches[0].PositionInWidget().y);
+      gfx::PointF touch_point(touch_event.touches[0].PositionInWidget());
       gfx::Vector2dF delta = touch_point - last_touch_point_;
       total_abs_move_distance_length_ += delta.Length();
 
       if (touch_event.GetType() == WebInputEvent::kTouchEnd)
-        start_to_end_distance_ = touch_point - gfx::PointF(start_);
+        start_to_end_distance_ = touch_point - start_;
 
       last_touch_point_ = touch_point;
     }
   }
 
  protected:
-  gfx::Point start_;
+  gfx::PointF start_;
   gfx::PointF last_touch_point_;
   bool started_;
 };
@@ -313,8 +311,7 @@
       EXPECT_EQ(mouse_event.button, WebMouseEvent::Button::kLeft);
       EXPECT_EQ(mouse_event.click_count, 1);
       EXPECT_EQ(mouse_event.GetType(), WebInputEvent::kMouseDown);
-      start_.SetPoint(mouse_event.PositionInWidget().x,
-                      mouse_event.PositionInWidget().y);
+      start_ = mouse_event.PositionInWidget();
       last_mouse_point_ = start_;
       started_ = true;
     } else {
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
index 01212778..7f4f707 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -99,8 +99,8 @@
   const unsigned num_touches = web_touch.touches_length;
   for (unsigned i = 0; i < num_touches; ++i) {
     const blink::WebTouchPoint* point = &web_touch.touches[i];
-    TouchSetPointer(i, point->PositionInWidget().x, point->PositionInWidget().y,
-                    point->id);
+    TouchSetPointer(i, point->PositionInWidget().x(),
+                    point->PositionInWidget().y(), point->id);
   }
 
   TouchInject(action, num_touches, web_touch.TimeStamp());
@@ -109,8 +109,8 @@
 void SyntheticGestureTargetAndroid::DispatchWebMouseWheelEventToPlatform(
     const WebMouseWheelEvent& web_wheel,
     const ui::LatencyInfo&) {
-  TouchSetScrollDeltas(web_wheel.PositionInWidget().x,
-                       web_wheel.PositionInWidget().y, web_wheel.delta_x,
+  TouchSetScrollDeltas(web_wheel.PositionInWidget().x(),
+                       web_wheel.PositionInWidget().y(), web_wheel.delta_x,
                        web_wheel.delta_y);
   TouchInject(MOTION_EVENT_ACTION_SCROLL, 1, web_wheel.TimeStamp());
 }
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
index dd41deb..bd5d6609 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -92,11 +92,10 @@
     modifiers |= ui::EF_SCROLL_BY_PAGE;
   }
 
-  gfx::PointF location(web_wheel.PositionInWidget().x,
-                       web_wheel.PositionInWidget().y);
   ui::MouseWheelEvent wheel_event(
-      gfx::Vector2d(web_wheel.delta_x, web_wheel.delta_y), location, location,
-      timestamp, modifiers, ui::EF_NONE);
+      gfx::Vector2d(web_wheel.delta_x, web_wheel.delta_y),
+      web_wheel.PositionInWidget(), web_wheel.PositionInWidget(), timestamp,
+      modifiers, ui::EF_NONE);
 
   aura::Window* window = GetWindow();
   wheel_event.ConvertLocationToTarget(window, window->GetRootWindow());
@@ -121,8 +120,8 @@
     if (event_type == ui::ET_GESTURE_PINCH_UPDATE)
       pinch_details.set_scale(web_gesture.data.pinch_update.scale);
 
-    ui::GestureEvent pinch_event(web_gesture.PositionInWidget().x,
-                                 web_gesture.PositionInWidget().y, flags,
+    ui::GestureEvent pinch_event(web_gesture.PositionInWidget().x(),
+                                 web_gesture.PositionInWidget().y(), flags,
                                  ui::EventTimeForNow(), pinch_details);
 
     pinch_event.ConvertLocationToTarget(window, window->GetRootWindow());
@@ -134,9 +133,8 @@
       web_gesture.GetType() == blink::WebInputEvent::kGestureFlingStart
           ? ui::EventMomentumPhase::BEGAN
           : ui::EventMomentumPhase::END;
-  gfx::PointF location(web_gesture.PositionInWidget().x,
-                       web_gesture.PositionInWidget().y);
-  ui::ScrollEvent scroll_event(event_type, location, location,
+  ui::ScrollEvent scroll_event(event_type, web_gesture.PositionInWidget(),
+                               web_gesture.PositionInWidget(),
                                ui::EventTimeForNow(), flags,
                                web_gesture.data.fling_start.velocity_x,
                                web_gesture.data.fling_start.velocity_y, 0, 0, 2,
@@ -159,9 +157,8 @@
     changed_button_flags =
         WebEventButtonToUIEventButtonFlags(web_mouse_event.button);
   }
-  gfx::PointF location(web_mouse_event.PositionInWidget().x,
-                       web_mouse_event.PositionInWidget().y);
-  ui::MouseEvent mouse_event(event_type, location, location,
+  ui::MouseEvent mouse_event(event_type, web_mouse_event.PositionInWidget(),
+                             web_mouse_event.PositionInWidget(),
                              ui::EventTimeForNow(), flags, changed_button_flags,
                              pointer_details);
 
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
index b8e8aff7..27c27cca 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
@@ -53,8 +53,7 @@
     // Check that all touch pointers are within the content bounds.
     for (unsigned i = 0; i < web_touch.touches_length; i++) {
       if (web_touch.touches[i].state == WebTouchPoint::kStatePressed &&
-          !PointIsWithinContents(web_touch.touches[i].PositionInWidget().x,
-                                 web_touch.touches[i].PositionInWidget().y)) {
+          !PointIsWithinContents(web_touch.touches[i].PositionInWidget())) {
         LOG(WARNING)
             << "Touch coordinates are not within content bounds on TouchStart.";
         return;
@@ -64,8 +63,7 @@
   } else if (event.GetType() == WebInputEvent::kMouseWheel) {
     const WebMouseWheelEvent& web_wheel =
         static_cast<const WebMouseWheelEvent&>(event);
-    if (!PointIsWithinContents(web_wheel.PositionInWidget().x,
-                               web_wheel.PositionInWidget().y)) {
+    if (!PointIsWithinContents(web_wheel.PositionInWidget())) {
       LOG(WARNING) << "Mouse wheel position is not within content bounds.";
       return;
     }
@@ -74,8 +72,7 @@
     const WebMouseEvent& web_mouse =
         static_cast<const WebMouseEvent&>(event);
     if (event.GetType() == WebInputEvent::kMouseDown &&
-        !PointIsWithinContents(web_mouse.PositionInWidget().x,
-                               web_mouse.PositionInWidget().y)) {
+        !PointIsWithinContents(web_mouse.PositionInWidget())) {
       LOG(WARNING)
           << "Mouse pointer is not within content bounds on MouseDown.";
       return;
@@ -87,8 +84,7 @@
     // Touchscreen pinches should be injected as touch events.
     DCHECK_EQ(blink::WebGestureDevice::kTouchpad, web_pinch.SourceDevice());
     if (event.GetType() == WebInputEvent::kGesturePinchBegin &&
-        !PointIsWithinContents(web_pinch.PositionInWidget().x,
-                               web_pinch.PositionInWidget().y)) {
+        !PointIsWithinContents(web_pinch.PositionInWidget())) {
       LOG(WARNING)
           << "Pinch coordinates are not within content bounds on PinchBegin.";
       return;
@@ -100,8 +96,7 @@
     // Touchscreen swipe should be injected as touch events.
     DCHECK_EQ(blink::WebGestureDevice::kTouchpad, web_fling.SourceDevice());
     if (event.GetType() == WebInputEvent::kGestureFlingStart &&
-        !PointIsWithinContents(web_fling.PositionInWidget().x,
-                               web_fling.PositionInWidget().y)) {
+        !PointIsWithinContents(web_fling.PositionInWidget())) {
       LOG(WARNING)
           << "Fling coordinates are not within content bounds on FlingStart.";
       return;
@@ -134,10 +129,11 @@
   host_->WaitForInputProcessed(type, source, std::move(callback));
 }
 
-bool SyntheticGestureTargetBase::PointIsWithinContents(int x, int y) const {
+bool SyntheticGestureTargetBase::PointIsWithinContents(
+    gfx::PointF point) const {
   gfx::Rect bounds = host_->GetView()->GetViewBounds();
   bounds -= bounds.OffsetFromOrigin();  // Translate the bounds to (0,0).
-  return bounds.Contains(x, y);
+  return bounds.Contains(point.x(), point.y());
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
index 33a2d55..a1f57138 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "ui/gfx/geometry/point_f.h"
 
 namespace ui {
 class LatencyInfo;
@@ -62,7 +63,7 @@
   RenderWidgetHostImpl* render_widget_host() const { return host_; }
 
  private:
-  bool PointIsWithinContents(int x, int y) const;
+  bool PointIsWithinContents(gfx::PointF point) const;
 
   RenderWidgetHostImpl* host_;
 
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm b/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm
index 6d6e1d9..2398bc8 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm
@@ -89,8 +89,8 @@
   // generate.
   @autoreleasepool {
     NSPoint content_local = NSMakePoint(
-        web_gesture.PositionInWidget().x,
-        [cocoa_view_ frame].size.height - web_gesture.PositionInWidget().y);
+        web_gesture.PositionInWidget().x(),
+        [cocoa_view_ frame].size.height - web_gesture.PositionInWidget().y());
     NSPoint location_in_window = [cocoa_view_ convertPoint:content_local
                                                     toView:nil];
 
diff --git a/content/browser/renderer_host/input/synthetic_mouse_driver.cc b/content/browser/renderer_host/input/synthetic_mouse_driver.cc
index 4e4e6a3..0e3e73c 100644
--- a/content/browser/renderer_host/input/synthetic_mouse_driver.cc
+++ b/content/browser/renderer_host/input/synthetic_mouse_driver.cc
@@ -73,8 +73,8 @@
                                    int key_modifiers) {
   DCHECK_EQ(index, 0);
   mouse_event_ = SyntheticWebMouseEventBuilder::Build(
-      blink::WebInputEvent::kMouseUp, mouse_event_.PositionInWidget().x,
-      mouse_event_.PositionInWidget().y, key_modifiers | last_modifiers_,
+      blink::WebInputEvent::kMouseUp, mouse_event_.PositionInWidget().x(),
+      mouse_event_.PositionInWidget().y(), key_modifiers | last_modifiers_,
       mouse_event_.pointer_type);
   mouse_event_.button =
       SyntheticPointerActionParams::GetWebMouseEventButton(button);
@@ -143,4 +143,4 @@
   return true;
 }
 
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_pen_driver.cc b/content/browser/renderer_host/input/synthetic_pen_driver.cc
index 697ee99..9989a650 100644
--- a/content/browser/renderer_host/input/synthetic_pen_driver.cc
+++ b/content/browser/renderer_host/input/synthetic_pen_driver.cc
@@ -15,9 +15,9 @@
 void SyntheticPenDriver::Leave(int index) {
   DCHECK_EQ(index, 0);
   mouse_event_ = SyntheticWebMouseEventBuilder::Build(
-      blink::WebInputEvent::kMouseLeave, mouse_event_.PositionInWidget().x,
-      mouse_event_.PositionInWidget().y, last_modifiers_,
+      blink::WebInputEvent::kMouseLeave, mouse_event_.PositionInWidget().x(),
+      mouse_event_.PositionInWidget().y(), last_modifiers_,
       mouse_event_.pointer_type);
 }
 
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc
index e5244b9..e5cc676 100644
--- a/content/browser/renderer_host/input/touch_emulator.cc
+++ b/content/browser/renderer_host/input/touch_emulator.cc
@@ -187,8 +187,8 @@
   if (mouse_event.button == WebMouseEvent::Button::kRight &&
       mouse_event.GetType() == WebInputEvent::kMouseDown) {
     client_->ShowContextMenuAtPoint(
-        gfx::Point(mouse_event.PositionInWidget().x,
-                   mouse_event.PositionInWidget().y),
+        gfx::Point(mouse_event.PositionInWidget().x(),
+                   mouse_event.PositionInWidget().y()),
         ui::MENU_SOURCE_MOUSE, target_view);
   }
 
@@ -496,7 +496,7 @@
 
 void TouchEmulator::PinchUpdate(const WebGestureEvent& event) {
   DCHECK(pinch_gesture_active_);
-  float dy = pinch_anchor_.y() - event.PositionInWidget().y;
+  float dy = pinch_anchor_.y() - event.PositionInWidget().y();
   float scale = exp(dy * 0.002f);
   WebGestureEvent pinch_event =
       GetPinchGestureEvent(WebInputEvent::kGesturePinchUpdate, event);
@@ -565,8 +565,8 @@
   // for example when scroll bubbling is taking place. The GestureRecognizer
   // isn't designed to handle that.
   point.SetPositionInWidget(pos_in_root);
-  point.SetPositionInScreen(mouse_event.PositionInScreen().x,
-                            mouse_event.PositionInScreen().y);
+  point.SetPositionInScreen(mouse_event.PositionInScreen().x(),
+                            mouse_event.PositionInScreen().y());
   point.tilt_x = 0;
   point.tilt_y = 0;
   point.pointer_type = blink::WebPointerProperties::PointerType::kTouch;
diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc
index 47bec6f..8c1c13e 100644
--- a/content/browser/renderer_host/input/touch_emulator_unittest.cc
+++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc
@@ -66,8 +66,8 @@
                                  RenderWidgetHostViewBase* target) override {
     forwarded_events_.push_back(event.GetType());
     EXPECT_EQ(1U, event.touches_length);
-    EXPECT_EQ(last_mouse_x_, event.touches[0].PositionInWidget().x);
-    EXPECT_EQ(last_mouse_y_, event.touches[0].PositionInWidget().y);
+    EXPECT_EQ(last_mouse_x_, event.touches[0].PositionInWidget().x());
+    EXPECT_EQ(last_mouse_y_, event.touches[0].PositionInWidget().y());
     const int all_buttons =
         WebInputEvent::kLeftButtonDown | WebInputEvent::kMiddleButtonDown |
         WebInputEvent::kRightButtonDown | WebInputEvent::kBackButtonDown |
diff --git a/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc b/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
index 9bf0d0f..f7bf3a0 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
+++ b/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
@@ -221,11 +221,11 @@
   WebMouseEvent web_event = content::WebMouseEventBuilder::Build(
       motion_event, blink::WebInputEvent::kMouseDown, 1,
       ui::MotionEvent::BUTTON_PRIMARY);
-  EXPECT_EQ(web_event.PositionInWidget().x, p0.pos_x_pixels * kPixToDip);
-  EXPECT_EQ(web_event.PositionInWidget().y, p0.pos_y_pixels * kPixToDip);
-  EXPECT_EQ(web_event.PositionInScreen().x,
+  EXPECT_EQ(web_event.PositionInWidget().x(), p0.pos_x_pixels * kPixToDip);
+  EXPECT_EQ(web_event.PositionInWidget().y(), p0.pos_y_pixels * kPixToDip);
+  EXPECT_EQ(web_event.PositionInScreen().x(),
             (p0.pos_x_pixels + raw_offset_x) * kPixToDip);
-  EXPECT_EQ(web_event.PositionInScreen().y,
+  EXPECT_EQ(web_event.PositionInScreen().y(),
             (p0.pos_y_pixels + raw_offset_y) * kPixToDip);
   EXPECT_EQ(web_event.button, blink::WebPointerProperties::Button::kLeft);
   EXPECT_EQ(web_event.TimeStamp(), event_time);
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
index 80069d5..cfd6502c 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
+++ b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
@@ -665,12 +665,12 @@
   EXPECT_EQ(delta_y * ui::kScrollbarPixelsPerCocoaTick, web_event.delta_y);
   EXPECT_EQ(web_event.delta_y, ui_event.y_offset());
 
-  EXPECT_EQ(11, web_event.PositionInWidget().x);
-  EXPECT_EQ(web_event.PositionInWidget().x, ui_event.x());
+  EXPECT_EQ(11, web_event.PositionInWidget().x());
+  EXPECT_EQ(web_event.PositionInWidget().x(), ui_event.x());
 
   // Both ui:: and blink:: events use an origin at the top-left.
-  EXPECT_EQ(100 - 22, web_event.PositionInWidget().y);
-  EXPECT_EQ(web_event.PositionInWidget().y, ui_event.y());
+  EXPECT_EQ(100 - 22, web_event.PositionInWidget().y());
+  EXPECT_EQ(web_event.PositionInWidget().y(), ui_event.y());
   [window close];
 }
 
@@ -768,8 +768,7 @@
   EXPECT_EQ(blink::WebInputEvent::kTouchStart, touch_event.GetType());
   EXPECT_FALSE(touch_event.hovering);
   EXPECT_EQ(1U, touch_event.touches_length);
-  EXPECT_EQ(blink::WebFloatPoint(6, 9),
-            touch_event.touches[0].PositionInScreen());
+  EXPECT_EQ(gfx::PointF(6, 9), touch_event.touches[0].PositionInScreen());
   EXPECT_EQ(blink::WebTouchPoint::kStatePressed, touch_event.touches[0].state);
   EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
             touch_event.touches[0].pointer_type);
@@ -800,7 +799,7 @@
   blink::WebMouseEvent mouse_event =
       content::WebMouseEventBuilder::Build(mac_event, [window contentView]);
   EXPECT_EQ(blink::WebInputEvent::kMouseDown, mouse_event.GetType());
-  EXPECT_EQ(blink::WebFloatPoint(6, 9), mouse_event.PositionInScreen());
+  EXPECT_EQ(gfx::PointF(6, 9), mouse_event.PositionInScreen());
   EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
             mouse_event.pointer_type);
   EXPECT_EQ(blink::WebMouseEvent::Button::kBack, mouse_event.button);
@@ -822,7 +821,7 @@
   blink::WebMouseEvent mouse_event =
       content::WebMouseEventBuilder::Build(mac_event, [window contentView]);
   EXPECT_EQ(blink::WebInputEvent::kMouseDown, mouse_event.GetType());
-  EXPECT_EQ(blink::WebFloatPoint(6, 9), mouse_event.PositionInScreen());
+  EXPECT_EQ(gfx::PointF(6, 9), mouse_event.PositionInScreen());
   EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
             mouse_event.pointer_type);
   EXPECT_EQ(blink::WebMouseEvent::Button::kForward, mouse_event.button);
diff --git a/content/browser/renderer_host/input/web_input_event_util_unittest.cc b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
index 0a35b02..a45f0eb 100644
--- a/content/browser/renderer_host/input/web_input_event_util_unittest.cc
+++ b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
@@ -111,10 +111,8 @@
   EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, web_event.GetType());
   EXPECT_EQ(0, web_event.GetModifiers());
   EXPECT_EQ(timestamp, web_event.TimeStamp());
-  EXPECT_EQ(pos.x(), web_event.PositionInWidget().x);
-  EXPECT_EQ(pos.y(), web_event.PositionInWidget().y);
-  EXPECT_EQ(raw_pos.x(), web_event.PositionInScreen().x);
-  EXPECT_EQ(raw_pos.y(), web_event.PositionInScreen().y);
+  EXPECT_EQ(pos, web_event.PositionInWidget());
+  EXPECT_EQ(raw_pos, web_event.PositionInScreen());
   EXPECT_EQ(blink::WebGestureDevice::kTouchscreen, web_event.SourceDevice());
   EXPECT_EQ(delta.x(), web_event.data.scroll_update.delta_x);
   EXPECT_EQ(delta.y(), web_event.data.scroll_update.delta_y);
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index ac6e2986..38f1ec87 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1123,8 +1123,8 @@
     const blink::WebMouseEvent& mouse_event,
     const ui::LatencyInfo& latency) {
   TRACE_EVENT2("input", "RenderWidgetHostImpl::ForwardMouseEvent", "x",
-               mouse_event.PositionInWidget().x, "y",
-               mouse_event.PositionInWidget().y);
+               mouse_event.PositionInWidget().x(), "y",
+               mouse_event.PositionInWidget().y());
 
   DCHECK_GE(mouse_event.GetType(), blink::WebInputEvent::kMouseTypeFirst);
   DCHECK_LE(mouse_event.GetType(), blink::WebInputEvent::kMouseTypeLast);
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 7859f24..2a36133e1 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -476,9 +476,7 @@
     // https://crbug.com/934434.
     if (event.GetType() == blink::WebInputEvent::kMouseUp &&
         target == last_mouse_down_target_ &&
-        mouse_down_pre_transformed_coordinate_ ==
-            gfx::PointF(event.PositionInWidget().x,
-                        event.PositionInWidget().y)) {
+        mouse_down_pre_transformed_coordinate_ == event.PositionInWidget()) {
       transformed_point = mouse_down_post_transformed_coordinate_;
       needs_transform_point = false;
     }
@@ -490,8 +488,7 @@
         FindViewAtLocation(root_view, event.PositionInWidget(),
                            viz::EventSource::MOUSE, &transformed_point);
     if (event.GetType() == blink::WebInputEvent::kMouseDown) {
-      mouse_down_pre_transformed_coordinate_.SetPoint(
-          event.PositionInWidget().x, event.PositionInWidget().y);
+      mouse_down_pre_transformed_coordinate_ = event.PositionInWidget();
     }
     if (result.should_query_view)
       return {result.view, true, transformed_point, latched_target};
@@ -1903,9 +1900,8 @@
 
   if (event.GetType() == blink::WebInputEvent::kTouchStart)
     active_touches_ += CountChangedTouchPoints(event);
-  blink::WebFloatPoint position_in_widget = event.touches[0].PositionInWidget();
   gfx::PointF transformed_point = target->TransformRootPointToViewCoordSpace(
-      gfx::PointF(position_in_widget.x, position_in_widget.y));
+      event.touches[0].PositionInWidget());
   DispatchTouchEvent(last_emulated_event_root_view_, target, event,
                      ui::LatencyInfo(), transformed_point, true /* emulated */);
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index b5180b1..08d9d116 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1541,6 +1541,21 @@
 #endif
 
 #if defined(OS_WIN)
+bool RenderWidgetHostViewAura::GetEditContextLayoutBounds(
+    gfx::Rect* control_bounds,
+    gfx::Rect* selection_bounds) {
+  if (text_input_manager_) {
+    const TextInputState* state = text_input_manager_->GetTextInputState();
+    if (state && state->edit_context_control_bounds &&
+        state->edit_context_selection_bounds) {
+      *control_bounds = state->edit_context_control_bounds.value();
+      *selection_bounds = state->edit_context_selection_bounds.value();
+      return true;
+    }
+  }
+  return false;
+}
+
 void RenderWidgetHostViewAura::SetActiveCompositionForAccessibility(
     const gfx::Range& range,
     const base::string16& active_composition_text,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index f8587832..661541b 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -232,6 +232,10 @@
 #endif
 
 #if defined(OS_WIN)
+  // Returns false if the EditContext bounds are not available, else it returns
+  // true with the control and selection bounds for the active EditContext.
+  bool GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                  gfx::Rect* selection_bounds) override;
   // API to notify accessibility whether there is an active composition
   // from TSF or not.
   // It notifies the composition range, composition text and whether the
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
index 83dc6cf..eeb44c8 100644
--- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc
+++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -785,8 +785,7 @@
     // reset any global_mouse_position set previously.
     if (ui_mouse_event.type() == ui::ET_MOUSE_ENTERED ||
         ui_mouse_event.type() == ui::ET_MOUSE_EXITED) {
-      global_mouse_position_.SetPoint(event->PositionInScreen().x,
-                                      event->PositionInScreen().y);
+      global_mouse_position_ = event->PositionInScreen();
     }
 
     // Movement is computed by taking the difference of the new cursor position
@@ -800,14 +799,13 @@
     // to keep the movement calculation as "floor(cur_pos) - floor(last_pos)".
     // Remove the floor here when movement_x/y is changed to double.
     if (!(ui_mouse_event.flags() & ui::EF_UNADJUSTED_MOUSE)) {
-      event->movement_x = gfx::ToFlooredInt(event->PositionInScreen().x) -
+      event->movement_x = gfx::ToFlooredInt(event->PositionInScreen().x()) -
                           gfx::ToFlooredInt(global_mouse_position_.x());
-      event->movement_y = gfx::ToFlooredInt(event->PositionInScreen().y) -
+      event->movement_y = gfx::ToFlooredInt(event->PositionInScreen().y()) -
                           gfx::ToFlooredInt(global_mouse_position_.y());
     }
 
-    global_mouse_position_.SetPoint(event->PositionInScreen().x,
-                                    event->PositionInScreen().y);
+    global_mouse_position_ = event->PositionInScreen();
   }
 
   // This logic is similar to |is_move_to_center_event| check when
@@ -832,10 +830,8 @@
                                  unlocked_global_mouse_position_.y());
     }
   } else {
-    unlocked_mouse_position_.SetPoint(event->PositionInWidget().x,
-                                      event->PositionInWidget().y);
-    unlocked_global_mouse_position_.SetPoint(event->PositionInScreen().x,
-                                             event->PositionInScreen().y);
+    unlocked_mouse_position_ = event->PositionInWidget();
+    unlocked_global_mouse_position_ = event->PositionInScreen();
   }
 }
 
@@ -880,9 +876,9 @@
       // correctly. Workaround is to treat a mouse move or drag event off by
       // atmost 2 px from the center as a move to center event.
       // TODO(crbug.com/991236): figure out a way to avoid the conversion error.
-      return ((std::abs(event.PositionInScreen().x -
+      return ((std::abs(event.PositionInScreen().x() -
                         synthetic_move_position_->x()) <= 2) &&
-              (std::abs(event.PositionInScreen().y -
+              (std::abs(event.PositionInScreen().y() -
                         synthetic_move_position_->y()) <= 2));
     } else {
       return synthetic_move_position_.value() ==
diff --git a/content/browser/resources/media/stats_rates_calculator.js b/content/browser/resources/media/stats_rates_calculator.js
index e875442a..9804e560 100644
--- a/content/browser/resources/media/stats_rates_calculator.js
+++ b/content/browser/resources/media/stats_rates_calculator.js
@@ -6,6 +6,7 @@
   kNone: Object.freeze({postfix: '', multiplier: 1}),
   kMillisecondsFromSeconds:
       Object.freeze({postfix: '_in_ms', multiplier: 1000}),
+  kBytesToBits: Object.freeze({bitrate: true, multiplier: 8}),
 });
 
 class Metric {
@@ -217,10 +218,13 @@
   }
 
   getCalculatedMetricName() {
+    const accumulativeMetric = this.modifier.bitrate ?
+        this.accumulativeMetric + '_in_bits' :
+        this.accumulativeMetric;
     if (this.samplesMetric == 'timestamp') {
-      return '[' + this.accumulativeMetric + '/s]';
+      return '[' + accumulativeMetric + '/s]';
     }
-    return '[' + this.accumulativeMetric + '/' + this.samplesMetric +
+    return '[' + accumulativeMetric + '/' + this.samplesMetric +
         this.modifier.postfix + ']';
   }
 
@@ -407,8 +411,10 @@
         metricCalculators: {
           messagesSent: new RateCalculator('messagesSent', 'timestamp'),
           messagesReceived: new RateCalculator('messagesReceived', 'timestamp'),
-          bytesSent: new RateCalculator('bytesSent', 'timestamp'),
-          bytesReceived: new RateCalculator('bytesReceived', 'timestamp'),
+          bytesSent: new RateCalculator(
+              'bytesSent', 'timestamp', CalculatorModifier.kBytesToBits),
+          bytesReceived: new RateCalculator(
+              'bytesReceived', 'timestamp', CalculatorModifier.kBytesToBits),
         },
       },
       {
@@ -434,15 +440,18 @@
       {
         type: 'outbound-rtp',
         metricCalculators: {
-          bytesSent: new RateCalculator('bytesSent', 'timestamp'),
-          headerBytesSent: new RateCalculator('headerBytesSent', 'timestamp'),
+          bytesSent: new RateCalculator(
+              'bytesSent', 'timestamp', CalculatorModifier.kBytesToBits),
+          headerBytesSent: new RateCalculator(
+              'headerBytesSent', 'timestamp', CalculatorModifier.kBytesToBits),
           packetsSent: new RateCalculator('packetsSent', 'timestamp'),
           totalPacketSendDelay: new RateCalculator(
               'totalPacketSendDelay', 'packetsSent',
               CalculatorModifier.kMillisecondsFromSeconds),
           framesEncoded: new RateCalculator('framesEncoded', 'timestamp'),
-          totalEncodedBytesTarget:
-              new RateCalculator('totalEncodedBytesTarget', 'timestamp'),
+          totalEncodedBytesTarget: new RateCalculator(
+              'totalEncodedBytesTarget', 'timestamp',
+              CalculatorModifier.kBytesToBits),
           totalEncodeTime: new RateCalculator(
               'totalEncodeTime', 'framesEncoded',
               CalculatorModifier.kMillisecondsFromSeconds),
@@ -453,9 +462,11 @@
       {
         type: 'inbound-rtp',
         metricCalculators: {
-          bytesReceived: new RateCalculator('bytesReceived', 'timestamp'),
-          headerBytesReceived:
-              new RateCalculator('headerBytesReceived', 'timestamp'),
+          bytesReceived: new RateCalculator(
+              'bytesReceived', 'timestamp', CalculatorModifier.kBytesToBits),
+          headerBytesReceived: new RateCalculator(
+              'headerBytesReceived', 'timestamp',
+              CalculatorModifier.kBytesToBits),
           packetsReceived: new RateCalculator('packetsReceived', 'timestamp'),
           framesDecoded: new RateCalculator('framesDecoded', 'timestamp'),
           totalDecodeTime: new RateCalculator(
@@ -474,8 +485,10 @@
       {
         type: 'transport',
         metricCalculators: {
-          bytesSent: new RateCalculator('bytesSent', 'timestamp'),
-          bytesReceived: new RateCalculator('bytesReceived', 'timestamp'),
+          bytesSent: new RateCalculator(
+              'bytesSent', 'timestamp', CalculatorModifier.kBytesToBits),
+          bytesReceived: new RateCalculator(
+              'bytesReceived', 'timestamp', CalculatorModifier.kBytesToBits),
           // TODO(https://crbug.com/webrtc/10568): Add packetsSent and
           // packetsReceived once implemented.
         },
@@ -483,8 +496,10 @@
       {
         type: 'candidate-pair',
         metricCalculators: {
-          bytesSent: new RateCalculator('bytesSent', 'timestamp'),
-          bytesReceived: new RateCalculator('bytesReceived', 'timestamp'),
+          bytesSent: new RateCalculator(
+              'bytesSent', 'timestamp', CalculatorModifier.kBytesToBits),
+          bytesReceived: new RateCalculator(
+              'bytesReceived', 'timestamp', CalculatorModifier.kBytesToBits),
           // TODO(https://crbug.com/webrtc/10569): Add packetsSent and
           // packetsReceived once implemented.
           totalRoundTripTime: new RateCalculator(
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc
index cdb5a6d2..628ba9d 100644
--- a/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -168,7 +168,14 @@
     helper_->context_wrapper()->AddObserver(this);
   }
 
-  void TearDown() override { helper_.reset(); }
+  void TearDown() override {
+    helper_.reset();
+    // The helper may post tasks to release resources in |temp_dir_|. Allow
+    // them to run now so that the directory may be deleted.
+    task_environment_.RunUntilIdle();
+    EXPECT_TRUE(!temp_dir_.IsValid() || temp_dir_.Delete())
+        << temp_dir_.GetPath();
+  }
 
   // ServiceWorkerContextCoreObserver overrides.
   void OnRegistrationCompleted(int64_t registration_id,
@@ -205,8 +212,14 @@
   ServiceWorkerContextWrapper* context_wrapper() {
     return helper_->context_wrapper();
   }
+  void GetTemporaryDirectory(base::FilePath* temp_dir) {
+    ASSERT_FALSE(temp_dir_.IsValid());
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    *temp_dir = temp_dir_.GetPath();
+  }
 
  protected:
+  base::ScopedTempDir temp_dir_;
   BrowserTaskEnvironment task_environment_;
   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
   std::vector<NotificationLog> notifications_;
@@ -1062,9 +1075,9 @@
 
   if (is_storage_on_disk()) {
     // Reinitialize the helper to test on-disk storage.
-    base::ScopedTempDir user_data_directory;
-    ASSERT_TRUE(user_data_directory.CreateUniqueTempDir());
-    helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory.GetPath()));
+    base::FilePath user_data_directory;
+    ASSERT_NO_FATAL_FAILURE(GetTemporaryDirectory(&user_data_directory));
+    helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory));
     helper_->context_wrapper()->AddObserver(this);
   }
 
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index aba2b328d..309cff0c 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -569,10 +569,10 @@
     return;
   }
 
-  const net::URLRequestStatus& main_script_status =
-      new_version()->script_cache_map()->main_script_status();
+  int main_script_net_error =
+      new_version()->script_cache_map()->main_script_net_error();
   std::string message;
-  if (main_script_status.status() != net::URLRequestStatus::SUCCESS) {
+  if (main_script_net_error != net::OK) {
     message = new_version()->script_cache_map()->main_script_status_message();
     if (message.empty())
       message = ServiceWorkerConsts::kServiceWorkerFetchScriptError;
@@ -817,13 +817,13 @@
 void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
   DCHECK_EQ(GetUpdateCheckType(),
             UpdateCheckType::kMainScriptDuringStartWorker);
-  net::URLRequestStatus status =
-      new_version()->script_cache_map()->main_script_status();
-  if (!status.is_success()) {
+  int main_script_net_error =
+      new_version()->script_cache_map()->main_script_net_error();
+  if (main_script_net_error != net::OK) {
     // OnPausedAfterDownload() signifies a successful network load, which
     // translates into a script cache error only in the byte-for-byte identical
     // case.
-    DCHECK_EQ(status.error(), net::ERR_FILE_EXISTS);
+    DCHECK_EQ(main_script_net_error, net::ERR_FILE_EXISTS);
 
     BumpLastUpdateCheckTimeIfNeeded();
     ResolvePromise(blink::ServiceWorkerStatusCode::kOk, std::string(),
diff --git a/content/browser/service_worker/service_worker_script_cache_map.cc b/content/browser/service_worker/service_worker_script_cache_map.cc
index 044befb..eaebf5e 100644
--- a/content/browser/service_worker/service_worker_script_cache_map.cc
+++ b/content/browser/service_worker/service_worker_script_cache_map.cc
@@ -76,7 +76,7 @@
     context_->storage()->DoomUncommittedResource(LookupResourceId(url));
     resource_map_.erase(url);
     if (owner_->script_url() == url) {
-      main_script_status_ = net::URLRequestStatus::FromError(net_error);
+      main_script_net_error_ = net_error;
       main_script_status_message_ = status_message;
     }
   } else if (size_bytes >= 0) {
diff --git a/content/browser/service_worker/service_worker_script_cache_map.h b/content/browser/service_worker/service_worker_script_cache_map.h
index df6c9ee8..41089e5e 100644
--- a/content/browser/service_worker/service_worker_script_cache_map.h
+++ b/content/browser/service_worker/service_worker_script_cache_map.h
@@ -16,7 +16,7 @@
 #include "content/browser/service_worker/service_worker_database.h"
 #include "content/common/content_export.h"
 #include "net/base/completion_once_callback.h"
-#include "net/url_request/url_request_status.h"
+#include "net/base/net_errors.h"
 
 class GURL;
 
@@ -57,9 +57,8 @@
 
   size_t size() const { return resource_map_.size(); }
 
-  const net::URLRequestStatus& main_script_status() const {
-    return main_script_status_;
-  }
+  // net::Error code from trying to load the main script resource.
+  int main_script_net_error() const { return main_script_net_error_; }
 
   const std::string& main_script_status_message() const {
     return main_script_status_message_;
@@ -86,7 +85,7 @@
   ServiceWorkerVersion* owner_;
   base::WeakPtr<ServiceWorkerContextCore> context_;
   ResourceMap resource_map_;
-  net::URLRequestStatus main_script_status_;
+  int main_script_net_error_ = net::OK;
   std::string main_script_status_message_;
 
   base::WeakPtrFactory<ServiceWorkerScriptCacheMap> weak_factory_{this};
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc
index 0413b84..30cda120d 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker.cc
+++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -174,6 +174,8 @@
     // https://w3c.github.io/ServiceWorker/#update-algorithm
     resource_request.fetch_request_context_type =
         static_cast<int>(blink::mojom::RequestContextType::SERVICE_WORKER);
+    resource_request.destination =
+        network::mojom::RequestDestination::kServiceWorker;
     resource_request.resource_type =
         static_cast<int>(ResourceType::kServiceWorker);
 
@@ -204,6 +206,7 @@
     // https://w3c.github.io/ServiceWorker/#update-algorithm
     resource_request.fetch_request_context_type =
         static_cast<int>(blink::mojom::RequestContextType::SCRIPT);
+    resource_request.destination = network::mojom::RequestDestination::kScript;
     resource_request.resource_type = static_cast<int>(ResourceType::kScript);
   }
 
@@ -216,8 +219,6 @@
   // for service worker served as modules, and "omit" as a credentials mode:
   // https://html.spec.whatwg.org/C/#fetch-a-single-module-script
 
-  SetFetchMetadataHeadersForBrowserInitiatedRequest(&resource_request);
-
   if (service_worker_loader_helpers::ShouldValidateBrowserCacheForScript(
           is_main_script_, force_bypass_cache_, update_via_cache_,
           time_since_last_check_)) {
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 71cbe4a..5263964 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -42,6 +42,7 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/navigation_policy.h"
 #include "content/public/common/result_codes.h"
+#include "net/base/net_errors.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_response_info.h"
 #include "third_party/blink/public/common/features.h"
@@ -895,8 +896,8 @@
   // If the script load was successful, unpause the worker by calling
   // InitializeGlobalScope(). Otherwise, keep it paused and the original
   // caller of StartWorker() is expected to terminate the worker.
-  net::URLRequestStatus status = script_cache_map()->main_script_status();
-  if (status.is_success())
+  int net_error = script_cache_map()->main_script_net_error();
+  if (net_error == net::OK)
     InitializeGlobalScope();
   // The callback can destroy |this|, so protect it first.
   auto protect = base::WrapRefCounted(this);
@@ -1971,12 +1972,11 @@
   if (start_worker_status_ != blink::ServiceWorkerStatusCode::kOk)
     return start_worker_status_;
 
-  const net::URLRequestStatus& main_script_status =
-      script_cache_map()->main_script_status();
-  if (main_script_status.status() != net::URLRequestStatus::SUCCESS) {
-    if (net::IsCertificateError(main_script_status.error()))
+  int main_script_net_error = script_cache_map()->main_script_net_error();
+  if (main_script_net_error != net::OK) {
+    if (net::IsCertificateError(main_script_net_error))
       return blink::ServiceWorkerStatusCode::kErrorSecurity;
-    switch (main_script_status.error()) {
+    switch (main_script_net_error) {
       case net::ERR_INSECURE_RESPONSE:
       case net::ERR_UNSAFE_REDIRECT:
         return blink::ServiceWorkerStatusCode::kErrorSecurity;
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 3347159..228c8cb 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -196,12 +196,12 @@
   RouteMouseEventAndWaitUntilDispatch(router, root_view, expected_target,
                                       &event);
   EXPECT_TRUE(monitor.EventWasReceived());
-  EXPECT_NEAR(expected_location.x(), monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(expected_location.x(), monitor.event().PositionInWidget().x(),
               kHitTestTolerance)
       << " & original location was " << location.x() << ", " << location.y()
       << " & root_location was " << root_location.x() << ", "
       << root_location.y();
-  EXPECT_NEAR(expected_location.y(), monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(expected_location.y(), monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
 }
 
@@ -1244,9 +1244,9 @@
         const gfx::PointF root_point = rwhv->TransformPointToRootCoordSpaceF(
             touch_event.touches[0].PositionInWidget());
 
-        EXPECT_NEAR(touch_event.touches[0].PositionInWidget().x,
+        EXPECT_NEAR(touch_event.touches[0].PositionInWidget().x(),
                     expected_position.x(), 1.0f);
-        EXPECT_NEAR(touch_event.touches[0].PositionInWidget().y,
+        EXPECT_NEAR(touch_event.touches[0].PositionInWidget().y(),
                     expected_position.y(), 1.0f);
         EXPECT_NEAR(root_point.x(), expected_position_in_root.x(), 1.0f);
         EXPECT_NEAR(root_point.y(), expected_position_in_root.y(), 1.0f);
@@ -1266,9 +1266,9 @@
         const gfx::PointF root_point = rwhv->TransformPointToRootCoordSpaceF(
             gesture_event.PositionInWidget());
 
-        EXPECT_NEAR(gesture_event.PositionInWidget().x, expected_position.x(),
+        EXPECT_NEAR(gesture_event.PositionInWidget().x(), expected_position.x(),
                     1.0f);
-        EXPECT_NEAR(gesture_event.PositionInWidget().y, expected_position.y(),
+        EXPECT_NEAR(gesture_event.PositionInWidget().y(), expected_position.y(),
                     1.0f);
         EXPECT_NEAR(root_point.x(), expected_position_in_root.x(), 1.0f);
         EXPECT_NEAR(root_point.y(), expected_position_in_root.y(), 1.0f);
@@ -1563,10 +1563,10 @@
   const blink::WebTouchEvent& touch_start_event_received =
       static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
   EXPECT_NEAR(touch_start_point_in_child.x(),
-              touch_start_event_received.touches[0].PositionInWidget().x,
+              touch_start_event_received.touches[0].PositionInWidget().x(),
               kCoordinateTolerance);
   EXPECT_NEAR(touch_start_point_in_child.y(),
-              touch_start_event_received.touches[0].PositionInWidget().y,
+              touch_start_event_received.touches[0].PositionInWidget().y(),
               kCoordinateTolerance);
 
   // TouchMove.
@@ -1588,10 +1588,10 @@
   const blink::WebTouchEvent& touch_move_event_received =
       static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
   EXPECT_NEAR(touch_move_point_in_child.x(),
-              touch_move_event_received.touches[0].PositionInWidget().x,
+              touch_move_event_received.touches[0].PositionInWidget().x(),
               kCoordinateTolerance);
   EXPECT_NEAR(touch_move_point_in_child.y(),
-              touch_move_event_received.touches[0].PositionInWidget().y,
+              touch_move_event_received.touches[0].PositionInWidget().y(),
               kCoordinateTolerance);
 
   // TouchEnd.
@@ -1613,10 +1613,10 @@
   const blink::WebTouchEvent& touch_end_event_received =
       static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
   EXPECT_NEAR(touch_move_point_in_child.x(),
-              touch_end_event_received.touches[0].PositionInWidget().x,
+              touch_end_event_received.touches[0].PositionInWidget().x(),
               kCoordinateTolerance);
   EXPECT_NEAR(touch_move_point_in_child.y(),
-              touch_end_event_received.touches[0].PositionInWidget().y,
+              touch_end_event_received.touches[0].PositionInWidget().y(),
               kCoordinateTolerance);
 }
 
@@ -1669,9 +1669,9 @@
 
         const blink::WebGestureEvent& gesture_event =
             static_cast<const blink::WebGestureEvent&>(event);
-        EXPECT_NEAR(expected_position.x(), gesture_event.PositionInWidget().x,
+        EXPECT_NEAR(expected_position.x(), gesture_event.PositionInWidget().x(),
                     kHitTestTolerance);
-        EXPECT_NEAR(expected_position.y(), gesture_event.PositionInWidget().y,
+        EXPECT_NEAR(expected_position.y(), gesture_event.PositionInWidget().y(),
                     kHitTestTolerance);
         return true;
       });
@@ -1913,10 +1913,10 @@
 
           const blink::WebGestureEvent& gesture_event =
               static_cast<const blink::WebGestureEvent&>(event);
-          EXPECT_NEAR(expected_position.x(), gesture_event.PositionInWidget().x,
-                      kHitTestTolerance);
-          EXPECT_NEAR(expected_position.y(), gesture_event.PositionInWidget().y,
-                      kHitTestTolerance);
+          EXPECT_NEAR(expected_position.x(),
+                      gesture_event.PositionInWidget().x(), kHitTestTolerance);
+          EXPECT_NEAR(expected_position.y(),
+                      gesture_event.PositionInWidget().y(), kHitTestTolerance);
           EXPECT_EQ(blink::WebGestureDevice::kTouchscreen,
                     gesture_event.SourceDevice());
           // We expect all gesture events to have non-zero ids otherwise they
@@ -2765,9 +2765,9 @@
   waiter.Wait();
 
   EXPECT_TRUE(main_frame_monitor.EventWasReceived());
-  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().x(),
               kHitTestTolerance);
-  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
   EXPECT_FALSE(child_frame_monitor.EventWasReceived());
 
@@ -2800,9 +2800,9 @@
   child_waiter.Wait();
 
   EXPECT_TRUE(child_frame_monitor.EventWasReceived());
-  EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().x(),
               kHitTestTolerance);
-  EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
 }
 
@@ -3048,9 +3048,9 @@
                                       &child_event);
 
   EXPECT_TRUE(main_frame_monitor.EventWasReceived());
-  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().x(),
               kHitTestTolerance);
-  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
   EXPECT_FALSE(child_frame_monitor.EventWasReceived());
 }
@@ -4248,14 +4248,16 @@
   // The child_view should receive a mouse-move event.
   EXPECT_TRUE(child_monitor.EventWasReceived());
   EXPECT_EQ(blink::WebInputEvent::kMouseMove, child_monitor.event().GetType());
-  EXPECT_NEAR(8, child_monitor.event().PositionInWidget().x, kHitTestTolerance);
-  EXPECT_NEAR(8, child_monitor.event().PositionInWidget().y, kHitTestTolerance);
+  EXPECT_NEAR(8, child_monitor.event().PositionInWidget().x(),
+              kHitTestTolerance);
+  EXPECT_NEAR(8, child_monitor.event().PositionInWidget().y(),
+              kHitTestTolerance);
 
   // The root_view should also receive a mouse-move event.
   EXPECT_TRUE(root_monitor.EventWasReceived());
   EXPECT_EQ(blink::WebInputEvent::kMouseMove, root_monitor.event().GetType());
-  EXPECT_EQ(60, root_monitor.event().PositionInWidget().x);
-  EXPECT_EQ(60, root_monitor.event().PositionInWidget().y);
+  EXPECT_EQ(60, root_monitor.event().PositionInWidget().x());
+  EXPECT_EQ(60, root_monitor.event().PositionInWidget().y());
 
   // CursorMessageFilter::Wait() implicitly tests whether we receive a
   // WidgetHostMsg_SetCursor message from the renderer process, because it does
@@ -4572,9 +4574,9 @@
         const gfx::PointF root_point = rwhv->TransformPointToRootCoordSpaceF(
             gesture_event.PositionInWidget());
 
-        EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().x,
+        EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().x(),
                         expected_position.x());
-        EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().y,
+        EXPECT_FLOAT_EQ(gesture_event.PositionInWidget().y(),
                         expected_position.y());
         EXPECT_FLOAT_EQ(root_point.x(), expected_position_in_root.x());
         EXPECT_FLOAT_EQ(root_point.y(), expected_position_in_root.y());
@@ -6354,8 +6356,8 @@
 
   EXPECT_TRUE(event_monitor.EventWasReceived());
   gfx::Point mouse_down_coords =
-      gfx::Point(event_monitor.event().PositionInWidget().x,
-                 event_monitor.event().PositionInWidget().y);
+      gfx::Point(event_monitor.event().PositionInWidget().x(),
+                 event_monitor.event().PositionInWidget().y());
   event_monitor.ResetEventReceived();
 
   mouse_event.SetType(blink::WebInputEvent::kMouseUp);
@@ -6363,12 +6365,13 @@
   router->RouteMouseEvent(rwhv, &mouse_event, ui::LatencyInfo());
 
   EXPECT_TRUE(event_monitor.EventWasReceived());
-  EXPECT_EQ(mouse_down_coords.x(), event_monitor.event().PositionInWidget().x);
+  EXPECT_EQ(mouse_down_coords.x(),
+            event_monitor.event().PositionInWidget().x());
   // The transform from browser to renderer is (2, 35) in DIP. When we
   // scale that to pixels, it's (3, 53). Note that 35 * 1.5 should be 52.5,
   // so we already lost precision there in the transform from draw quad.
-  EXPECT_NEAR(mouse_down_coords.y(), event_monitor.event().PositionInWidget().y,
-              kHitTestTolerance);
+  EXPECT_NEAR(mouse_down_coords.y(),
+              event_monitor.event().PositionInWidget().y(), kHitTestTolerance);
 }
 
 IN_PROC_BROWSER_TEST_F(SitePerProcessNonIntegerScaleFactorHitTestBrowserTest,
@@ -6432,16 +6435,20 @@
                                       &down_event);
   EXPECT_TRUE(root_monitor.EventWasReceived());
   EXPECT_FALSE(child_monitor.EventWasReceived());
-  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().x, kHitTestTolerance);
-  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().y, kHitTestTolerance);
+  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().x(),
+              kHitTestTolerance);
+  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().y(),
+              kHitTestTolerance);
 
   root_monitor.ResetEventReceived();
   child_monitor.ResetEventReceived();
   RouteMouseEventAndWaitUntilDispatch(router, rwhv_root, rwhv_root, &up_event);
   EXPECT_TRUE(root_monitor.EventWasReceived());
   EXPECT_FALSE(child_monitor.EventWasReceived());
-  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().x, kHitTestTolerance);
-  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().y, kHitTestTolerance);
+  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().x(),
+              kHitTestTolerance);
+  EXPECT_NEAR(25, root_monitor.event().PositionInWidget().y(),
+              kHitTestTolerance);
 
   // Target at child.
   root_monitor.ResetEventReceived();
@@ -6453,9 +6460,9 @@
   // In surface layer hit testing, we should not query client asynchronously.
   EXPECT_FALSE(root_monitor.EventWasReceived());
   EXPECT_TRUE(child_monitor.EventWasReceived());
-  EXPECT_NEAR(90, child_monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(90, child_monitor.event().PositionInWidget().x(),
               kHitTestTolerance);
-  EXPECT_NEAR(100, child_monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(100, child_monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
 
   root_monitor.ResetEventReceived();
@@ -6465,9 +6472,9 @@
   EXPECT_FALSE(root_monitor.EventWasReceived());
   EXPECT_TRUE(child_monitor.EventWasReceived());
   EXPECT_TRUE(child_monitor.EventWasReceived());
-  EXPECT_NEAR(90, child_monitor.event().PositionInWidget().x,
+  EXPECT_NEAR(90, child_monitor.event().PositionInWidget().x(),
               kHitTestTolerance);
-  EXPECT_NEAR(100, child_monitor.event().PositionInWidget().y,
+  EXPECT_NEAR(100, child_monitor.event().PositionInWidget().y(),
               kHitTestTolerance);
 }
 
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index 4d8d2fa..05840b6 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -141,21 +141,6 @@
   manager->OnCertError(std::move(handler));
 }
 
-// static
-void SSLManager::OnSSLCertificateSubresourceError(
-    const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
-    const GURL& url,
-    int render_process_id,
-    int render_frame_id,
-    int net_error,
-    const net::SSLInfo& ssl_info,
-    bool fatal) {
-  OnSSLCertificateError(delegate, false, url,
-                        WebContentsImpl::FromRenderFrameHostID(
-                            render_process_id, render_frame_id),
-                        net_error, ssl_info, fatal);
-}
-
 SSLManager::SSLManager(NavigationControllerImpl* controller)
     : controller_(controller),
       ssl_host_state_delegate_(
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 36e4af3..32306bb 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -56,18 +56,6 @@
       const net::SSLInfo& ssl_info,
       bool fatal);
 
-  // Same as the above, and only works for subresources. Prefer using
-  // OnSSLCertificateError whenever possible (ie when you have access to the
-  // WebContents).
-  static void OnSSLCertificateSubresourceError(
-      const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
-      const GURL& url,
-      int render_process_id,
-      int render_frame_id,
-      int net_error,
-      const net::SSLInfo& ssl_info,
-      bool fatal);
-
   // Construct an SSLManager for the specified tab.
   explicit SSLManager(NavigationControllerImpl* controller);
   virtual ~SSLManager();
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index db7c4010..f4fb82d1 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6852,7 +6852,7 @@
   // Notify for UI updates if the state changes.
   bluetooth_connected_device_count_++;
   if (bluetooth_connected_device_count_ == 1) {
-    NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+    OnIsConnectedToBluetoothDeviceChanged(true);
   }
 }
 
@@ -6866,7 +6866,16 @@
   DCHECK_NE(bluetooth_connected_device_count_, 0u);
   bluetooth_connected_device_count_--;
   if (bluetooth_connected_device_count_ == 0) {
-    NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+    OnIsConnectedToBluetoothDeviceChanged(false);
+  }
+}
+
+void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged(
+    bool is_connected_to_bluetooth_device) {
+  NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+  for (auto& observer : observers_) {
+    observer.OnIsConnectedToBluetoothDeviceChanged(
+        is_connected_to_bluetooth_device);
   }
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 4859c122..46bd431 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1003,6 +1003,11 @@
   void IncrementBluetoothConnectedDeviceCount();
   void DecrementBluetoothConnectedDeviceCount();
 
+  // Notifies the delegate and observers when the connected to Bluetooth device
+  // state changes.
+  void OnIsConnectedToBluetoothDeviceChanged(
+      bool is_connected_to_bluetooth_device);
+
   // Modify the counter of frames in this WebContents actively using serial
   // ports.
   void IncrementSerialActiveFrameCount();
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index ffe3b3f..84919144 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -3298,9 +3298,8 @@
     TestNavigationObserver back_observer(web_contents);
     web_contents->GetRenderWidgetHostWithPageFocus()->ForwardMouseEvent(
         blink::WebMouseEvent(
-            blink::WebInputEvent::kMouseUp, blink::WebFloatPoint(51, 50),
-            blink::WebFloatPoint(51, 50),
-            blink::WebPointerProperties::Button::kBack, 0,
+            blink::WebInputEvent::kMouseUp, gfx::PointF(51, 50),
+            gfx::PointF(51, 50), blink::WebPointerProperties::Button::kBack, 0,
             blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
     back_observer.Wait();
     ASSERT_EQ(url_a, web_contents->GetLastCommittedURL());
@@ -3310,10 +3309,9 @@
     TestNavigationObserver forward_observer(web_contents);
     web_contents->GetRenderWidgetHostWithPageFocus()->ForwardMouseEvent(
         blink::WebMouseEvent(
-            blink::WebInputEvent::kMouseUp, blink::WebFloatPoint(51, 50),
-            blink::WebFloatPoint(51, 50),
-            blink::WebPointerProperties::Button::kForward, 0,
-            blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
+            blink::WebInputEvent::kMouseUp, gfx::PointF(51, 50),
+            gfx::PointF(51, 50), blink::WebPointerProperties::Button::kForward,
+            0, blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
     forward_observer.Wait();
     ASSERT_EQ(url_b, web_contents->GetLastCommittedURL());
   }
@@ -3342,9 +3340,9 @@
   RenderWidgetHostImpl* render_widget_host =
       web_contents->GetRenderWidgetHostWithPageFocus();
   render_widget_host->ForwardMouseEvent(blink::WebMouseEvent(
-      blink::WebInputEvent::kMouseUp, blink::WebFloatPoint(51, 50),
-      blink::WebFloatPoint(51, 50), blink::WebPointerProperties::Button::kBack,
-      0, blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
+      blink::WebInputEvent::kMouseUp, gfx::PointF(51, 50), gfx::PointF(51, 50),
+      blink::WebPointerProperties::Button::kBack, 0,
+      blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
   RunUntilInputProcessed(render_widget_host);
 
   // Wait an action timeout and assert the URL is correct.
@@ -3374,8 +3372,7 @@
 
   render_widget_host = web_contents->GetRenderWidgetHostWithPageFocus();
   render_widget_host->ForwardMouseEvent(blink::WebMouseEvent(
-      blink::WebInputEvent::kMouseUp, blink::WebFloatPoint(51, 50),
-      blink::WebFloatPoint(51, 50),
+      blink::WebInputEvent::kMouseUp, gfx::PointF(51, 50), gfx::PointF(51, 50),
       blink::WebPointerProperties::Button::kForward, 0,
       blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
   RunUntilInputProcessed(render_widget_host);
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 1e0dfde..b4fe54e 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -333,6 +333,12 @@
     last_vertical_scroll_direction_ = scroll_direction;
   }
 
+  void OnIsConnectedToBluetoothDeviceChanged(
+      bool is_connected_to_bluetooth_device) override {
+    ++num_is_connected_to_bluetooth_device_changed_;
+    last_is_connected_to_bluetooth_device_ = is_connected_to_bluetooth_device;
+  }
+
   const GURL& last_url() const { return last_url_; }
   base::Optional<SkColor> last_theme_color() const { return last_theme_color_; }
   base::Optional<viz::VerticalScrollDirection> last_vertical_scroll_direction()
@@ -342,12 +348,20 @@
   bool observed_did_first_visually_non_empty_paint() const {
     return observed_did_first_visually_non_empty_paint_;
   }
+  int num_is_connected_to_bluetooth_device_changed() const {
+    return num_is_connected_to_bluetooth_device_changed_;
+  }
+  bool last_is_connected_to_bluetooth_device() const {
+    return last_is_connected_to_bluetooth_device_;
+  }
 
  private:
   GURL last_url_;
   base::Optional<SkColor> last_theme_color_;
   base::Optional<viz::VerticalScrollDirection> last_vertical_scroll_direction_;
   bool observed_did_first_visually_non_empty_paint_ = false;
+  int num_is_connected_to_bluetooth_device_changed_ = 0;
+  bool last_is_connected_to_bluetooth_device_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
 };
@@ -3584,4 +3598,20 @@
   contents()->SetDelegate(nullptr);
 }
 
+TEST_F(WebContentsImplTest, Bluetooth) {
+  TestWebContentsObserver observer(contents());
+  EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 0);
+  EXPECT_FALSE(contents()->IsConnectedToBluetoothDevice());
+
+  contents()->TestIncrementBluetoothConnectedDeviceCount();
+  EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 1);
+  EXPECT_TRUE(observer.last_is_connected_to_bluetooth_device());
+  EXPECT_TRUE(contents()->IsConnectedToBluetoothDevice());
+
+  contents()->TestDecrementBluetoothConnectedDeviceCount();
+  EXPECT_EQ(observer.num_is_connected_to_bluetooth_device_changed(), 2);
+  EXPECT_FALSE(observer.last_is_connected_to_bluetooth_device());
+  EXPECT_FALSE(contents()->IsConnectedToBluetoothDevice());
+}
+
 }  // namespace content
diff --git a/content/browser/web_package/mock_web_bundle_reader_factory.cc b/content/browser/web_package/mock_web_bundle_reader_factory.cc
index 2f8f1d2..54335d6 100644
--- a/content/browser/web_package/mock_web_bundle_reader_factory.cc
+++ b/content/browser/web_package/mock_web_bundle_reader_factory.cc
@@ -162,10 +162,7 @@
 class MockWebBundleReaderFactoryImpl final : public MockWebBundleReaderFactory {
  public:
   MockWebBundleReaderFactoryImpl() : MockWebBundleReaderFactory() {}
-  ~MockWebBundleReaderFactoryImpl() override {
-    EXPECT_TRUE(!temp_dir_.IsValid() || temp_dir_.Delete())
-        << temp_dir_.GetPath();
-  }
+  ~MockWebBundleReaderFactoryImpl() override = default;
 
   scoped_refptr<WebBundleReader> CreateReader(
       const std::string& test_file_data) override {
diff --git a/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc b/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
index 3652830..56cfa2d 100644
--- a/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
+++ b/content/browser/web_package/web_bundle_url_loader_factory_unittest.cc
@@ -66,13 +66,6 @@
     resource_request_.method = net::HttpRequestHeaders::kGetMethod;
   }
 
-  void TearDown() override {
-    // Shut down the loader factory and allow its cleanup tasks in the
-    // ThreadPool to run so that temp dirs can be deleted.
-    loader_factory_.reset();
-    task_environment_.RunUntilIdle();
-  }
-
   // This function creates a URLLoader with |resource_request_|, and simulates
   // a response for WebBundleReader::ReadResponse with |response| if it
   // is given. |response| can contain nullptr to simulate the case ReadResponse
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc
index a40310c..e9d5fbc8d 100644
--- a/content/browser/worker_host/worker_script_fetch_initiator.cc
+++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -150,10 +150,14 @@
     case ResourceType::kWorker:
       resource_request->fetch_request_context_type =
           static_cast<int>(blink::mojom::RequestContextType::WORKER);
+      resource_request->destination =
+          network::mojom::RequestDestination::kWorker;
       break;
     case ResourceType::kSharedWorker:
       resource_request->fetch_request_context_type =
           static_cast<int>(blink::mojom::RequestContextType::SHARED_WORKER);
+      resource_request->destination =
+          network::mojom::RequestDestination::kSharedWorker;
       break;
     default:
       NOTREACHED() << static_cast<int>(resource_type);
@@ -268,8 +272,6 @@
   UpdateAdditionalHeadersForBrowserInitiatedRequest(
       &resource_request->headers, browser_context,
       /*should_update_existing_headers=*/false, renderer_preferences);
-
-  SetFetchMetadataHeadersForBrowserInitiatedRequest(resource_request);
 }
 
 void WorkerScriptFetchInitiator::CreateScriptLoader(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 4796899..6a9c28a 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -254,6 +254,7 @@
     "//third_party/blink/public:blink_headers",
     "//third_party/blink/public/common",
     "//ui/accessibility",
+    "//ui/events/ipc",
   ]
   deps = [
     ":buildflags",
diff --git a/content/common/background_fetch/background_fetch_types.cc b/content/common/background_fetch/background_fetch_types.cc
index ca509f6..9222c878 100644
--- a/content/common/background_fetch/background_fetch_types.cc
+++ b/content/common/background_fetch/background_fetch_types.cc
@@ -48,12 +48,13 @@
     return nullptr;
   return blink::mojom::FetchAPIRequest::New(
       request->mode, request->is_main_resource_load,
-      request->request_context_type, request->frame_type, request->url,
-      request->method, request->headers, CloneSerializedBlob(request->blob),
-      request->body, request->referrer.Clone(), request->credentials_mode,
-      request->cache_mode, request->redirect_mode, request->integrity,
-      request->priority, request->fetch_window_id, request->keepalive,
-      request->is_reload, request->is_history_navigation);
+      request->request_context_type, request->destination, request->frame_type,
+      request->url, request->method, request->headers,
+      CloneSerializedBlob(request->blob), request->body,
+      request->referrer.Clone(), request->credentials_mode, request->cache_mode,
+      request->redirect_mode, request->integrity, request->priority,
+      request->fetch_window_id, request->keepalive, request->is_reload,
+      request->is_history_navigation);
 }
 
 }  // namespace content
diff --git a/content/common/fetch/fetch_request_type_converters.cc b/content/common/fetch/fetch_request_type_converters.cc
index c02b5f00..3952de1 100644
--- a/content/common/fetch/fetch_request_type_converters.cc
+++ b/content/common/fetch/fetch_request_type_converters.cc
@@ -40,6 +40,8 @@
   output->redirect_mode = input.redirect_mode;
   output->request_context_type = static_cast<blink::mojom::RequestContextType>(
       input.fetch_request_context_type);
+  output->destination =
+      static_cast<network::mojom::RequestDestination>(input.destination);
   output->is_reload = ui::PageTransitionCoreTypeIs(
       static_cast<ui::PageTransition>(input.transition_type),
       ui::PAGE_TRANSITION_RELOAD);
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 6e647839..d247d8b 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -147,10 +147,6 @@
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScrollDirection,
                               blink::kFirstScrollDirection,
                               blink::kLastScrollDirection)
-IPC_ENUM_TRAITS_MIN_MAX_VALUE(
-    ui::input_types::ScrollGranularity,
-    ui::input_types::ScrollGranularity::kFirstScrollGranularity,
-    ui::input_types::ScrollGranularity::kMaxValue)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyDisposition,
                           blink::mojom::FeaturePolicyDisposition::kMaxValue)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FrameVisibility,
diff --git a/content/common/input/event_with_latency_info_unittest.cc b/content/common/input/event_with_latency_info_unittest.cc
index 53c46856..a5cdfa19 100644
--- a/content/common/input/event_with_latency_info_unittest.cc
+++ b/content/common/input/event_with_latency_info_unittest.cc
@@ -332,8 +332,8 @@
   Coalesce(mouse_wheel_0, &mouse_wheel_1);
 
   // Coalesced event has the position of the most recent event.
-  EXPECT_EQ(1, mouse_wheel_1.event.PositionInWidget().x);
-  EXPECT_EQ(1, mouse_wheel_1.event.PositionInWidget().y);
+  EXPECT_EQ(1, mouse_wheel_1.event.PositionInWidget().x());
+  EXPECT_EQ(1, mouse_wheel_1.event.PositionInWidget().y());
 
   // deltaX/Y, wheelTicksX/Y, and movementX/Y of the coalesced event are
   // calculated properly.
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom
index 2f161f8..19aa8ca 100644
--- a/content/common/input/input_handler.mojom
+++ b/content/common/input/input_handler.mojom
@@ -13,6 +13,7 @@
 import "ui/base/ime/mojom/ime_types.mojom";
 import "ui/events/mojom/event.mojom";
 import "ui/events/mojom/event_constants.mojom";
+import "ui/events/mojom/scroll_granularity.mojom";
 import "ui/gfx/geometry/mojom/geometry.mojom";
 import "ui/gfx/range/mojom/range.mojom";
 import "ui/latency/mojom/latency_info.mojom";
@@ -81,7 +82,7 @@
 struct ScrollData {
   float delta_x;
   float delta_y;
-  ScrollGranularity delta_units;
+  ui.mojom.ScrollGranularity delta_units;
   bool target_viewport;
   InertialPhaseState inertial_phase;
   bool synthetic;
diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc
index 54f11ee6..c6d23bf 100644
--- a/content/common/input/synthetic_web_input_event_builders.cc
+++ b/content/common/input/synthetic_web_input_event_builders.cc
@@ -149,8 +149,8 @@
   WebGestureEvent result =
       Build(WebInputEvent::kGesturePinchUpdate, source_device, modifiers);
   result.data.pinch_update.scale = scale;
-  result.SetPositionInWidget(blink::WebFloatPoint(anchor_x, anchor_y));
-  result.SetPositionInScreen(blink::WebFloatPoint(anchor_x, anchor_y));
+  result.SetPositionInWidget(gfx::PointF(anchor_x, anchor_y));
+  result.SetPositionInScreen(gfx::PointF(anchor_x, anchor_y));
   return result;
 }
 
diff --git a/content/common/input/synthetic_web_input_event_builders_unittest.cc b/content/common/input/synthetic_web_input_event_builders_unittest.cc
index 1c225e7..e5f6ca9 100644
--- a/content/common/input/synthetic_web_input_event_builders_unittest.cc
+++ b/content/common/input/synthetic_web_input_event_builders_unittest.cc
@@ -6,7 +6,6 @@
 #include "content/common/input/web_touch_event_traits.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using blink::WebFloatPoint;
 using blink::WebInputEvent;
 using blink::WebTouchEvent;
 using blink::WebTouchPoint;
@@ -20,21 +19,21 @@
   EXPECT_EQ(1U, event.touches_length);
   EXPECT_EQ(0, event.touches[0].id);
   EXPECT_EQ(WebTouchPoint::kStatePressed, event.touches[0].state);
-  EXPECT_EQ(WebFloatPoint(1, 2), event.touches[0].PositionInWidget());
+  EXPECT_EQ(gfx::PointF(1, 2), event.touches[0].PositionInWidget());
   event.ResetPoints();
 
   event.PressPoint(3, 4);
   EXPECT_EQ(2U, event.touches_length);
   EXPECT_EQ(1, event.touches[1].id);
   EXPECT_EQ(WebTouchPoint::kStatePressed, event.touches[1].state);
-  EXPECT_EQ(WebFloatPoint(3, 4), event.touches[1].PositionInWidget());
+  EXPECT_EQ(gfx::PointF(3, 4), event.touches[1].PositionInWidget());
   event.ResetPoints();
 
   event.MovePoint(1, 5, 6);
   EXPECT_EQ(2U, event.touches_length);
   EXPECT_EQ(1, event.touches[1].id);
   EXPECT_EQ(WebTouchPoint::kStateMoved, event.touches[1].state);
-  EXPECT_EQ(WebFloatPoint(5, 6), event.touches[1].PositionInWidget());
+  EXPECT_EQ(gfx::PointF(5, 6), event.touches[1].PositionInWidget());
   event.ResetPoints();
 
   event.ReleasePoint(0);
@@ -47,7 +46,7 @@
   EXPECT_EQ(1U, event.touches_length);
   EXPECT_EQ(1, event.touches[1].id);
   EXPECT_EQ(WebTouchPoint::kStateMoved, event.touches[1].state);
-  EXPECT_EQ(WebFloatPoint(7, 8), event.touches[1].PositionInWidget());
+  EXPECT_EQ(gfx::PointF(7, 8), event.touches[1].PositionInWidget());
   EXPECT_EQ(WebTouchPoint::kStateUndefined, event.touches[0].state);
   event.ResetPoints();
 
@@ -55,7 +54,7 @@
   EXPECT_EQ(2U, event.touches_length);
   EXPECT_EQ(2, event.touches[0].id);
   EXPECT_EQ(WebTouchPoint::kStatePressed, event.touches[0].state);
-  EXPECT_EQ(WebFloatPoint(9, 10), event.touches[0].PositionInWidget());
+  EXPECT_EQ(gfx::PointF(9, 10), event.touches[0].PositionInWidget());
 }
 
 }  // namespace content
diff --git a/content/common/input_messages.h b/content/common/input_messages.h
index 0616398c..66e08a0a 100644
--- a/content/common/input_messages.h
+++ b/content/common/input_messages.h
@@ -30,6 +30,7 @@
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/public/platform/web_pointer_properties.h"
 #include "ui/events/blink/did_overscroll_params.h"
+#include "ui/events/ipc/ui_events_param_traits_macros.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d_f.h"
diff --git a/content/common/native_types.mojom b/content/common/native_types.mojom
index 0796a31..7906e355 100644
--- a/content/common/native_types.mojom
+++ b/content/common/native_types.mojom
@@ -68,9 +68,6 @@
 enum GestureDevice;
 
 [Native]
-enum ScrollGranularity;
-
-[Native]
 enum InertialPhaseState;
 
 [Native]
diff --git a/content/common/text_input_state.cc b/content/common/text_input_state.cc
index c08a3309..d7bd82f 100644
--- a/content/common/text_input_state.cc
+++ b/content/common/text_input_state.cc
@@ -10,4 +10,6 @@
 
 TextInputState::TextInputState(const TextInputState& other) = default;
 
+TextInputState::~TextInputState() = default;
+
 }  //  namespace content
diff --git a/content/common/text_input_state.h b/content/common/text_input_state.h
index 2ce7f20c..11c2c3f1 100644
--- a/content/common/text_input_state.h
+++ b/content/common/text_input_state.h
@@ -5,11 +5,13 @@
 #ifndef CONTENT_COMMON_TEXT_INPUT_STATE_H_
 #define CONTENT_COMMON_TEXT_INPUT_STATE_H_
 
+#include "base/optional.h"
 #include "base/strings/string16.h"
 #include "content/common/content_export.h"
 #include "ui/base/ime/text_input_action.h"
 #include "ui/base/ime/text_input_mode.h"
 #include "ui/base/ime/text_input_type.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace content {
 
@@ -19,6 +21,7 @@
 struct CONTENT_EXPORT TextInputState {
   TextInputState();
   TextInputState(const TextInputState& other);
+  ~TextInputState();
 
   // Type of the input field.
   ui::TextInputType type = ui::TEXT_INPUT_TYPE_NONE;
@@ -62,6 +65,13 @@
 
   // Whether or not this is a reply to a request from IME.
   bool reply_to_request = false;
+
+  // Store control and selection bounds of EditContext.
+  // These optionals will be nullopts if there isn't any active EditContext.
+  // For non EditContext scenarios, the bounds are returned via
+  // |GetCompositionCharacterBounds|
+  base::Optional<gfx::Rect> edit_context_control_bounds;
+  base::Optional<gfx::Rect> edit_context_selection_bounds;
 };
 
 }  // namespace content
diff --git a/content/common/widget_messages.h b/content/common/widget_messages.h
index dbd1115f..575cea9 100644
--- a/content/common/widget_messages.h
+++ b/content/common/widget_messages.h
@@ -95,6 +95,8 @@
   IPC_STRUCT_TRAITS_MEMBER(show_ime_if_needed)
   IPC_STRUCT_TRAITS_MEMBER(always_hide_ime)
   IPC_STRUCT_TRAITS_MEMBER(reply_to_request)
+  IPC_STRUCT_TRAITS_MEMBER(edit_context_control_bounds)
+  IPC_STRUCT_TRAITS_MEMBER(edit_context_selection_bounds)
 IPC_STRUCT_TRAITS_END()
 
 //
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index fbb8227..b8407d7 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -195,6 +195,9 @@
       gpu_service->gpu_feature_info(),
       gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
       gpu_service->gpu_memory_buffer_factory(), std::move(overlay_factory_cb)));
+  for (auto& receiver : pending_service_receivers_)
+    BindServiceInterface(std::move(receiver));
+  pending_service_receivers_.clear();
 
   if (GetContentClient()->gpu())  // Null in tests.
     GetContentClient()->gpu()->GpuServiceInitialized();
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index ad5c48f4..4af569b 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -102,9 +102,13 @@
 
   viz::VizMainImpl viz_main_;
 
-  // ServiceFactory for service_manager::Service hosting.
+  // ServiceFactory for Mojo service hosting.
   std::unique_ptr<GpuServiceFactory> service_factory_;
 
+  // A queue of incoming service interface requests received prior to
+  // |service_factory_| initialization.
+  std::vector<mojo::GenericPendingReceiver> pending_service_receivers_;
+
   blink::AssociatedInterfaceRegistry associated_interfaces_;
 
   // A closure which quits the main message loop.
diff --git a/content/gpu/gpu_child_thread_receiver_bindings.cc b/content/gpu/gpu_child_thread_receiver_bindings.cc
index 567e660e..5248ec8 100644
--- a/content/gpu/gpu_child_thread_receiver_bindings.cc
+++ b/content/gpu/gpu_child_thread_receiver_bindings.cc
@@ -20,6 +20,11 @@
 
 void GpuChildThread::BindServiceInterface(
     mojo::GenericPendingReceiver receiver) {
+  if (!service_factory_) {
+    pending_service_receivers_.push_back(std::move(receiver));
+    return;
+  }
+
   if (auto shape_detection_receiver =
           receiver.As<shape_detection::mojom::ShapeDetectionService>()) {
     static base::NoDestructor<shape_detection::ShapeDetectionService> service{
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index b3c757d5..f68e51f9 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -448,6 +448,10 @@
   // Called when an audio change occurs.
   virtual void OnAudioStateChanged(bool audible) {}
 
+  // Called when the connected to Bluetooth device state changes.
+  virtual void OnIsConnectedToBluetoothDeviceChanged(
+      bool is_connected_to_bluetooth_device) {}
+
   // Invoked when the WebContents is muted/unmuted.
   virtual void DidUpdateAudioMutingState(bool muted) {}
 
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc
index 594776b..77f8cb2 100644
--- a/content/public/test/mock_render_thread.cc
+++ b/content/public/test/mock_render_thread.cc
@@ -225,14 +225,14 @@
   return blink::WebString();
 }
 
-bool MockRenderThread::IsUseZoomForDSF() {
-  return zoom_for_dsf_;
-}
-
 const blink::UserAgentMetadata& MockRenderThread::GetUserAgentMetadata() {
   return kUserAgentMetadata;
 }
 
+bool MockRenderThread::IsUseZoomForDSF() {
+  return zoom_for_dsf_;
+}
+
 #if defined(OS_WIN)
 void MockRenderThread::PreCacheFont(const LOGFONT& log_font) {
 }
diff --git a/content/public/test/web_contents_tester.h b/content/public/test/web_contents_tester.h
index b21361d54..33eed825 100644
--- a/content/public/test/web_contents_tester.h
+++ b/content/public/test/web_contents_tester.h
@@ -177,10 +177,9 @@
   // Sets the last active time.
   virtual void SetLastActiveTime(base::TimeTicks last_active_time) = 0;
 
-  // Setting this to true will make IsConnectedToBluetoothDevice() return true,
-  // setting it to false will make the value use the logic from WebContentsImpl.
-  virtual void SetIsConnectedToBluetoothDevice(
-      bool is_connected_to_bluetooth_device) = 0;
+  // Increments/decrements the number of connected Bluetooth devices.
+  virtual void TestIncrementBluetoothConnectedDeviceCount() = 0;
+  virtual void TestDecrementBluetoothConnectedDeviceCount() = 0;
 };
 
 }  // namespace content
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index c771eda..342036f1d 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -1119,6 +1119,10 @@
                                       role);
     }
 
+    // Presence of other ARIA attributes.
+    if (src.HasAriaAttribute())
+      dst->AddBoolAttribute(ax::mojom::BoolAttribute::kHasAriaAttribute, true);
+
     // Frames and iframes.
     WebFrame* frame = WebFrame::FromFrameOwnerElement(element);
     if (frame) {
diff --git a/content/renderer/input/input_event_prediction_unittest.cc b/content/renderer/input/input_event_prediction_unittest.cc
index ebac5a55..afc0a1e 100644
--- a/content/renderer/input/input_event_prediction_unittest.cc
+++ b/content/renderer/input/input_event_prediction_unittest.cc
@@ -321,8 +321,8 @@
   // change.
   const WebMouseEvent& event =
       static_cast<const blink::WebMouseEvent&>(coalesced_event.Event());
-  EXPECT_EQ(event.PositionInWidget().x, 13);
-  EXPECT_EQ(event.PositionInWidget().y, 7);
+  EXPECT_EQ(event.PositionInWidget().x(), 13);
+  EXPECT_EQ(event.PositionInWidget().y(), 7);
 }
 
 // Test that when dt > maxResampling, resampling is cut off .
@@ -362,8 +362,8 @@
 
     const WebMouseEvent& event =
         static_cast<const blink::WebMouseEvent&>(coalesced_event.Event());
-    EXPECT_GT(event.PositionInWidget().x, 13);
-    EXPECT_LT(event.PositionInWidget().y, 7);
+    EXPECT_GT(event.PositionInWidget().x(), 13);
+    EXPECT_LT(event.PositionInWidget().y(), 7);
     EXPECT_EQ(event.TimeStamp(), frame_time);
 
     EXPECT_EQ(coalesced_event.PredictedEventSize(), 3u);
@@ -389,8 +389,8 @@
     // the predictor
     const WebMouseEvent& event =
         static_cast<const blink::WebMouseEvent&>(coalesced_event.Event());
-    EXPECT_GT(event.PositionInWidget().x, 14);
-    EXPECT_LT(event.PositionInWidget().y, 6);
+    EXPECT_GT(event.PositionInWidget().x(), 14);
+    EXPECT_LT(event.PositionInWidget().y(), 6);
     EXPECT_EQ(event.TimeStamp(), event_time + predictor_max_resample_time);
 
     EXPECT_EQ(coalesced_event.PredictedEventSize(), 3u);
diff --git a/content/renderer/input/render_widget_input_handler.cc b/content/renderer/input/render_widget_input_handler.cc
index adf492ef..aa41e47 100644
--- a/content/renderer/input/render_widget_input_handler.cc
+++ b/content/renderer/input/render_widget_input_handler.cc
@@ -363,8 +363,8 @@
     const WebMouseEvent& mouse_event =
         static_cast<const WebMouseEvent&>(input_event);
     TRACE_EVENT2("renderer", "HandleMouseMove", "x",
-                 mouse_event.PositionInWidget().x, "y",
-                 mouse_event.PositionInWidget().y);
+                 mouse_event.PositionInWidget().x(), "y",
+                 mouse_event.PositionInWidget().y());
 
     prevent_default = delegate_->WillHandleMouseEvent(mouse_event);
 
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 3372c38..cde88b5 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -67,6 +67,7 @@
 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
 #include "third_party/blink/public/platform/file_path_conversion.h"
 #include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_http_load_info.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_url.h"
@@ -613,10 +614,7 @@
     response_override = extra_data->TakeNavigationResponseOverrideOwnership();
   }
 
-  // TODO(domfarolino): Retrieve the referrer in the form of a referrer member
-  // instead of the header field. See https://crbug.com/850813.
-  GURL referrer_url(
-      request.HttpHeaderField(WebString::FromASCII("Referer")).Latin1());
+  GURL referrer_url = blink::WebStringToGURL(request.ReferrerString());
   const std::string& method = request.HttpMethod().Latin1();
 
   // TODO(brettw) this should take parameter encoding into account when
@@ -726,6 +724,7 @@
   resource_request->cors_preflight_policy = request.GetCorsPreflightPolicy();
   resource_request->skip_service_worker = request.GetSkipServiceWorker();
   resource_request->mode = request.GetMode();
+  resource_request->destination = request.GetRequestDestination();
   resource_request->credentials_mode = request.GetCredentialsMode();
   resource_request->redirect_mode = request.GetRedirectMode();
   resource_request->fetch_integrity =
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.cc b/content/renderer/loader/web_worker_fetch_context_impl.cc
index f84a52e..776a03e 100644
--- a/content/renderer/loader/web_worker_fetch_context_impl.cc
+++ b/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -465,8 +465,8 @@
     request.SetUrl(g_rewrite_url(request.Url().GetString().Utf8(), false));
 
   if (!renderer_preferences_.enable_referrers) {
-    request.SetHttpReferrer(blink::WebString(),
-                            network::mojom::ReferrerPolicy::kNever);
+    request.SetReferrerString(blink::WebString());
+    request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
   }
 }
 
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
index 22b73c5..328fead 100644
--- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
+++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -335,7 +335,7 @@
     if (bit_depth == 10) {
       if (capabilities.image_xr30)
         return media::GpuVideoAcceleratorFactories::OutputFormat::XR30;
-      else if (capabilities.image_xb30)
+      else if (capabilities.image_ab30)
         return media::GpuVideoAcceleratorFactories::OutputFormat::XB30;
     }
 #endif
diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc
index 82e73f97..2e09ff8 100644
--- a/content/renderer/pepper/event_conversion.cc
+++ b/content/renderer/pepper/event_conversion.cc
@@ -236,17 +236,17 @@
         return;
     }
   }
-  result.mouse_position.x = mouse_event.PositionInWidget().x;
-  result.mouse_position.y = mouse_event.PositionInWidget().y;
+  result.mouse_position.x = mouse_event.PositionInWidget().x();
+  result.mouse_position.y = mouse_event.PositionInWidget().y();
   result.mouse_click_count = mouse_event.click_count;
 
   if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) {
     if (mouse_event.GetType() == WebInputEvent::kMouseMove &&
         *in_out_last_mouse_position) {
-      result.mouse_movement.x =
-          mouse_event.PositionInScreen().x - (*in_out_last_mouse_position)->x();
-      result.mouse_movement.y =
-          mouse_event.PositionInScreen().y - (*in_out_last_mouse_position)->y();
+      result.mouse_movement.x = mouse_event.PositionInScreen().x() -
+                                (*in_out_last_mouse_position)->x();
+      result.mouse_movement.y = mouse_event.PositionInScreen().y() -
+                                (*in_out_last_mouse_position)->y();
     }
     *in_out_last_mouse_position =
         std::make_unique<gfx::PointF>(mouse_event.PositionInScreen());
@@ -305,8 +305,8 @@
     }
     PP_TouchPoint pp_pt;
     pp_pt.id = touch_point.id;
-    pp_pt.position.x = touch_point.PositionInWidget().x;
-    pp_pt.position.y = touch_point.PositionInWidget().y;
+    pp_pt.position.x = touch_point.PositionInWidget().x();
+    pp_pt.position.y = touch_point.PositionInWidget().y();
     pp_pt.radius.x = touch_point.radius_x;
     pp_pt.radius.y = touch_point.radius_y;
     pp_pt.rotation_angle = touch_point.rotation_angle;
diff --git a/content/renderer/pepper/event_conversion_unittest.cc b/content/renderer/pepper/event_conversion_unittest.cc
index edb8d4e..29af5d53 100644
--- a/content/renderer/pepper/event_conversion_unittest.cc
+++ b/content/renderer/pepper/event_conversion_unittest.cc
@@ -30,10 +30,10 @@
       ASSERT_NE(j, actual.touches_length);
       EXPECT_EQ(expected.touches[i].id, actual.touches[j].id);
       EXPECT_EQ(expected.touches[i].state, actual.touches[j].state);
-      EXPECT_EQ(expected.touches[i].PositionInWidget().x,
-                actual.touches[j].PositionInWidget().x);
-      EXPECT_EQ(expected.touches[i].PositionInWidget().y,
-                actual.touches[j].PositionInWidget().y);
+      EXPECT_EQ(expected.touches[i].PositionInWidget().x(),
+                actual.touches[j].PositionInWidget().x());
+      EXPECT_EQ(expected.touches[i].PositionInWidget().y(),
+                actual.touches[j].PositionInWidget().y());
       EXPECT_EQ(expected.touches[i].radius_x, actual.touches[j].radius_x);
       EXPECT_EQ(expected.touches[i].radius_y, actual.touches[j].radius_y);
       EXPECT_EQ(expected.touches[i].rotation_angle,
@@ -162,8 +162,8 @@
   ASSERT_EQ(1U, pp_events.size());
   const ppapi::InputEventData& pp_event = pp_events[0];
   ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
-  ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x);
-  ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y);
+  ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x());
+  ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
   ASSERT_EQ(pp_event.mouse_movement.x, 0);
   ASSERT_EQ(pp_event.mouse_movement.y, 0);
   if (last_mouse_position) {
@@ -175,8 +175,8 @@
       blink::WebInputEvent::kMouseMove, 123, 188, 0);
   CreateInputEventData(mouse_event, &last_mouse_position, &pp_events);
   ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
-  ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x);
-  ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y);
+  ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x());
+  ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
   ASSERT_EQ(pp_event.mouse_movement.x, 23);
   ASSERT_EQ(pp_event.mouse_movement.y, -12);
 }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 80bc4ed..e464342 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -529,8 +529,7 @@
   DCHECK(!info->url_request.RequestorOrigin().IsNull());
 
   blink::mojom::ReferrerPtr referrer = blink::mojom::Referrer::New(
-      GURL(info->url_request.HttpHeaderField(WebString::FromUTF8("Referer"))
-               .Latin1()),
+      blink::WebStringToGURL(info->url_request.ReferrerString()),
       info->url_request.GetReferrerPolicy());
 
   // No history-navigation is expected to happen.
@@ -4352,7 +4351,9 @@
   } else {
     params.url = url;
   }
-  params.referrer = RenderViewImpl::GetReferrerFromRequest(frame_, request);
+
+  params.referrer.url = blink::WebStringToGURL(request.ReferrerString());
+  params.referrer.policy = request.GetReferrerPolicy();
   params.initiator_origin = request.RequestorOrigin();
   if (request.GetSuggestedFilename().has_value())
     params.suggested_name = request.GetSuggestedFilename()->Utf16();
@@ -4978,9 +4979,10 @@
     blink::WebURLRequest& request,
     ResourceType resource_type,
     ui::PageTransition transition_type) {
-  if (render_view_->renderer_preferences_.enable_do_not_track)
+  if (render_view_->renderer_preferences_.enable_do_not_track) {
     request.SetHttpHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
                                "1");
+  }
 
   ApplyFilePathAlias(&request);
   GURL new_url;
@@ -5053,9 +5055,10 @@
   request.SetHasUserGesture(
       WebUserGestureIndicator::IsProcessingUserGesture(frame_));
 
-  if (!render_view_->renderer_preferences_.enable_referrers)
-    request.SetHttpReferrer(WebString(),
-                            network::mojom::ReferrerPolicy::kNever);
+  if (!render_view_->renderer_preferences_.enable_referrers) {
+    request.SetReferrerString(WebString());
+    request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
+  }
 }
 
 void RenderFrameImpl::DidLoadResourceFromMemoryCache(
@@ -6309,8 +6312,9 @@
   params.post_body = GetRequestBodyForWebURLRequest(info->url_request);
   DCHECK_EQ(!!params.post_body, IsHttpPost(info->url_request));
   params.extra_headers = GetWebURLRequestHeadersAsString(info->url_request);
-  params.referrer =
-      RenderViewImpl::GetReferrerFromRequest(frame_, info->url_request);
+  params.referrer.url =
+      blink::WebStringToGURL(info->url_request.ReferrerString());
+  params.referrer.policy = info->url_request.GetReferrerPolicy();
   params.disposition = RenderViewImpl::NavigationPolicyToDisposition(policy);
   params.triggering_event_info = info->triggering_event_info;
   params.blob_url_token =
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 623cb11..ed402242 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -744,11 +744,8 @@
   params.post_body = GetRequestBodyForWebURLRequest(request);
   DCHECK_EQ(!!params.post_body, request.HttpMethod().Utf8() == "POST");
   params.extra_headers = GetWebURLRequestHeadersAsString(request);
-  // TODO(domfarolino): Retrieve the referrer in the form of a referrer member
-  // instead of the header field. See https://crbug.com/850813.
-  params.referrer = Referrer(blink::WebStringToGURL(request.HttpHeaderField(
-                                 blink::WebString::FromUTF8("Referer"))),
-                             request.GetReferrerPolicy());
+  params.referrer.url = blink::WebStringToGURL(request.ReferrerString());
+  params.referrer.policy = request.GetReferrerPolicy();
   params.disposition = WindowOpenDisposition::CURRENT_TAB;
   params.should_replace_current_entry = should_replace_current_entry;
   params.user_gesture = request.HasUserGesture();
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index a3d1b49..ffd00e51 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -1389,6 +1389,36 @@
   GetMainFrame()->SetAutofillClient(nullptr);
 }
 
+TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
+  // Load an HTML page consisting of one input fields.
+  LoadHTML(
+      "<html>"
+      "<head>"
+      "</head>"
+      "<body>"
+      "</body>"
+      "</html>");
+  render_thread_->sink().ClearMessages();
+  // Create an EditContext with control and selection bounds and set input
+  // panel policy to auto.
+  ExecuteJavaScriptForTests(
+      "const editContext = new EditContext(); "
+      "editContext.focus();editContext.inputPanelPolicy=\"auto\";editContext."
+      "updateLayout(new DOMRect(10, 20, 30, 40), new DOMRect(10,20, 1, 5));");
+  base::RunLoop().RunUntilIdle();
+  // Update the IME status and verify if our IME backend sends an IPC message
+  // to notify layout bounds of the EditContext.
+  view()->GetWidget()->UpdateTextInputState();
+  auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
+  EXPECT_EQ(true, std::get<0>(params).show_ime_if_needed);
+  gfx::Rect edit_context_control_bounds_expected(10, 20, 30, 40);
+  gfx::Rect edit_context_selection_bounds_expected(10, 20, 1, 5);
+  EXPECT_EQ(edit_context_control_bounds_expected,
+            std::get<0>(params).edit_context_control_bounds.value());
+  EXPECT_EQ(edit_context_selection_bounds_expected,
+            std::get<0>(params).edit_context_selection_bounds.value());
+}
+
 // Test that our IME backend can compose CJK words.
 // Our IME front-end sends many platform-independent messages to the IME backend
 // while it composes CJK words. This test sends the minimal messages captured
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index a85a854..44bf7722 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -251,15 +251,6 @@
     const mojom::CreateViewParams&) = nullptr;
 
 // static
-Referrer RenderViewImpl::GetReferrerFromRequest(
-    WebFrame* frame,
-    const WebURLRequest& request) {
-  return Referrer(blink::WebStringToGURL(
-                      request.HttpHeaderField(WebString::FromUTF8("Referer"))),
-                  request.GetReferrerPolicy());
-}
-
-// static
 WindowOpenDisposition RenderViewImpl::NavigationPolicyToDisposition(
     WebNavigationPolicy policy) {
   switch (policy) {
@@ -1329,8 +1320,9 @@
   params->disposition = NavigationPolicyToDisposition(policy);
   if (!request.IsNull()) {
     params->target_url = request.Url();
-    params->referrer =
-        blink::mojom::Referrer::From(GetReferrerFromRequest(creator, request));
+    params->referrer = blink::mojom::Referrer::New(
+        blink::WebStringToGURL(request.ReferrerString()),
+        request.GetReferrerPolicy());
   }
   params->features = ConvertWebWindowFeaturesToMojoWindowFeatures(features);
 
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index e97bd2c9..8f30d57a 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -419,10 +419,6 @@
   // RenderFrameImpl. These implementations are to be moved to RenderFrameImpl
   // <http://crbug.com/361761>.
 
-  static Referrer GetReferrerFromRequest(
-      blink::WebFrame* frame,
-      const blink::WebURLRequest& request);
-
   static WindowOpenDisposition NavigationPolicyToDisposition(
       blink::WebNavigationPolicy policy);
 
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 936add5..fce757d 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1598,8 +1598,14 @@
     return;  // Not considered as a text input field in WebKit/Chromium.
 
   blink::WebTextInputInfo new_info;
-  if (auto* controller = GetInputMethodController())
+  if (auto* controller = GetInputMethodController()) {
     new_info = controller->TextInputInfo();
+    // Check if the input panel policy in |EditContext| is set to manual or not.
+    // This will be used to decide whether or not to show VK when |EditContext|
+    // is set focus.
+    if (controller->IsEditContextActive())
+      show_virtual_keyboard = !controller->IsInputPanelPolicyManual();
+  }
   const ui::TextInputMode new_mode =
       ConvertWebTextInputMode(new_info.input_mode);
 
@@ -1623,6 +1629,15 @@
     params.mode = new_mode;
     params.action = new_info.action;
     params.flags = new_info.flags;
+    if (auto* controller = GetInputMethodController()) {
+      if (controller->IsEditContextActive()) {
+        WebRect control_bounds;
+        WebRect selection_bounds;
+        controller->GetLayoutBounds(&control_bounds, &selection_bounds);
+        params.edit_context_control_bounds = control_bounds;
+        params.edit_context_selection_bounds = selection_bounds;
+      }
+    }
 #if defined(OS_ANDROID)
     if (next_previous_flags_ == kInvalidNextPreviousFlagsValue) {
       // Due to a focus change, values will be reset by the frame.
@@ -1688,7 +1703,7 @@
   possible_drag_event_info_.event_source =
       ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
   possible_drag_event_info_.event_location =
-      gfx::Point(event.PositionInScreen().x, event.PositionInScreen().y);
+      gfx::Point(event.PositionInScreen().x(), event.PositionInScreen().y());
 
   return mouse_lock_dispatcher()->WillHandleMouseEvent(event);
 }
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index c6c2121..fa403f10 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -102,10 +102,8 @@
   mouse.click_count = (mouse.GetType() == WebInputEvent::kMouseDown ||
                        mouse.GetType() == WebInputEvent::kMouseUp);
 
-  mouse.SetPositionInWidget(gesture.PositionInWidget().x,
-                            gesture.PositionInWidget().y);
-  mouse.SetPositionInScreen(gesture.PositionInScreen().x,
-                            gesture.PositionInScreen().y);
+  mouse.SetPositionInWidget(gesture.PositionInWidget());
+  mouse.SetPositionInScreen(gesture.PositionInScreen());
 
   return mouse;
 }
@@ -193,10 +191,8 @@
           WebMouseEvent mouse(WebInputEvent::kMouseMove,
                               gesture_event->GetModifiers(),
                               gesture_event->TimeStamp());
-          mouse.SetPositionInWidget(gesture_event->PositionInWidget().x,
-                                    gesture_event->PositionInWidget().y);
-          mouse.SetPositionInScreen(gesture_event->PositionInScreen().x,
-                                    gesture_event->PositionInScreen().y);
+          mouse.SetPositionInWidget(gesture_event->PositionInWidget());
+          mouse.SetPositionInScreen(gesture_event->PositionInScreen());
           mouse.movement_x = 0;
           mouse.movement_y = 0;
           result |= widget_->plugin()->HandleInputEvent(mouse, &cursor);
diff --git a/content/renderer/service_worker/service_worker_fetch_context_impl.cc b/content/renderer/service_worker/service_worker_fetch_context_impl.cc
index 88ff674..bb1f6c7 100644
--- a/content/renderer/service_worker/service_worker_fetch_context_impl.cc
+++ b/content/renderer/service_worker/service_worker_fetch_context_impl.cc
@@ -138,8 +138,8 @@
   request.SetExtraData(std::move(extra_data));
 
   if (!renderer_preferences_.enable_referrers) {
-    request.SetHttpReferrer(blink::WebString(),
-                            network::mojom::ReferrerPolicy::kNever);
+    request.SetReferrerString(blink::WebString());
+    request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
   }
 }
 
diff --git a/content/shell/test_runner/event_sender.cc b/content/shell/test_runner/event_sender.cc
index 053d2a29..c563dd37 100644
--- a/content/shell/test_runner/event_sender.cc
+++ b/content/shell/test_runner/event_sender.cc
@@ -2344,10 +2344,8 @@
       event.data.scroll_update.delta_x = static_cast<float>(x);
       event.data.scroll_update.delta_y = static_cast<float>(y);
       event.SetPositionInWidget(current_gesture_location_);
-      current_gesture_location_.x =
-          current_gesture_location_.x + event.data.scroll_update.delta_x;
-      current_gesture_location_.y =
-          current_gesture_location_.y + event.data.scroll_update.delta_y;
+      current_gesture_location_.Offset(event.data.scroll_update.delta_x,
+                                       event.data.scroll_update.delta_y);
       break;
     }
     case WebInputEvent::kGestureScrollBegin:
@@ -2731,8 +2729,8 @@
             current_pointer_state_[kRawMousePointerId].pressed_button_,
             current_pointer_state_[kRawMousePointerId].current_buttons_, e.pos,
             click_count_, &event);
-        current_pointer_state_[kRawMousePointerId].last_pos_ =
-            WebPoint(event.PositionInWidget().x, event.PositionInWidget().y);
+        current_pointer_state_[kRawMousePointerId].last_pos_ = blink::WebPoint(
+            event.PositionInWidget().x(), event.PositionInWidget().y());
         HandleInputEventOnViewOrPopup(event);
         DoDragAfterMouseMove(event);
         break;
diff --git a/content/shell/test_runner/event_sender.h b/content/shell/test_runner/event_sender.h
index 4ac763f4..78d4e15 100644
--- a/content/shell/test_runner/event_sender.h
+++ b/content/shell/test_runner/event_sender.h
@@ -278,7 +278,7 @@
   blink::WebDragData current_drag_data_;
 
   // Location of the touch point that initiated a gesture.
-  blink::WebFloatPoint current_gesture_location_;
+  gfx::PointF current_gesture_location_;
 
   // Mouse-like pointer properties.
   struct PointerState {
diff --git a/content/shell/test_runner/test_plugin.cc b/content/shell/test_runner/test_plugin.cc
index 38bee7f..d6879fc 100644
--- a/content/shell/test_runner/test_plugin.cc
+++ b/content/shell/test_runner/test_plugin.cc
@@ -75,8 +75,8 @@
                     int length) {
   for (int i = 0; i < length; ++i) {
     delegate->PrintMessage(base::StringPrintf(
-        "* %.2f, %.2f: %s\n", points[i].PositionInWidget().x,
-        points[i].PositionInWidget().y, PointState(points[i].state)));
+        "* %.2f, %.2f: %s\n", points[i].PositionInWidget().x(),
+        points[i].PositionInWidget().y(), PointState(points[i].state)));
   }
 }
 
@@ -91,14 +91,14 @@
     const blink::WebMouseEvent& mouse =
         static_cast<const blink::WebMouseEvent&>(event);
     delegate->PrintMessage(base::StringPrintf("* %.2f, %.2f\n",
-                                              mouse.PositionInWidget().x,
-                                              mouse.PositionInWidget().y));
+                                              mouse.PositionInWidget().x(),
+                                              mouse.PositionInWidget().y()));
   } else if (blink::WebInputEvent::IsGestureEventType(event.GetType())) {
     const blink::WebGestureEvent& gesture =
         static_cast<const blink::WebGestureEvent&>(event);
     delegate->PrintMessage(base::StringPrintf("* %.2f, %.2f\n",
-                                              gesture.PositionInWidget().x,
-                                              gesture.PositionInWidget().y));
+                                              gesture.PositionInWidget().x(),
+                                              gesture.PositionInWidget().y()));
   }
 }
 
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc
index ffdec75..88def18d 100644
--- a/content/shell/test_runner/test_runner.cc
+++ b/content/shell/test_runner/test_runner.cc
@@ -264,6 +264,7 @@
   void SetTextSubpixelPositioning(bool value);
   void SetViewSourceForFrame(const std::string& name, bool enabled);
   void SetWillSendRequestClearHeader(const std::string& header);
+  void SetWillSendRequestClearReferrer();
   void SetWindowIsKey(bool value);
   void NavigateSecondaryWindow(const std::string& url);
   void InspectSecondaryWindow();
@@ -587,6 +588,8 @@
                  &TestRunnerBindings::SetViewSourceForFrame)
       .SetMethod("setWillSendRequestClearHeader",
                  &TestRunnerBindings::SetWillSendRequestClearHeader)
+      .SetMethod("setWillSendRequestClearReferrer",
+                 &TestRunnerBindings::SetWillSendRequestClearReferrer)
       .SetMethod("setWindowIsKey", &TestRunnerBindings::SetWindowIsKey)
       .SetMethod("navigateSecondaryWindow",
                  &TestRunnerBindings::NavigateSecondaryWindow)
@@ -1109,6 +1112,11 @@
     runner_->SetWillSendRequestClearHeader(header);
 }
 
+void TestRunnerBindings::SetWillSendRequestClearReferrer() {
+  if (runner_)
+    runner_->SetWillSendRequestClearReferrer();
+}
+
 void TestRunnerBindings::WaitUntilExternalURLLoad() {
   if (runner_)
     runner_->WaitUntilExternalURLLoad();
@@ -1536,6 +1544,7 @@
   did_notify_done_ = false;
 
   http_headers_to_clear_.clear();
+  clear_referrer_ = false;
 
   platform_name_ = "chromium";
   tooltip_text_ = std::string();
@@ -1758,6 +1767,10 @@
   return &http_headers_to_clear_;
 }
 
+bool TestRunner::ClearReferrer() const {
+  return clear_referrer_;
+}
+
 bool TestRunner::IsFramePartOfMainTestWindow(blink::WebFrame* frame) const {
   return test_is_running_ && frame->Top()->View() == main_view_;
 }
@@ -2399,6 +2412,10 @@
     http_headers_to_clear_.insert(header);
 }
 
+void TestRunner::SetWillSendRequestClearReferrer() {
+  clear_referrer_ = true;
+}
+
 void TestRunner::WaitUntilExternalURLLoad() {
   web_test_runtime_flags_.set_wait_until_external_url_load(true);
   web_test_runtime_flags_.set_wait_until_done(true);
diff --git a/content/shell/test_runner/test_runner.h b/content/shell/test_runner/test_runner.h
index f6ddfb5e..6593628 100644
--- a/content/shell/test_runner/test_runner.h
+++ b/content/shell/test_runner/test_runner.h
@@ -131,6 +131,7 @@
   bool ShouldDumpSpellCheckCallbacks() const;
   bool ShouldWaitUntilExternalURLLoad() const;
   const std::set<std::string>* HttpHeadersToClear() const;
+  bool ClearReferrer() const;
   bool is_web_platform_tests_mode() const {
     return is_web_platform_tests_mode_;
   }
@@ -407,8 +408,15 @@
   void SetShouldStayOnPageAfterHandlingBeforeUnload(bool value);
 
   // Causes WillSendRequest to clear certain headers.
+  // Note: This cannot be used to clear the request's `Referer` header, as this
+  // header is computed later given its referrer string member. To clear it, use
+  // SetWillSendRequestClearReferrer() below.
   void SetWillSendRequestClearHeader(const std::string& header);
 
+  // Causes WillSendRequest to clear the request's referrer string and set its
+  // referrer policy to the default.
+  void SetWillSendRequestClearReferrer();
+
   // Sets a flag that causes the test to be marked as completed when the
   // WebLocalFrameClient receives a LoadURLExternally() call.
   void WaitUntilExternalURLLoad();
@@ -542,6 +550,7 @@
   bool sweep_horizontally_;
 
   std::set<std::string> http_headers_to_clear_;
+  bool clear_referrer_ = false;
 
   // WAV audio data is stored here.
   std::vector<unsigned char> audio_data_;
diff --git a/content/shell/test_runner/web_frame_test_client.cc b/content/shell/test_runner/web_frame_test_client.cc
index f7c0669c..21367dd 100644
--- a/content/shell/test_runner/web_frame_test_client.cc
+++ b/content/shell/test_runner/web_frame_test_client.cc
@@ -411,8 +411,15 @@
   GURL main_document_url = request.SiteForCookies();
 
   if (test_runner()->HttpHeadersToClear()) {
-    for (const std::string& header : *test_runner()->HttpHeadersToClear())
+    for (const std::string& header : *test_runner()->HttpHeadersToClear()) {
+      DCHECK(!base::EqualsCaseInsensitiveASCII(header, "referer"));
       request.ClearHttpHeaderField(blink::WebString::FromUTF8(header));
+    }
+  }
+
+  if (test_runner()->ClearReferrer()) {
+    request.SetReferrerString(blink::WebString());
+    request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault);
   }
 
   std::string host = url.host();
@@ -528,10 +535,18 @@
 
   if (test_runner()->HttpHeadersToClear()) {
     for (const std::string& header : *test_runner()->HttpHeadersToClear()) {
+      DCHECK(!base::EqualsCaseInsensitiveASCII(header, "referer"));
       info->url_request.ClearHttpHeaderField(
           blink::WebString::FromUTF8(header));
     }
   }
+
+  if (test_runner()->ClearReferrer()) {
+    info->url_request.SetReferrerString(blink::WebString());
+    info->url_request.SetReferrerPolicy(
+        network::mojom::ReferrerPolicy::kDefault);
+  }
+
   info->url_request.SetUrl(delegate_->RewriteWebTestsURL(
       info->url_request.Url().GetString().Utf8(),
       test_runner()->is_web_platform_tests_mode()));
diff --git a/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt b/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt
index a05833c..1e2c73559 100644
--- a/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt
+++ b/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt
@@ -1,7 +1,7 @@
 document LocalizedControlType='document'
 ++group Name='comment'
 ++group Name='suggestion'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++description Name='This is '
 ++++description LocalizedControlType='highlight'
 ++++++description Name='highlighted'
diff --git a/content/test/data/accessibility/css/transform-expected-uia-win.txt b/content/test/data/accessibility/css/transform-expected-uia-win.txt
index 22b62242..3c3072e 100644
--- a/content/test/data/accessibility/css/transform-expected-uia-win.txt
+++ b/content/test/data/accessibility/css/transform-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group BoundingRectangle=(0, 50, 48, 18)
-++++group BoundingRectangle=(0, 50, 48, 18)
+++group BoundingRectangle=(0, 50, 48, 18) IsControlElement=false
+++++group BoundingRectangle=(0, 50, 48, 18) IsControlElement=false
 ++++++description BoundingRectangle=(0, 50, 48, 17) Name='content'
diff --git a/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt b/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt
index 686385f..9e3673a 100644
--- a/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/live-region-create-expected-uia-win.txt
@@ -1,3 +1,3 @@
 LiveRegionChanged on role=group
 StructureChanged/ChildAdded on role=group
-StructureChanged/ChildrenReordered on role=group
+StructureChanged/ChildrenReordered on role=document
diff --git a/content/test/data/accessibility/event/scroll-horizontal-scroll-percent-change-expected-uia-win.txt b/content/test/data/accessibility/event/scroll-horizontal-scroll-percent-change-expected-uia-win.txt
index 8215dfd..00e2fc5 100644
--- a/content/test/data/accessibility/event/scroll-horizontal-scroll-percent-change-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/scroll-horizontal-scroll-percent-change-expected-uia-win.txt
@@ -1,2 +1,2 @@
 ScrollHorizontalScrollPercent changed on role=document
-ScrollHorizontalScrollPercent changed on role=group
+ScrollHorizontalScrollPercent changed on role=document
diff --git a/content/test/data/accessibility/event/scroll-vertical-scroll-percent-change-expected-uia-win.txt b/content/test/data/accessibility/event/scroll-vertical-scroll-percent-change-expected-uia-win.txt
index b60638e..024af54 100644
--- a/content/test/data/accessibility/event/scroll-vertical-scroll-percent-change-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/scroll-vertical-scroll-percent-change-expected-uia-win.txt
@@ -1,2 +1,2 @@
 ScrollVerticalScrollPercent changed on role=document
-ScrollVerticalScrollPercent changed on role=group
+ScrollVerticalScrollPercent changed on role=document
diff --git a/content/test/data/accessibility/event/value-value-changed-expected-uia-win.txt b/content/test/data/accessibility/event/value-value-changed-expected-uia-win.txt
index 4144fca..ee27d31 100644
--- a/content/test/data/accessibility/event/value-value-changed-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/value-value-changed-expected-uia-win.txt
@@ -1,3 +1,5 @@
+Text_TextChanged on role=textbox
 ValueValue changed on role=textbox
 === Start Continuation ===
+Text_TextChanged on role=textbox
 ValueValue changed on role=textbox
diff --git a/content/test/data/accessibility/html/a-expected-uia-win.txt b/content/test/data/accessibility/html/a-expected-uia-win.txt
index f4511ba7..77a2856 100644
--- a/content/test/data/accessibility/html/a-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/a-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++link Name='normal link'
 ++++++description Name='normal link' IsControlElement=false
diff --git a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt
index f254100..8e61a15 100644
--- a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++link Name='Link with image at start.'
 ++++++img Name='Link'
 ++++++description Name=' with image at start.' IsControlElement=false
diff --git a/content/test/data/accessibility/html/abbr-expected-uia-win.txt b/content/test/data/accessibility/html/abbr-expected-uia-win.txt
index 113efff..48e920f 100644
--- a/content/test/data/accessibility/html/abbr-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/abbr-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='The '
 ++++description Name='World Health Organization'
 ++++++description Name='WHO'
diff --git a/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt b/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt
index 3afb908c..fb050b49 100644
--- a/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document Name='Action verbs'
-++group
+++group IsControlElement=false
 ++++description Name='Generic div'
 ++heading Name='Heading'
 ++++description Name='Heading' IsControlElement=false
@@ -23,7 +23,7 @@
 ++group
 ++++description Name='Div with click handler'
 ++group
-++++group
+++++group IsControlElement=false
 ++++++description Name='Paragraph with click handler on parent' IsControlElement=false
 ++menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
 ++++menuitem Name='Menu item 1'
diff --git a/content/test/data/accessibility/html/actions-expected-uia-win.txt b/content/test/data/accessibility/html/actions-expected-uia-win.txt
index e191919..b542d3b 100644
--- a/content/test/data/accessibility/html/actions-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/actions-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document Name='Actions'
-++group
+++group IsControlElement=false
 ++++slider RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=100.00 RangeValue.Minimum=1.00 RangeValue.Value=50.00 Value.Value='50'
 ++++textbox Name='Test textfield'
diff --git a/content/test/data/accessibility/html/address-expected-uia-win.txt b/content/test/data/accessibility/html/address-expected-uia-win.txt
index dccbc9a..fc3155ce 100644
--- a/content/test/data/accessibility/html/address-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/address-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Please contact John Citizen for more information.'
diff --git a/content/test/data/accessibility/html/area-expected-uia-win.txt b/content/test/data/accessibility/html/area-expected-uia-win.txt
index 71f43c0..704aac3 100644
--- a/content/test/data/accessibility/html/area-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/area-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++document Name='pipe'
 ++++++link Name='pipe1'
 ++++++link Name='pipe2'
diff --git a/content/test/data/accessibility/html/aside-expected-uia-win.txt b/content/test/data/accessibility/html/aside-expected-uia-win.txt
index 9d2e54e..6fd86db0 100644
--- a/content/test/data/accessibility/html/aside-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/aside-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='The aside tag defines some content aside from the content it is placed in.'
 ++complementary
 ++++heading Name='Aside tag'
 ++++++description Name='Aside tag' IsControlElement=false
-++++group
+++++group IsControlElement=false
 ++++++description Name='The aside content should be related to the surrounding content.'
diff --git a/content/test/data/accessibility/html/b-expected-uia-win.txt b/content/test/data/accessibility/html/b-expected-uia-win.txt
index 149b059..8f0f41a 100644
--- a/content/test/data/accessibility/html/b-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/b-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Some '
 ++++description Name='bold'
 ++++description Name=' text'
diff --git a/content/test/data/accessibility/html/bdo-expected-uia-win.txt b/content/test/data/accessibility/html/bdo-expected-uia-win.txt
index d1dbd89..97325d9 100644
--- a/content/test/data/accessibility/html/bdo-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/bdo-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Some LTR text'
 ++++description Name=' '
 ++++description Name='Some RTL text '
diff --git a/content/test/data/accessibility/html/blockquote-expected-uia-win.txt b/content/test/data/accessibility/html/blockquote-expected-uia-win.txt
index f5c37da..b497104 100644
--- a/content/test/data/accessibility/html/blockquote-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/blockquote-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++group
-++++group
+++++group IsControlElement=false
 ++++++description Name='First blockquote has a child element.'
 ++group
 ++++description Name='Second blockquote has no child.'
diff --git a/content/test/data/accessibility/html/body-expected-uia-win.txt b/content/test/data/accessibility/html/body-expected-uia-win.txt
index 83d6d2b7..d147be46 100644
--- a/content/test/data/accessibility/html/body-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/body-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This test is for body tag'
diff --git a/content/test/data/accessibility/html/br-expected-uia-win.txt b/content/test/data/accessibility/html/br-expected-uia-win.txt
index f4a6204f..410f106 100644
--- a/content/test/data/accessibility/html/br-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/br-expected-uia-win.txt
@@ -1,7 +1,7 @@
 document
 ++separator Name='<newline>'
 ++description Name='Text line 1'
-++group
+++group IsControlElement=false
 ++++description Name='Text line 2'
 ++++separator Name='<newline>'
 ++++description Name='Text line 3'
diff --git a/content/test/data/accessibility/html/button-expected-uia-win.txt b/content/test/data/accessibility/html/button-expected-uia-win.txt
index 9d4c319..49e7ff5 100644
--- a/content/test/data/accessibility/html/button-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/button-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++button Name='Click me!'
diff --git a/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt b/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt
index f1643ae..7a30ee0 100644
--- a/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt
@@ -7,7 +7,7 @@
 ++button Name='InnerText5' FullDescription='DescribedBy5'
 ++button Name='Outer inner'
 ++++description Name='Outer' IsControlElement=false
-++++group
+++++group IsControlElement=false
 ++++++description Name='inner' IsControlElement=false
 ++button Name='Outer inner1'
 ++++description Name='Outer' IsControlElement=false
@@ -16,5 +16,5 @@
 ++button Name='Outer grandchild'
 ++++description Name='Outer' IsControlElement=false
 ++++group
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='grandchild' IsControlElement=false
diff --git a/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt b/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt
index 76cd6d4..bcff1ef 100644
--- a/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt
+++ b/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt
@@ -7,7 +7,7 @@
 ++button Name='InnerText5'
 ++button Name='Outer inner'
 ++++description Name='Outer' IsControlElement=false
-++++group
+++++group IsControlElement=false
 ++++++description Name='inner' IsControlElement=false
 ++button Name='Outer inner1'
 ++++description Name='Outer' IsControlElement=false
@@ -16,5 +16,5 @@
 ++button Name='Outer grandchild'
 ++++description Name='Outer' IsControlElement=false
 ++++group
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='grandchild' IsControlElement=false
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt b/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt
index d937af2f..cfaf39f 100644
--- a/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
-++group
-++++group
+++group IsControlElement=false
+++++group IsControlElement=false
 ++++++description Name='Choose one:'
 ++++menu Name='Choose one: Foo' ExpandCollapse.ExpandCollapseState='LeafNode'
 ++++++description Name='Foo'
diff --git a/content/test/data/accessibility/html/canvas-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-expected-uia-win.txt
index d165211e..fcae904 100644
--- a/content/test/data/accessibility/html/canvas-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/canvas-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++img
 ++++++description Name='Static fallback'
 ++++img
diff --git a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt
index d08b7b0..dbc3893 100644
--- a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++img
 ++++++description Name='Static fallback'
 ++++img
@@ -13,9 +13,9 @@
 ++++++heading Name='Aria hidden paragraph in fallback content'
 ++++++++description Name='Aria hidden paragraph in fallback content' IsControlElement=false
 ++++++description Name='<newline>    '
-++++++heading
+++++++heading IsControlElement=false
 ++++++++description Name='Display none text in fallback content ' IsControlElement=false
 ++++++description Name='<newline>    '
-++++++heading
+++++++heading IsControlElement=false
 ++++++++description Name='Visibility hidden paragraph in fallback content' IsControlElement=false
 ++++++description Name='<newline>  '
diff --git a/content/test/data/accessibility/html/caption-expected-uia-win.txt b/content/test/data/accessibility/html/caption-expected-uia-win.txt
index 0f5763b..c72e2c7 100644
--- a/content/test/data/accessibility/html/caption-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/caption-expected-uia-win.txt
@@ -1,18 +1,18 @@
 document
 ++grid Name='Browser and Engine' Grid.ColumnCount=2 Grid.RowCount=3 Table.RowOrColumnMajor='RowMajor'
-++++description
+++++description IsControlElement=false
 ++++++description Name='Browser and Engine'
-++++row
+++++row IsControlElement=false
 ++++++columnheader Name='Browser' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
 ++++++++description Name='Browser' IsControlElement=false
 ++++++columnheader Name='Engine' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
 ++++++++description Name='Engine' IsControlElement=false
-++++row
+++++row IsControlElement=false
 ++++++gridcell Name='Chrome' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
 ++++++++description Name='Chrome' IsControlElement=false
 ++++++gridcell Name='Blink' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
 ++++++++description Name='Blink' IsControlElement=false
-++++row
+++++row IsControlElement=false
 ++++++gridcell Name='Safari' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
 ++++++++description Name='Safari' IsControlElement=false
 ++++++gridcell Name='WebKit' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine'
diff --git a/content/test/data/accessibility/html/cite-expected-uia-win.txt b/content/test/data/accessibility/html/cite-expected-uia-win.txt
index 4a7f98b..9d22eb8 100644
--- a/content/test/data/accessibility/html/cite-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/cite-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
 ++img Name='Pipe'
-++group
+++group IsControlElement=false
 ++++description Name='The pipe'
 ++++description Name=' clicked by SomeOne.'
diff --git a/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt b/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt
index 3ea045c48..8d7027d 100644
--- a/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++combobox ExpandCollapse.ExpandCollapseState='Collapsed' Value.IsReadOnly=false Value.Value='Mercedes Label'
 ++++++list Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Value.IsReadOnly=false
 ++++++++listitem Name='Volvo Label' SelectionItem.IsSelected=false
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
index 95b9633a..5f15583 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++group
-++++group
+++++group IsControlElement=false
 ++++++description Name='A contenteditable with a '
 ++++++link Name='link'
 ++++++++description Name='link' IsControlElement=false
@@ -10,14 +10,14 @@
 ++++++button Name='Button'
 ++++++description Name='.'
 ++++grid Grid.ColumnCount=1 Grid.RowCount=1 Table.RowOrColumnMajor='RowMajor'
-++++++row
+++++++row IsControlElement=false
 ++++++++gridcell Name='Always expose editable tables as tables.' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++description Name='Always expose editable tables as tables.' IsControlElement=false
 ++++list
 ++++++listitem
 ++++++++description Name='1. '
 ++++++++description Name='Editable list item.' IsControlElement=false
-++group
+++group IsControlElement=false
 ++++description Name='Non-editable paragraph.'
 ++group
 ++++description Name='Should keep the role but change the state.'
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
index a128de7e..fcb4abc 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++group
-++++group
+++++group IsControlElement=false
 ++++++description Name='A contenteditable with a '
 ++++++link Name='link'
 ++++++++description Name='link' IsControlElement=false
@@ -10,7 +10,7 @@
 ++++++button Name='Button'
 ++++++description Name='.'
 ++++grid Grid.ColumnCount=1 Grid.RowCount=1 Table.RowOrColumnMajor='RowMajor'
-++++++row
+++++++row IsControlElement=false
 ++++++++gridcell Name='Always expose editable tables as tables.' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++description Name='Always expose editable tables as tables.' IsControlElement=false
 ++++list
diff --git a/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt
index 194ca20..87987f4 100644
--- a/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++group
-++++group
+++++group IsControlElement=false
 ++++++description Name='This is editable.'
 ++++description Name='This is not editable.'
 ++++separator Name='<newline>'
diff --git a/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt
index 9412a3a..70096a0 100644
--- a/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt
@@ -2,5 +2,5 @@
 ++group Name='label'
 ++group
 ++group Name='title'
-++group
+++group IsControlElement=false
 ++++description Name='description'
diff --git a/content/test/data/accessibility/html/dd-expected-uia-win.txt b/content/test/data/accessibility/html/dd-expected-uia-win.txt
index decbb19..353dd1c 100644
--- a/content/test/data/accessibility/html/dd-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/dd-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++list
-++++listitem
+++++listitem IsControlElement=false
 ++++++description Name='Coffee'
-++++description
+++++description IsControlElement=false
 ++++++description Name='Black hot drink'
diff --git a/content/test/data/accessibility/html/del-expected-uia-win.txt b/content/test/data/accessibility/html/del-expected-uia-win.txt
index 4d34966..ba63f04 100644
--- a/content/test/data/accessibility/html/del-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/del-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='I am '
-++++group
+++++group IsControlElement=false
 ++++++description Name='vegetarian'
diff --git a/content/test/data/accessibility/html/details-expected-uia-win.txt b/content/test/data/accessibility/html/details-expected-uia-win.txt
index 6754eff..21955a7 100644
--- a/content/test/data/accessibility/html/details-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/details-expected-uia-win.txt
@@ -5,5 +5,5 @@
 ++group LocalizedControlType='details'
 ++++button Name='details tag open' ExpandCollapse.ExpandCollapseState='Expanded'
 ++++++description Name='details tag open'
-++++group
+++++group IsControlElement=false
 ++++++description Name='The details tag with open specifies that the details should be visible (open) to the user.'
diff --git a/content/test/data/accessibility/html/dfn-expected-uia-win.txt b/content/test/data/accessibility/html/dfn-expected-uia-win.txt
index b818887a..839efe8 100644
--- a/content/test/data/accessibility/html/dfn-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/dfn-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Web Browser'
 ++++description Name=' A computer program with a graphical user interface for displaying HTML files, used to navigate the World Wide Web.'
diff --git a/content/test/data/accessibility/html/dialog-expected-uia-win.txt b/content/test/data/accessibility/html/dialog-expected-uia-win.txt
index 01cc608..aed70ec 100644
--- a/content/test/data/accessibility/html/dialog-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/dialog-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++dialog Window.IsModal=false
+++dialog IsControlElement=false Window.IsModal=false
 ++++description Name='Text in dialog'
diff --git a/content/test/data/accessibility/html/div-expected-uia-win.txt b/content/test/data/accessibility/html/div-expected-uia-win.txt
index 8f153e6..f9062bd5 100644
--- a/content/test/data/accessibility/html/div-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/div-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Unfocusable div'
 ++group Name='Focusable div'
 ++++description Name='Focusable div'
diff --git a/content/test/data/accessibility/html/dl-expected-uia-win.txt b/content/test/data/accessibility/html/dl-expected-uia-win.txt
index 694e4ee..efd067b 100644
--- a/content/test/data/accessibility/html/dl-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/dl-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
 ++list
-++++listitem
+++++listitem IsControlElement=false
 ++++++description Name='Term'
-++++description
+++++description IsControlElement=false
 ++++++description Name='Description'
 ++definition
 ++++description Name='Definition'
diff --git a/content/test/data/accessibility/html/dt-expected-uia-win.txt b/content/test/data/accessibility/html/dt-expected-uia-win.txt
index decbb19..353dd1c 100644
--- a/content/test/data/accessibility/html/dt-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/dt-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
 ++list
-++++listitem
+++++listitem IsControlElement=false
 ++++++description Name='Coffee'
-++++description
+++++description IsControlElement=false
 ++++++description Name='Black hot drink'
diff --git a/content/test/data/accessibility/html/em-expected-uia-win.txt b/content/test/data/accessibility/html/em-expected-uia-win.txt
index f9bf405f..b1f752c 100644
--- a/content/test/data/accessibility/html/em-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/em-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='One word is '
 ++++description Name='emphasized'
 ++++description Name='.'
diff --git a/content/test/data/accessibility/html/embed-expected-uia-win.txt b/content/test/data/accessibility/html/embed-expected-uia-win.txt
index e74482a..8cf75072 100644
--- a/content/test/data/accessibility/html/embed-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/embed-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++document
diff --git a/content/test/data/accessibility/html/fieldset-expected-uia-win.txt b/content/test/data/accessibility/html/fieldset-expected-uia-win.txt
index 9ffdb92..a0d99d4 100644
--- a/content/test/data/accessibility/html/fieldset-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/fieldset-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
 ++form
 ++++group Name='Browser Engines:'
-++++++description
+++++++description IsControlElement=false
 ++++++++description Name='Browser Engines:' IsControlElement=false
diff --git a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt
index 2ad5236..86d7818 100644
--- a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
 ++group Name='Fig.1 - A green Box'
 ++++img Name='This is a green box.'
-++++description ControlType='UIA_TextControlTypeId'
+++++description ControlType='UIA_TextControlTypeId' IsControlElement=false
 ++++++description ControlType='UIA_TextControlTypeId' Name='Fig.1 - A green Box'
diff --git a/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt b/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt
index da4964d..671568a 100644
--- a/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt
@@ -1,13 +1,13 @@
 document
 ++article
 ++++group LocalizedControlType='footer'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='footer inside article.'
 ++group
 ++++group LocalizedControlType='footer'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='footer inside section.'
 ++main
 ++++group LocalizedControlType='footer'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='footer inside main.'
diff --git a/content/test/data/accessibility/html/frameset-expected-uia-win.txt b/content/test/data/accessibility/html/frameset-expected-uia-win.txt
index 331f811..5f332dc 100644
--- a/content/test/data/accessibility/html/frameset-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/frameset-expected-uia-win.txt
@@ -1,18 +1,18 @@
 document
 ++document
 ++++document
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='My favorite browser is '
-++++++++group
+++++++++group IsControlElement=false
 ++++++++++description Name='ABC'
 ++++++++description Name=' '
-++++++++group
+++++++++group IsControlElement=false
 ++++++++++description Name='Chrome'
 ++++++++description Name='!'
 ++document
 ++++document
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='This test is to check '
-++++++++description
+++++++++description IsControlElement=false
 ++++++++++description Name='mark tag'
 ++++++++description Name='.'
diff --git a/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt b/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt
index 894275d..0f92375 100644
--- a/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt
@@ -1,13 +1,13 @@
 document
 ++article
 ++++group LocalizedControlType='header'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Header inside article.'
 ++group
 ++++group LocalizedControlType='header'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Header inside section.'
 ++main
 ++++group LocalizedControlType='header'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Header inside main.'
diff --git a/content/test/data/accessibility/html/hr-expected-uia-win.txt b/content/test/data/accessibility/html/hr-expected-uia-win.txt
index e074f7f..dcb50d2d 100644
--- a/content/test/data/accessibility/html/hr-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/hr-expected-uia-win.txt
@@ -1,9 +1,9 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Before.'
 ++separator Name='Dividing line'
-++group
+++group IsControlElement=false
 ++++description Name='Middle.'
 ++separator
-++group
+++group IsControlElement=false
 ++++description Name='After.'
diff --git a/content/test/data/accessibility/html/i-expected-uia-win.txt b/content/test/data/accessibility/html/i-expected-uia-win.txt
index b6c4afc..654576b 100644
--- a/content/test/data/accessibility/html/i-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/i-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This is to check '
 ++++description Name='italic property'
 ++++description Name=' using i tag.'
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt
index 2380fe7..e66ec72 100644
--- a/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt
@@ -1,15 +1,15 @@
 document
-++group
+++group IsControlElement=false
 ++++button Name='Button'
-++group
+++group IsControlElement=false
 ++++button Name='Button'
-++group
+++group IsControlElement=false
 ++++document
 ++++++document
-++++++++group
+++++++++group IsControlElement=false
 ++++++++++button Name='Ordinary Button'
-++group
+++group IsControlElement=false
 ++++document
 ++++++document
-++++++++group
+++++++++group IsControlElement=false
 ++++++++++button Name='Scrolled Button'
diff --git a/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt
index 49e99c7..d76a066 100644
--- a/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt
@@ -1,10 +1,10 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Before frame'
-++group
+++group IsControlElement=false
 ++++document Name='Cross-process iframe'
 ++++++document
-++++++++group
+++++++++group IsControlElement=false
 ++++++++++description Name='Text in iframe'
-++group
+++group IsControlElement=false
 ++++description Name='After frame'
diff --git a/content/test/data/accessibility/html/iframe-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-expected-uia-win.txt
index f60fc7ab..4b8e7471 100644
--- a/content/test/data/accessibility/html/iframe-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/iframe-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++document Name='Empty iframe'
 ++++++document
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt
index f6c37cb9..6638dc1d 100644
--- a/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++group
 ++++++group
diff --git a/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt b/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt
index 609bfb9..45e007c 100644
--- a/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='before selection'
-++group
+++group IsControlElement=false
 ++++description Name='this text is not ignored'
-++group
+++group IsControlElement=false
 ++++description Name='after selection'
 ++description Name='Done'
diff --git a/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt b/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt
index 3ea770ed..12c051eb 100644
--- a/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
 ++description Name='this text is not ignored'
-++group
+++group IsControlElement=false
 ++++description Name='after selection'
 ++description Name='Done'
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-android.txt b/content/test/data/accessibility/html/img-empty-alt-expected-android.txt
index a358c0e..9ce2726c 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-android.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-android.txt
@@ -1,4 +1,5 @@
 android.webkit.WebView focusable focused scrollable
 ++android.view.View
+++++android.widget.Image role_description='graphic'
 ++++android.widget.Image role_description='graphic' name='read'
 ++++android.widget.Image role_description='graphic' name='full'
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-auralinux.txt b/content/test/data/accessibility/html/img-empty-alt-expected-auralinux.txt
index 51e48e3e..c88664d50 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-auralinux.txt
@@ -1,4 +1,5 @@
 [document web]
 ++[section]
+++++[image] name=''
 ++++[image]
 ++++[image] name='full'
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-blink.txt b/content/test/data/accessibility/html/img-empty-alt-expected-blink.txt
index 177dc10..22abcff9 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-blink.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-blink.txt
@@ -1,6 +1,7 @@
 rootWebArea
 ++genericContainer
 ++++presentational ignored name=''
+++++image name=''
 ++++image ignored name=''
 ++++image ignored name=''
 ++++image
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-mac.txt b/content/test/data/accessibility/html/img-empty-alt-expected-mac.txt
index 02ee4d9..e93dffb 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-mac.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-mac.txt
@@ -1,4 +1,5 @@
 AXWebArea
 ++AXGroup
+++++AXUnknown
 ++++AXImage AXDescription='/read.jpg'
 ++++AXImage AXDescription='full'
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt b/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt
index c31fc910..e386a0f5 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt
@@ -1,4 +1,5 @@
 document
-++group
+++group IsControlElement=false
+++++img IsControlElement=false
 ++++img
 ++++img Name='full'
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-win.txt b/content/test/data/accessibility/html/img-empty-alt-expected-win.txt
index deaa7dc..e1b5fa5 100644
--- a/content/test/data/accessibility/html/img-empty-alt-expected-win.txt
+++ b/content/test/data/accessibility/html/img-empty-alt-expected-win.txt
@@ -1,4 +1,5 @@
 ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
 ++IA2_ROLE_SECTION
+++++ROLE_SYSTEM_GRAPHIC name='' READONLY
 ++++ROLE_SYSTEM_GRAPHIC READONLY
 ++++ROLE_SYSTEM_GRAPHIC name='full' READONLY
diff --git a/content/test/data/accessibility/html/img-empty-alt.html b/content/test/data/accessibility/html/img-empty-alt.html
index fc4607b..c99806ca 100644
--- a/content/test/data/accessibility/html/img-empty-alt.html
+++ b/content/test/data/accessibility/html/img-empty-alt.html
@@ -1,6 +1,10 @@
 <html>
   <body>
-    <img src="unread.jpg" alt="" role="presentation"><img src="read.jpg" alt=""><img src="read.jpg" alt><img src="read.jpg"><img src="read.jpg" alt="full">
+    <img src="unread.jpg" alt="" role="presentation">
+    <img src="read.jpg" alt="" aria-hidden="false">
+    <img src="read.jpg" alt="">
+    <img src="read.jpg" alt>
+    <img src="read.jpg">
+    <img src="read.jpg" alt="full">
   </body>
 </html>
-
diff --git a/content/test/data/accessibility/html/img-expected-uia-win.txt b/content/test/data/accessibility/html/img-expected-uia-win.txt
index 97ffe28..ca96c95a 100644
--- a/content/test/data/accessibility/html/img-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/img-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++img Name='pipe'
 ++++description Name=' '
 ++++description Name=' '
diff --git a/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt b/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt
index 02f3646..38f51658 100644
--- a/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++link Name='unread '
 ++++++description Name='unread ' IsControlElement=false
 ++++link Name='read '
diff --git a/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt b/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt
index 9ba4ce6..96a64087 100644
--- a/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt
@@ -16,20 +16,20 @@
 ++description Name=' '
 ++link Name='Paragraph with content'
 ++++description Name='Paragraph with content' IsControlElement=false
-++group
+++group IsControlElement=false
 ++++link
 ++++description Name='After empty anchor'
-++group
+++group IsControlElement=false
 ++++link Name='Anchor with content'
 ++++++description Name='Anchor with content'
-++group
+++group IsControlElement=false
 ++++link Name='Anchor with ID'
 ++++++description Name='Anchor with ID'
-++group
-++++group
+++group IsControlElement=false
+++++group IsControlElement=false
 ++++description Name='After empty span'
-++group
-++++group
+++group IsControlElement=false
+++++group IsControlElement=false
 ++++++description Name='Span with content'
-++group
+++group IsControlElement=false
 ++++description Name='Paragraph with content'
diff --git a/content/test/data/accessibility/html/input-button-expected-uia-win.txt b/content/test/data/accessibility/html/input-button-expected-uia-win.txt
index cae6f304..07fa9a6 100644
--- a/content/test/data/accessibility/html/input-button-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-button-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++button Name='Button'
diff --git a/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt
index 0d4ec90..98daa9fc 100644
--- a/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++menuitem Name='Button in menu element'
 ++menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
 ++++menuitem Name='Button in element with menu role'
diff --git a/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt b/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt
index b5b30ddf..86a631c 100644
--- a/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++checkbox Name='Checkbox0' Toggle.ToggleState='Off'
 ++++checkbox Name='Checkbox1' Toggle.ToggleState='On'
 ++++checkbox Name='Checkbox2' Toggle.ToggleState='On'
diff --git a/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt
index 8d45d959..060c6ea 100644
--- a/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++checkbox Name='Checkbox1' Toggle.ToggleState='Off'
 ++++checkbox Name='Checkbox2' Toggle.ToggleState='On'
 ++menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
diff --git a/content/test/data/accessibility/html/input-color-expected-uia-win.txt b/content/test/data/accessibility/html/input-color-expected-uia-win.txt
index 67243b5..f2a8d1d32 100644
--- a/content/test/data/accessibility/html/input-color-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-color-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox LocalizedControlType='color picker' Value.Value='100% red 60% green 0% blue'
diff --git a/content/test/data/accessibility/html/input-date-expected-uia-win.txt b/content/test/data/accessibility/html/input-date-expected-uia-win.txt
index 1b7c12a..e9f25f9 100644
--- a/content/test/data/accessibility/html/input-date-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-date-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox LocalizedControlType='date picker'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
 ++++++++++++description Name='09'
 ++++++++++description Name='/'
@@ -13,8 +13,8 @@
 ++++++++++++description Name='2008'
 ++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='Collapsed'
 ++++textbox LocalizedControlType='date picker' Name='When'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month When' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
 ++++++++++++description Name='09'
 ++++++++++description Name='/'
diff --git a/content/test/data/accessibility/html/input-date-with-popup-open-multiple-expected-uia-win.txt b/content/test/data/accessibility/html/input-date-with-popup-open-multiple-expected-uia-win.txt
index 21e7605..0740926 100644
--- a/content/test/data/accessibility/html/input-date-with-popup-open-multiple-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-date-with-popup-open-multiple-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox LocalizedControlType='date picker'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
 ++++++++++++description Name='09'
 ++++++++++description Name='/'
@@ -13,8 +13,8 @@
 ++++++++++++description Name='2008'
 ++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='Collapsed'
 ++++textbox LocalizedControlType='date picker'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
 ++++++++++++description Name='09'
 ++++++++++description Name='/'
@@ -25,8 +25,8 @@
 ++++++++++++description Name='2008'
 ++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='Collapsed'
 ++++textbox LocalizedControlType='date picker' Name='Third date picker' ControllerFor='{document}'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month Third date picker' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=9.00 Value.Value='09'
 ++++++++++++description Name='09'
 ++++++++++description Name='/'
@@ -38,33 +38,33 @@
 ++++++menu Name='Show date picker' ExpandCollapse.ExpandCollapseState='Collapsed'
 ++++++Name='Chrome Legacy Window' IsControlElement=false
 ++++++++document
-++++++++++group
-++++++++++++group
-++++++++++++++group
+++++++++++group IsControlElement=false
+++++++++++++group IsControlElement=false
+++++++++++++++group IsControlElement=false
 ++++++++++++++++button Name='Show month selection panel'
 ++++++++++++++++++description IsControlElement=false
 ++++++++++++++++++img
 ++++++++++++++button Name='Show previous month'
 ++++++++++++++++img
 ++++++++++++++button Name='Today'
-++++++++++++++++group
+++++++++++++++++group IsControlElement=false
 ++++++++++++++button Name='Show next month'
 ++++++++++++++++img
 ++++++++++++++grid Grid.ColumnCount=0 Grid.RowCount=0 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
-++++++++++++++++group
-++++++++++++++++++group
+++++++++++++++++group IsControlElement=false
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Sun'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Mon'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Tue'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Wed'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Thu'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Fri'
-++++++++++++++++++group
+++++++++++++++++++group IsControlElement=false
 ++++++++++++++++++++description Name='Sat'
-++++++++++++++++group
-++++++++++++++++++group
+++++++++++++++++group IsControlElement=false
+++++++++++++++++++group IsControlElement=false
diff --git a/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt b/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt
index 6d7b15e..1cb00f8 100644
--- a/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='1/1/2015 1:00AM'
 ++++textbox Name='Launch' Value.Value='1/1/2015 1:00AM'
diff --git a/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt b/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt
index 7a88bef4..b3954c2 100644
--- a/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox LocalizedControlType='local date and time picker'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Month' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=0.00 Value.Value='0'
 ++++++++++++description Name='mm'
 ++++++++++description Name='/'
diff --git a/content/test/data/accessibility/html/input-email-expected-uia-win.txt b/content/test/data/accessibility/html/input-email-expected-uia-win.txt
index 7dba3ee2..80ddd33 100644
--- a/content/test/data/accessibility/html/input-email-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-email-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document LocalizedControlType='document'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++textbox LocalizedControlType='email' Value.Value='someone@example.com'
diff --git a/content/test/data/accessibility/html/input-file-expected-uia-win.txt b/content/test/data/accessibility/html/input-file-expected-uia-win.txt
index 23863ea..fad5021 100644
--- a/content/test/data/accessibility/html/input-file-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-file-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++button Name='Choose File'
 ++++++button Name='Choose File'
diff --git a/content/test/data/accessibility/html/input-image-expected-uia-win.txt b/content/test/data/accessibility/html/input-image-expected-uia-win.txt
index a3314b3..a2471e57 100644
--- a/content/test/data/accessibility/html/input-image-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-image-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++button Name='Submit'
diff --git a/content/test/data/accessibility/html/input-list-expected-uia-win.txt b/content/test/data/accessibility/html/input-list-expected-uia-win.txt
index 813dbdd..4d5bd60 100644
--- a/content/test/data/accessibility/html/input-list-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-list-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description
 ++++++description Name='Choose a pokemon '
 ++++++combobox Name='Choose a pokemon' ExpandCollapse.ExpandCollapseState='LeafNode'
diff --git a/content/test/data/accessibility/html/input-number-expected-uia-win.txt b/content/test/data/accessibility/html/input-number-expected-uia-win.txt
index 89e30bac..ed54c734c 100644
--- a/content/test/data/accessibility/html/input-number-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-number-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++spinbutton RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=0.00 RangeValue.Minimum=0.00 RangeValue.Value=1.00 Value.Value='1'
 ++++spinbutton RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=10.00 RangeValue.Minimum=5.00 RangeValue.Value=6.00 Value.Value='6'
diff --git a/content/test/data/accessibility/html/input-password-expected-uia-win.txt b/content/test/data/accessibility/html/input-password-expected-uia-win.txt
index 5fdfb67..aa6e4faa 100644
--- a/content/test/data/accessibility/html/input-password-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-password-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox IsPassword=true Value.Value='••••••'
diff --git a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt
index 7fe0bc39..69b28926 100644
--- a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++menuitemradio SelectionItem.IsSelected=true
 ++++description Name='Radio0 '
 ++++menuitemradio SelectionItem.IsSelected=false
diff --git a/content/test/data/accessibility/html/input-range-expected-uia-win.txt b/content/test/data/accessibility/html/input-range-expected-uia-win.txt
index aa63326..e6e29de 100644
--- a/content/test/data/accessibility/html/input-range-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-range-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++slider RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=10.00 RangeValue.Minimum=1.00 RangeValue.Value=5.00 Value.Value='5'
diff --git a/content/test/data/accessibility/html/input-reset-expected-uia-win.txt b/content/test/data/accessibility/html/input-reset-expected-uia-win.txt
index 5c2c6b8..8a4121e9 100644
--- a/content/test/data/accessibility/html/input-reset-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-reset-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox
 ++++button Name='Reset'
diff --git a/content/test/data/accessibility/html/input-search-expected-uia-win.txt b/content/test/data/accessibility/html/input-search-expected-uia-win.txt
index 2f4c42d..a5039a1 100644
--- a/content/test/data/accessibility/html/input-search-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-search-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document LocalizedControlType='document'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++searchbox LocalizedControlType='search box' Value.Value='Search terms'
diff --git a/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt b/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt
index 3a7fbd0..f26bf694 100644
--- a/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++combobox ExpandCollapse.ExpandCollapseState='LeafNode'
diff --git a/content/test/data/accessibility/html/input-tel-expected-uia-win.txt b/content/test/data/accessibility/html/input-tel-expected-uia-win.txt
index 0add879..447c122 100644
--- a/content/test/data/accessibility/html/input-tel-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-tel-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document LocalizedControlType='document'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++textbox LocalizedControlType='telephone' Value.Value='123-456-7890'
diff --git a/content/test/data/accessibility/html/input-text-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-expected-uia-win.txt
index 70a2cd1..1bb4c03 100644
--- a/content/test/data/accessibility/html/input-text-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-text-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Name='Name'
diff --git a/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt
index 70a2cd1..1bb4c03 100644
--- a/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Name='Name'
diff --git a/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt
index ff9b09f..95678c4 100644
--- a/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description
 ++++++description Name='l1'
 ++++textbox Name='l1'
@@ -10,7 +10,7 @@
 ++++textbox Name='l2' Value.Value='value  *'
 ++++description
 ++++++description Name='Email'
-++++group
+++++group IsControlElement=false
 ++++textbox Name='Email'
 ++++textbox Name='Email' Value.Value='value'
 ++++textbox Name='l5'
diff --git a/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt
index 6bc56d35..22407b9 100644
--- a/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='Selection'
diff --git a/content/test/data/accessibility/html/input-time-expected-uia-win.txt b/content/test/data/accessibility/html/input-time-expected-uia-win.txt
index 73c9e23..dd8a40b 100644
--- a/content/test/data/accessibility/html/input-time-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-time-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++group
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Hours' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=12.00 Value.Value='12'
 ++++++++++++description Name='12'
 ++++++++++description Name=':'
@@ -12,8 +12,8 @@
 ++++++++++spinbutton Name='AM/PM' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=2.00 RangeValue.Minimum=1.00 RangeValue.Value=1.00 Value.Value='AM'
 ++++++++++++description Name='AM'
 ++++group Name='Breakfast'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++spinbutton Name='Hours Breakfast' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=12.00 Value.Value='12'
 ++++++++++++description Name='12'
 ++++++++++description Name=':'
diff --git a/content/test/data/accessibility/html/input-types-expected-uia-win.txt b/content/test/data/accessibility/html/input-types-expected-uia-win.txt
index 9c68fcf6..ec59efe 100644
--- a/content/test/data/accessibility/html/input-types-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-types-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description
 ++++++description Name='Default: '
 ++++++textbox Name='Default:'
diff --git a/content/test/data/accessibility/html/input-url-expected-uia-win.txt b/content/test/data/accessibility/html/input-url-expected-uia-win.txt
index ad47bee..6999c1b 100644
--- a/content/test/data/accessibility/html/input-url-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-url-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document LocalizedControlType='document'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++textbox LocalizedControlType='url' Value.Value='example.com'
diff --git a/content/test/data/accessibility/html/input-week-expected-uia-win.txt b/content/test/data/accessibility/html/input-week-expected-uia-win.txt
index 33eaa92..09087252 100644
--- a/content/test/data/accessibility/html/input-week-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/input-week-expected-uia-win.txt
@@ -1,8 +1,8 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox LocalizedControlType='week picker'
-++++++group
-++++++++group
+++++++group IsControlElement=false
+++++++++group IsControlElement=false
 ++++++++++description Name='Week '
 ++++++++++spinbutton Name='Week' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=53.00 RangeValue.Minimum=1.00 RangeValue.Value=0.00 Value.Value='0'
 ++++++++++++description Name='--'
diff --git a/content/test/data/accessibility/html/ins-expected-uia-win.txt b/content/test/data/accessibility/html/ins-expected-uia-win.txt
index b3a9459..4a362e97 100644
--- a/content/test/data/accessibility/html/ins-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/ins-expected-uia-win.txt
@@ -1,9 +1,9 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='My favorite browser is '
-++++group
+++++group IsControlElement=false
 ++++++description Name='ABC'
 ++++description Name=' '
-++++group
+++++group IsControlElement=false
 ++++++description Name='Chrome'
 ++++description Name='!'
diff --git a/content/test/data/accessibility/html/label-expected-uia-win.txt b/content/test/data/accessibility/html/label-expected-uia-win.txt
index 00610c6..99bafe4 100644
--- a/content/test/data/accessibility/html/label-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/label-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++description
 ++++++description Name='Label'
diff --git a/content/test/data/accessibility/html/landmark-expected-uia-win.txt b/content/test/data/accessibility/html/landmark-expected-uia-win.txt
index 7371d82..1deb73e 100644
--- a/content/test/data/accessibility/html/landmark-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/landmark-expected-uia-win.txt
@@ -3,7 +3,7 @@
 ++++description Name='This is a header element.'
 ++complementary
 ++++description Name='This is an aside element.'
-++group
+++group IsControlElement=false
 ++++description Name='This is an address element.'
 ++contentinfo
 ++++description Name='This is a footer element.'
@@ -47,7 +47,7 @@
 ++group
 ++++button Name='Details' ExpandCollapse.ExpandCollapseState='LeafNode'
 ++++++description Name='Details'
-++group
+++group IsControlElement=false
 ++++group
 ++++++description Name='This should NOT have banner role.' IsControlElement=false
 ++group
@@ -77,7 +77,7 @@
 ++group
 ++++button Name='Details' ExpandCollapse.ExpandCollapseState='LeafNode'
 ++++++description Name='Details'
-++group
+++group IsControlElement=false
 ++++group
 ++++++description Name='This should NOT have banner role.' IsControlElement=false
 ++group
@@ -106,7 +106,7 @@
 ++group
 ++++button Name='Details' ExpandCollapse.ExpandCollapseState='LeafNode'
 ++++++description Name='Details'
-++group
+++group IsControlElement=false
 ++++group
 ++++++description Name='This should NOT have footer role.' IsControlElement=false
 ++group
@@ -135,7 +135,7 @@
 ++group
 ++++button Name='Details' ExpandCollapse.ExpandCollapseState='LeafNode'
 ++++++description Name='Details'
-++group
+++group IsControlElement=false
 ++++group
 ++++++description Name='This should NOT have footer role.' IsControlElement=false
 ++group
diff --git a/content/test/data/accessibility/html/legend-expected-uia-win.txt b/content/test/data/accessibility/html/legend-expected-uia-win.txt
index f5b8f95..1b227b58 100644
--- a/content/test/data/accessibility/html/legend-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/legend-expected-uia-win.txt
@@ -1,7 +1,7 @@
 document
 ++form
 ++++group Name='Browser Engines:'
-++++++description
+++++++description IsControlElement=false
 ++++++++description Name='Browser Engines:' IsControlElement=false
 ++++++description Name='Browser: ' IsControlElement=false
 ++++++textbox
diff --git a/content/test/data/accessibility/html/mark-expected-uia-win.txt b/content/test/data/accessibility/html/mark-expected-uia-win.txt
index 95f8ba6..88eacb14 100644
--- a/content/test/data/accessibility/html/mark-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/mark-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This test is to check '
-++++description LocalizedControlType='highlight'
+++++description LocalizedControlType='highlight' IsControlElement=false
 ++++++description Name='mark tag'
 ++++description Name='.'
diff --git a/content/test/data/accessibility/html/math-expected-uia-win.txt b/content/test/data/accessibility/html/math-expected-uia-win.txt
index dc1172f1..a9c5d1f 100644
--- a/content/test/data/accessibility/html/math-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/math-expected-uia-win.txt
@@ -1,10 +1,10 @@
 document
-++group
-++++group
+++group IsControlElement=false
+++++group IsControlElement=false
 ++++++description Name='a'
 ++++++description Name='2'
-++++group
+++++group IsControlElement=false
 ++++++description Name='+'
-++++group
+++++group IsControlElement=false
 ++++++description Name='b'
 ++++++description Name='2'
diff --git a/content/test/data/accessibility/html/meter-expected-uia-win.txt b/content/test/data/accessibility/html/meter-expected-uia-win.txt
index 89e72c96..d69991b9 100644
--- a/content/test/data/accessibility/html/meter-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/meter-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document LocalizedControlType='document'
-++group LocalizedControlType='group'
+++group LocalizedControlType='group' IsControlElement=false
 ++++progressbar LocalizedControlType='meter' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=10.00 RangeValue.Minimum=1.00 RangeValue.Value=2.00 Value.Value='2'
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt
index 65d663ea..4baecbb 100644
--- a/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
-++group
-++dialog Window.IsModal=true
+++group IsControlElement=false
+++dialog IsControlElement=false Window.IsModal=true
 ++++description Name='The dialog subtree should be the only text content in the accessibility tree. '
 ++++link Name='Link inside the dialog.'
 ++++++description Name='Link inside the dialog.' IsControlElement=false
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt
index 7275201..15f808d 100644
--- a/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
-++dialog Window.IsModal=true
+++group IsControlElement=false
+++dialog IsControlElement=false Window.IsModal=true
 ++++description Name='This is the now active dialog. Of course it should be in the tree. '
 ++++button Name='This is in the active dialog and should be in the tree.'
diff --git a/content/test/data/accessibility/html/object-expected-uia-win.txt b/content/test/data/accessibility/html/object-expected-uia-win.txt
index e74482a..8cf75072 100644
--- a/content/test/data/accessibility/html/object-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/object-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++document
diff --git a/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt b/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt
index 3e01b27f..9f43eb2 100644
--- a/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++document
 ++++++document
 ++++++++group Name='iframe_onscreen'
diff --git a/content/test/data/accessibility/html/optgroup-expected-uia-win.txt b/content/test/data/accessibility/html/optgroup-expected-uia-win.txt
index 573c808..30dfbaaa 100644
--- a/content/test/data/accessibility/html/optgroup-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/optgroup-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++listbox Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Value.IsReadOnly=false
 ++++++group Name='Enabled'
 ++++++++description Name='Enabled' IsControlElement=false
diff --git a/content/test/data/accessibility/html/output-expected-uia-win.txt b/content/test/data/accessibility/html/output-expected-uia-win.txt
index 5de33980..6e5cdf8 100644
--- a/content/test/data/accessibility/html/output-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/output-expected-uia-win.txt
@@ -4,4 +4,4 @@
 ++++description Name=' + '
 ++++spinbutton RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=0.00 RangeValue.Minimum=0.00 RangeValue.Value=0.00
 ++++description Name=' ='
-++++status LocalizedControlType='output'
+++++status LocalizedControlType='output' IsControlElement=false
diff --git a/content/test/data/accessibility/html/p-expected-uia-win.txt b/content/test/data/accessibility/html/p-expected-uia-win.txt
index ee67a64..ee12578 100644
--- a/content/test/data/accessibility/html/p-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/p-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
 ++description Name='Before'
-++group
+++group IsControlElement=false
 ++++description Name='Paragraph'
 ++description Name='After'
diff --git a/content/test/data/accessibility/html/pre-expected-uia-win.txt b/content/test/data/accessibility/html/pre-expected-uia-win.txt
index 85bd64d..703295d 100644
--- a/content/test/data/accessibility/html/pre-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/pre-expected-uia-win.txt
@@ -1,9 +1,9 @@
 document
-++region
+++region IsControlElement=false
 ++++description Name='This test is to check   pre<newline>formatting.'
-++group
+++group IsControlElement=false
 ++++description Name='This test is to check   pre<newline>formatting'
-++group
+++group IsControlElement=false
 ++++description Name='This test is to check   pre<newline>formatting.'
-++group
+++group IsControlElement=false
 ++++description Name='This test is to check pre formatting.'
diff --git a/content/test/data/accessibility/html/progress-expected-uia-win.txt b/content/test/data/accessibility/html/progress-expected-uia-win.txt
index 02e9645..dab6bdd 100644
--- a/content/test/data/accessibility/html/progress-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/progress-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++progressbar RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=100.00 RangeValue.Minimum=0.00 RangeValue.Value=22.00 Value.Value='22'
 ++++progressbar RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=1.00 RangeValue.Minimum=0.00 RangeValue.Value=0.00
diff --git a/content/test/data/accessibility/html/q-expected-uia-win.txt b/content/test/data/accessibility/html/q-expected-uia-win.txt
index c85b7bb..47b3b84e2 100644
--- a/content/test/data/accessibility/html/q-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/q-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This is '
 ++++description Name='"'
 ++++description Name='Chromium Blink'
diff --git a/content/test/data/accessibility/html/ruby-expected-uia-win.txt b/content/test/data/accessibility/html/ruby-expected-uia-win.txt
index 2ad5cab..18ff2fb 100644
--- a/content/test/data/accessibility/html/ruby-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/ruby-expected-uia-win.txt
@@ -1,6 +1,6 @@
 document
-++group
-++++region
-++++++description
+++group IsControlElement=false
+++++region IsControlElement=false
+++++++description IsControlElement=false
 ++++++++description Name='ruby text'
 ++++++description Name='ruby base'
diff --git a/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt b/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt
index dd1ed8a..a4b795a7 100644
--- a/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt
@@ -1,4 +1,4 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='little'
 ++++textbox Value.Value='lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text'
diff --git a/content/test/data/accessibility/html/select-expected-uia-win.txt b/content/test/data/accessibility/html/select-expected-uia-win.txt
index 7bfe644..5953c08 100644
--- a/content/test/data/accessibility/html/select-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/select-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++combobox ExpandCollapse.ExpandCollapseState='Collapsed' Value.Value='Placeholder option'
 ++++++list Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
 ++++++++listitem Name='Placeholder option' SelectionItem.IsSelected=true
diff --git a/content/test/data/accessibility/html/selection-container-expected-uia-win.txt b/content/test/data/accessibility/html/selection-container-expected-uia-win.txt
index 327dce2..f64d138 100644
--- a/content/test/data/accessibility/html/selection-container-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/selection-container-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++listbox Name='selection_list' Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
 ++++++group Name='Enabled'
 ++++++++description Name='Enabled' IsControlElement=false
diff --git a/content/test/data/accessibility/html/span-expected-uia-win.txt b/content/test/data/accessibility/html/span-expected-uia-win.txt
index efe8df2..57754e1 100644
--- a/content/test/data/accessibility/html/span-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/span-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This'
 ++++description Name=' '
 ++++description Name='paragraph has '
@@ -9,62 +9,62 @@
 ++++description Name=' '
 ++++description Name='spans'
 ++++description Name='.'
-++group
+++group IsControlElement=false
 ++++description Name='E1. Eat'
 ++++description Name=' '
 ++++link Name='space'
 ++++++description Name='space' IsControlElement=false
-++group
+++group IsControlElement=false
 ++++description Name='E2. Eat'
 ++++description Name=' '
 ++++link Name='space'
 ++++++description Name='space' IsControlElement=false
-++group
+++group IsControlElement=false
 ++++description Name='E3. Eat'
 ++++description Name=' '
 ++++link Name='space'
 ++++++description Name='space' IsControlElement=false
-++group
+++group IsControlElement=false
 ++++link Name='E4. Eat'
 ++++++description Name='E4. Eat' IsControlElement=false
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++link Name='E5. Eat'
 ++++++description Name='E5. Eat' IsControlElement=false
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++link Name='E6. Eat'
 ++++++description Name='E6. Eat' IsControlElement=false
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K1. Keep'
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K2. Keep'
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K3. Keep'
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K4. Keep '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K5. Keep'
 ++++description Name=' '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K6. Keep '
 ++++description Name='space'
-++group
+++group IsControlElement=false
 ++++description Name='K7. Keep'
 ++++description Name=' space'
-++group
+++group IsControlElement=false
 ++++description Name='K8. Keep'
 ++++description Name=' '
 ++++description Name='space'
diff --git a/content/test/data/accessibility/html/sub-expected-uia-win.txt b/content/test/data/accessibility/html/sub-expected-uia-win.txt
index 9807886..f72048a 100644
--- a/content/test/data/accessibility/html/sub-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/sub-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This text contains '
 ++++description Name='subscript'
 ++++description Name=' text.'
diff --git a/content/test/data/accessibility/html/sup-expected-uia-win.txt b/content/test/data/accessibility/html/sup-expected-uia-win.txt
index fdab9b2..8c24b2a 100644
--- a/content/test/data/accessibility/html/sup-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/sup-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='This text contains'
 ++++description Name='superscript'
 ++++description Name='text.'
diff --git a/content/test/data/accessibility/html/svg-expected-uia-win.txt b/content/test/data/accessibility/html/svg-expected-uia-win.txt
index 26dc12b..1ce2090 100644
--- a/content/test/data/accessibility/html/svg-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/svg-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++img Name='svg' HelpText='SVG Title Tag'
-++++++group
+++++++group IsControlElement=false
 ++++++++description Name='Test'
diff --git a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
index 3368e45..593cffa 100644
--- a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
@@ -1,24 +1,24 @@
 document Name='Table example - focusable thead, tbody, tfoot'
 ++grid Grid.ColumnCount=2 Grid.RowCount=4 Table.RowOrColumnMajor='RowMajor'
 ++++rowgroup
-++++++row
+++++++row IsControlElement=false
 ++++++++columnheader Name='Sum' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++description Name='Sum' IsControlElement=false
 ++++++++columnheader Name='Subtraction' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++description Name='Subtraction' IsControlElement=false
 ++++rowgroup
-++++++row
+++++++row IsControlElement=false
 ++++++++gridcell Name='10' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++++description Name='10' IsControlElement=false
 ++++++++gridcell Name='7' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++++description Name='7' IsControlElement=false
-++++++row
+++++++row IsControlElement=false
 ++++++++gridcell Name='2' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++++description Name='2' IsControlElement=false
 ++++++++gridcell Name='4' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++++description Name='4' IsControlElement=false
 ++++rowgroup
-++++++row
+++++++row IsControlElement=false
 ++++++++gridcell Name='12' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
 ++++++++++description Name='12' IsControlElement=false
 ++++++++gridcell Name='3' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/html/table-layout-expected-uia-win.txt b/content/test/data/accessibility/html/table-layout-expected-uia-win.txt
index a3f279d..70857a5 100644
--- a/content/test/data/accessibility/html/table-layout-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-layout-expected-uia-win.txt
@@ -1,23 +1,23 @@
 document Name='Table example #2'
 ++grid Grid.ColumnCount=3 Grid.RowCount=3 Table.RowOrColumnMajor='RowMajor'
-++++row
+++++row IsControlElement=false
 ++++++gridcell Name='1' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
-++++++++description Name='1'
+++++++++description Name='1' IsControlElement=false
 ++++++gridcell Name='2' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
-++++++++description Name='2'
+++++++++description Name='2' IsControlElement=false
 ++++++gridcell Name='3' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
-++++++++description Name='3'
-++++row
+++++++++description Name='3' IsControlElement=false
+++++row IsControlElement=false
 ++++++gridcell Name='4' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
-++++++++description Name='4'
+++++++++description Name='4' IsControlElement=false
 ++++++gridcell Name='5' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
-++++++++description Name='5'
+++++++++description Name='5' IsControlElement=false
 ++++++gridcell Name='6' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
-++++++++description Name='6'
-++++row
+++++++++description Name='6' IsControlElement=false
+++++row IsControlElement=false
 ++++++gridcell Name='7' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
-++++++++description Name='7'
+++++++++description Name='7' IsControlElement=false
 ++++++gridcell Name='8' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
-++++++++description Name='8'
+++++++++description Name='8' IsControlElement=false
 ++++++gridcell Name='9' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
-++++++++description Name='9'
+++++++++description Name='9' IsControlElement=false
diff --git a/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt b/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt
index ea02498..c4764267 100644
--- a/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt
@@ -1,9 +1,9 @@
 document Name='Table with role=presentation'
-++group
+++group IsControlElement=false
 ++++description Name='1'
-++group
+++group IsControlElement=false
 ++++description Name='2'
-++group
+++group IsControlElement=false
 ++++description Name='4'
-++group
+++group IsControlElement=false
 ++++description Name='5'
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
index 8282ba2..680d8bf5f4 100644
--- a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
@@ -1,11 +1,11 @@
 document
 ++grid Grid.ColumnCount=2 Grid.RowCount=2 Table.RowOrColumnMajor='RowMajor'
-++++row
+++++row IsControlElement=false
 ++++++columnheader Name='Firstname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++description Name='Firstname' IsControlElement=false
 ++++++columnheader Name='Lastname' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++description Name='Lastname' IsControlElement=false
-++++row
+++++row IsControlElement=false
 ++++++gridcell Name='Jill' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++description Name='Jill' IsControlElement=false
 ++++++gridcell Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
index f717d1e..d0b908d8 100644
--- a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
@@ -1,11 +1,11 @@
 document Name='Table example - th rowheader'
 ++grid Grid.ColumnCount=2 Grid.RowCount=2 Table.RowOrColumnMajor='RowMajor'
-++++row
+++++row IsControlElement=false
 ++++++rowheader Name='Firstname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++description Name='Firstname' IsControlElement=false
 ++++++gridcell Name='Jill' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++description Name='Jill' IsControlElement=false
-++++row
+++++row IsControlElement=false
 ++++++rowheader Name='Lastname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++description Name='Lastname' IsControlElement=false
 ++++++gridcell Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/html/textarea-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-expected-uia-win.txt
index a3c95cf..d8b1205 100644
--- a/content/test/data/accessibility/html/textarea-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/textarea-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='The <newline>textarea tag  defines a multi-line text input control.<newline>'
diff --git a/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt
index d968b8fa..9c159ed 100644
--- a/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='The textarea tag defines a multi-line text input control.<newline>'
diff --git a/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt
index d968b8fa..9c159ed 100644
--- a/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt
@@ -1,3 +1,3 @@
 document
-++group
+++group IsControlElement=false
 ++++textbox Value.Value='The textarea tag defines a multi-line text input control.<newline>'
diff --git a/content/test/data/accessibility/html/time-expected-uia-win.txt b/content/test/data/accessibility/html/time-expected-uia-win.txt
index 8efb7c1..8766d42 100644
--- a/content/test/data/accessibility/html/time-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/time-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++time LocalizedControlType='time'
 ++++++description Name='10:00'
 ++++description Name=' '
diff --git a/content/test/data/accessibility/html/wbr-expected-uia-win.txt b/content/test/data/accessibility/html/wbr-expected-uia-win.txt
index 712587b..2056c64 100644
--- a/content/test/data/accessibility/html/wbr-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/wbr-expected-uia-win.txt
@@ -1,5 +1,5 @@
 document
-++group
+++group IsControlElement=false
 ++++description Name='Supercali'
 ++++description Name='fragilistic'
 ++++description Name='expialidocious'
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 49c4b5e6..b36150d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -737,15 +737,12 @@
 
 # Video uploads to some texture formats new in WebGL 2.0 are
 # failing.
-crbug.com/906735 [ android ] conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ Failure ]
-crbug.com/906735 [ android ] conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ Failure ]
 crbug.com/951628 [ android no-passthrough ] conformance/rendering/blending.html [ Failure ]
 
 # Qualcomm (Pixel 2) failures
 crbug.com/906737 [ android qualcomm ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ]
 crbug.com/906742 [ android qualcomm no-passthrough ] conformance2/glsl3/compare-structs-containing-arrays.html [ Failure ]
 crbug.com/1008535 [ android qualcomm-adreno-(tm)-540 passthrough ] conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html [ Skip ]
-crbug.com/906735 [ android qualcomm ] conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ]
 crbug.com/981216 [ android qualcomm-adreno-(tm)-540 ] deqp/functional/gles3/fbocolorbuffer/tex2d_01.html [ RetryOnFailure ]
 crbug.com/949321 [ android qualcomm ] deqp/functional/gles3/framebufferblit/default_framebuffer_02.html [ RetryOnFailure ]
 crbug.com/1022410 [ android qualcomm ] conformance2/transform_feedback/switching-objects.html [ RetryOnFailure ]
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index 29008ac..408f1490 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -50,8 +50,7 @@
       expect_set_history_offset_and_length_(false),
       expect_set_history_offset_and_length_history_length_(0),
       pause_subresource_loading_called_(false),
-      audio_group_id_(base::UnguessableToken::Create()),
-      is_connected_to_bluetooth_device_(false) {
+      audio_group_id_(base::UnguessableToken::Create()) {
   if (!RenderProcessHostImpl::get_render_process_host_factory_for_testing()) {
     // Most unit tests should prefer to create a generic MockRenderProcessHost
     // (instead of a real RenderProcessHostImpl).  Tests that need to use a
@@ -447,14 +446,12 @@
   last_active_time_ = last_active_time;
 }
 
-void TestWebContents::SetIsConnectedToBluetoothDevice(
-    bool is_connected_to_bluetooth_device) {
-  is_connected_to_bluetooth_device_ = is_connected_to_bluetooth_device;
+void TestWebContents::TestIncrementBluetoothConnectedDeviceCount() {
+  IncrementBluetoothConnectedDeviceCount();
 }
 
-bool TestWebContents::IsConnectedToBluetoothDevice() {
-  return is_connected_to_bluetooth_device_ ||
-         WebContentsImpl::IsConnectedToBluetoothDevice();
+void TestWebContents::TestDecrementBluetoothConnectedDeviceCount() {
+  DecrementBluetoothConnectedDeviceCount();
 }
 
 base::UnguessableToken TestWebContents::GetAudioGroupId() {
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h
index 9c36ced..9987c17 100644
--- a/content/test/test_web_contents.h
+++ b/content/test/test_web_contents.h
@@ -165,11 +165,8 @@
 
   void SetLastActiveTime(base::TimeTicks last_active_time) override;
 
-  void SetIsConnectedToBluetoothDevice(
-      bool is_connected_to_bluetooth_device) override;
-
-  // Override IsConnectedToBluetoothDevice() to allow using the mocked value.
-  bool IsConnectedToBluetoothDevice() override;
+  void TestIncrementBluetoothConnectedDeviceCount() override;
+  void TestDecrementBluetoothConnectedDeviceCount() override;
 
   base::UnguessableToken GetAudioGroupId() override;
 
@@ -222,7 +219,6 @@
   base::Optional<base::string16> title_;
   bool pause_subresource_loading_called_;
   base::UnguessableToken audio_group_id_;
-  bool is_connected_to_bluetooth_device_;
 };
 
 }  // namespace content
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc
index 5d7dacc..5724474 100644
--- a/device/bluetooth/dbus/bluez_dbus_manager.cc
+++ b/device/bluetooth/dbus/bluez_dbus_manager.cc
@@ -244,14 +244,9 @@
 }
 
 std::string BluezDBusManager::GetBluetoothServiceName() {
-  bool use_newblue = false;
-#if defined(OS_CHROMEOS)
-  use_newblue = base::FeatureList::IsEnabled(device::kNewblueDaemon);
-#endif  // defined(OS_CHROMEOS)
-
-  return use_newblue
-             ? bluetooth_object_manager::kBluetoothObjectManagerServiceName
-             : bluez_object_manager::kBluezObjectManagerServiceName;
+  // TODO(b/145163508): Remove the NewBlue feature flag as Bluetooth service is
+  // now always BlueZ.
+  return bluez_object_manager::kBluezObjectManagerServiceName;
 }
 
 // static
diff --git a/device/bluetooth/strings/bluetooth_strings_eu.xtb b/device/bluetooth/strings/bluetooth_strings_eu.xtb
index b863d77..aad526f4 100644
--- a/device/bluetooth/strings/bluetooth_strings_eu.xtb
+++ b/device/bluetooth/strings/bluetooth_strings_eu.xtb
@@ -17,6 +17,7 @@
 <translation id="5271696982761495740">Tableta (<ph name="ADDRESS" />)</translation>
 <translation id="5376363957846771741">Gailu ezezaguna edo bateraezina (<ph name="ADDRESS" />)</translation>
 <translation id="5716052956047449618">Modema (<ph name="DEVICE_NAME" />)</translation>
+<translation id="6459740836740815150">Autorako audio-gailua (<ph name="DEVICE_NAME" />)</translation>
 <translation id="6542922424766292144">Teklatua (<ph name="DEVICE_NAME" />)</translation>
 <translation id="654594702871184195">Audioa (<ph name="ADDRESS" />)</translation>
 <translation id="6744468237221042970">Ordenagailua (<ph name="ADDRESS" />)</translation>
@@ -26,5 +27,6 @@
 <translation id="8866374292072238753">Bideoa (<ph name="ADDRESS" />)</translation>
 <translation id="8952558712545617651">Sagua (<ph name="ADDRESS" />)</translation>
 <translation id="8961448405689538648">Gailu mota ezezaguna (<ph name="DEVICE_NAME" />)</translation>
+<translation id="907431882454731668">Gailu periferikoa (<ph name="ADDRESS" />)</translation>
 <translation id="978248992969828584">Telefonoa (<ph name="ADDRESS" />)</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/device/bluetooth/strings/bluetooth_strings_fr.xtb b/device/bluetooth/strings/bluetooth_strings_fr.xtb
index be8c6a5..9f0cc96 100644
--- a/device/bluetooth/strings/bluetooth_strings_fr.xtb
+++ b/device/bluetooth/strings/bluetooth_strings_fr.xtb
@@ -17,7 +17,7 @@
 <translation id="5271696982761495740">Tablette (<ph name="ADDRESS" />)</translation>
 <translation id="5376363957846771741">Appareil inconnu ou non compatible (<ph name="ADDRESS" />)</translation>
 <translation id="5716052956047449618"><ph name="DEVICE_NAME" />, modem</translation>
-<translation id="6459740836740815150"><ph name="DEVICE_NAME" />, appareil audio pour automobile</translation>
+<translation id="6459740836740815150"><ph name="DEVICE_NAME" />, appareil audio pour voiture</translation>
 <translation id="6542922424766292144"><ph name="DEVICE_NAME" />, clavier</translation>
 <translation id="654594702871184195">Audio (<ph name="ADDRESS" />)</translation>
 <translation id="6744468237221042970">Ordinateur (<ph name="ADDRESS" />)</translation>
diff --git a/device/bluetooth/strings/bluetooth_strings_km.xtb b/device/bluetooth/strings/bluetooth_strings_km.xtb
index 06f4914c..cad548eb 100644
--- a/device/bluetooth/strings/bluetooth_strings_km.xtb
+++ b/device/bluetooth/strings/bluetooth_strings_km.xtb
@@ -17,6 +17,7 @@
 <translation id="5271696982761495740">ថេប្លេត (<ph name="ADDRESS" />)</translation>
 <translation id="5376363957846771741">ឧបករណ៍ដែលមិនស្គាល់ និងមិនមានការគាំទ្រ (<ph name="ADDRESS" />)</translation>
 <translation id="5716052956047449618"><ph name="DEVICE_NAME" />, ម៉ូដឹម</translation>
+<translation id="6459740836740815150"><ph name="DEVICE_NAME" />, ឧបករណ៍​សំឡេង​របស់​រថយន្ត</translation>
 <translation id="6542922424766292144"><ph name="DEVICE_NAME" />, ក្ដារចុច</translation>
 <translation id="654594702871184195">ប្រព័ន្ធសម្លេង (<ph name="ADDRESS" />)</translation>
 <translation id="6744468237221042970">កុំព្យូទ័រ (<ph name="ADDRESS" />)</translation>
@@ -26,5 +27,6 @@
 <translation id="8866374292072238753">វីដេអូ (<ph name="ADDRESS" />)</translation>
 <translation id="8952558712545617651">កណ្តុរ (<ph name="ADDRESS" />)</translation>
 <translation id="8961448405689538648"><ph name="DEVICE_NAME" />, ប្រភេទ​ឧបករណ៍​ដែលមិនស្គាល់</translation>
+<translation id="907431882454731668">ឧបករណ៍​សម្រាប់​ភ្ជាប់​ជាមួយ​កុំព្យូទ័រ (<ph name="ADDRESS" />)</translation>
 <translation id="978248992969828584">ទូរស័ព្ទ (<ph name="ADDRESS" />)</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
index b7ccaa45..004b1e83 100644
--- a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
+++ b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
@@ -24,7 +24,7 @@
     @VisibleForTesting
     static final String MICROSOFT_XBOX_PAD_DEVICE_NAME = "Microsoft X-Box 360 pad";
     @VisibleForTesting
-    static final String PS3_SIXAXIS_DEVICE_NAME = "Sony PLAYSTATION(R)3 Controller";
+    static final String PS_DUALSHOCK_3_SIXAXIS_DEVICE_NAME = "Sony PLAYSTATION(R)3 Controller";
     @VisibleForTesting
     static final String SAMSUNG_EI_GP20_DEVICE_NAME = "Samsung Game Pad EI-GP20";
     @VisibleForTesting
@@ -57,13 +57,19 @@
     @TargetApi(Build.VERSION_CODES.KITKAT)
     @VisibleForTesting
     static GamepadMappings getMappings(int productId, int vendorId) {
-        // Device name of a PS4 gamepad is "Wireless Controller". This is not reliably unique
-        // so we better go by the product and vendor ids.
+        // Device name of a DualShock 4 gamepad is "Wireless Controller". This is not reliably
+        // unique so we better go by the product and vendor ids.
         if (vendorId == PS_DUALSHOCK_4_VENDOR_ID
                 && (productId == PS_DUALSHOCK_4_PRODUCT_ID
                            || productId == PS_DUALSHOCK_4_SLIM_PRODUCT_ID
                            || productId == PS_DUALSHOCK_4_USB_RECEIVER_PRODUCT_ID)) {
-            return new PS4GamepadMappings();
+            // Android 9 included improvements for Sony PlayStation gamepads that changed the
+            // KeyEvent and MotionEvent codes for some buttons and axes. Use an alternate mapping
+            // for versions of Android that include these improvements.
+            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                return new XboxCompatibleGamepadMappings();
+            }
+            return new Dualshock4GamepadMappingsPreP();
         }
         // Microsoft released a firmware update for the Xbox One S gamepad that modified the button
         // and axis assignments. With the new firmware, these gamepads work correctly in Android
@@ -82,8 +88,14 @@
         if (deviceName.startsWith(NVIDIA_SHIELD_DEVICE_NAME_PREFIX)
                 || deviceName.equals(MICROSOFT_XBOX_PAD_DEVICE_NAME)) {
             return new XboxCompatibleGamepadMappings();
-        } else if (deviceName.equals(PS3_SIXAXIS_DEVICE_NAME)) {
-            return new PS3SixAxisGamepadMappings();
+        } else if (deviceName.equals(PS_DUALSHOCK_3_SIXAXIS_DEVICE_NAME)) {
+            // Android 9 included improvements for Sony PlayStation gamepads that changed the
+            // KeyEvent and MotionEvent codes for some buttons and axes. Use an alternate mapping
+            // for versions of Android that include these improvements.
+            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                return new Dualshock3SixAxisGamepadMappings();
+            }
+            return new Dualshock3SixAxisGamepadMappingsPreP();
         } else if (deviceName.equals(SAMSUNG_EI_GP20_DEVICE_NAME)) {
             return new SamsungEIGP20GamepadMappings();
         } else if (deviceName.equals(AMAZON_FIRE_DEVICE_NAME)) {
@@ -332,16 +344,15 @@
         }
     }
 
-    private static class PS3SixAxisGamepadMappings extends GamepadMappings {
-
+    private static class Dualshock3SixAxisGamepadMappingsPreP extends GamepadMappings {
         /**
-         * Method for mapping PS3 gamepad axis and button values
-         * to standard gamepad button and axes values.
+         * Method for mapping DualShock 3 and SIXAXIS gamepad inputs to standard gamepad button and
+         * axis values. This mapping function should only be used on Android 8 and earlier.
          */
         @Override
         public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
                 float[] rawAxes, float[] rawButtons) {
-            // On PS3 X/Y has higher priority.
+            // On DualShock 3 and SIXAXIS, X/Y has higher priority.
             float a = rawButtons[KeyEvent.KEYCODE_BUTTON_A];
             float b = rawButtons[KeyEvent.KEYCODE_BUTTON_B];
             float x = rawButtons[KeyEvent.KEYCODE_BUTTON_X];
@@ -362,15 +373,34 @@
         }
     }
 
-    static class PS4GamepadMappings extends GamepadMappings {
+    private static class Dualshock3SixAxisGamepadMappings extends GamepadMappings {
+        /**
+         * Method for mapping DualShock 3 and SIXAXIS gamepad inputs to standard gamepad button and
+         * axis values. This mapping function should only be used on Android 10+.
+         */
+        @Override
+        public void mapToStandardGamepad(
+                float[] mappedAxes, float[] mappedButtons, float[] rawAxes, float[] rawButtons) {
+            mapCommonXYABButtons(mappedButtons, rawButtons);
+            mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
+            mapCommonThumbstickButtons(mappedButtons, rawButtons);
+            mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+            mapCommonDpadButtons(mappedButtons, rawButtons);
+            mapXYAxes(mappedAxes, rawAxes);
+            mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+            mapTriggerAxesToBottomShoulder(mappedButtons, rawAxes);
+        }
+    }
+
+    static class Dualshock4GamepadMappingsPreP extends GamepadMappings {
         // Scale input from [-1, 1] to [0, 1] uniformly.
         private static float scaleRxRy(float input) {
             return 1.f - ((1.f - input) / 2.f);
         }
 
         /**
-         * Method for mapping PS4 gamepad axis and button values
-         * to standard gamepad button and axes values.
+         * Method for mapping DualShock 4 gamepad inputs to standard gamepad button and axis values.
+         * This mapping function should only be used on Android 9 and earlier.
          */
         @Override
         public void mapToStandardGamepad(
@@ -414,9 +444,8 @@
     }
 
     private static class SamsungEIGP20GamepadMappings extends GamepadMappings {
-
         /**
-         * Method for mapping PS3 gamepad axis and button values
+         * Method for mapping Samsung GamePad EI-GP20 axis and button values
          * to standard gamepad button and axes values.
          */
         @Override
diff --git a/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java b/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java
index 599f9d2..cab756c 100644
--- a/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java
+++ b/device/gamepad/android/junit/src/org/chromium/device/gamepad/GamepadMappingsTest.java
@@ -10,7 +10,6 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
@@ -94,17 +93,29 @@
     @Feature({"Gamepad"})
     public void testPS3SixAxisGamepadMappings() {
         GamepadMappings mappings =
-                GamepadMappings.getMappings(GamepadMappings.PS3_SIXAXIS_DEVICE_NAME);
+                GamepadMappings.getMappings(GamepadMappings.PS_DUALSHOCK_3_SIXAXIS_DEVICE_NAME);
         mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons);
 
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            // Changes in Android 9 caused the DualShock 3 and SIXAXIS mappings to change.
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
+        } else {
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
+        }
 
         assertMappedTriggerButtonsToTopShoulder();
         assertMappedCommonThumbstickButtons();
@@ -268,7 +279,6 @@
     }
 
     @Test
-    @Ignore("https://crbug.com/719765")
     @Feature({"Gamepad"})
     public void testPS4GamepadMappings() {
         GamepadMappings mappings =
@@ -276,31 +286,56 @@
                         GamepadMappings.PS_DUALSHOCK_4_VENDOR_ID);
         mappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons);
 
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_C], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            // Changes in Android 9 caused the DualShock 4 mapping to change.
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
 
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_Z], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
-                mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_L1], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_R1], ERROR_TOLERANCE);
 
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
-                mRawAxes[MotionEvent.AXIS_RX], ERROR_TOLERANCE);
-        Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
-                mRawAxes[MotionEvent.AXIS_RY], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
+                    mRawAxes[MotionEvent.AXIS_LTRIGGER], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
+                    mRawAxes[MotionEvent.AXIS_RTRIGGER], ERROR_TOLERANCE);
+
+            assertMappedCommonThumbstickButtons();
+        } else {
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_C], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
+
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_Z], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
+                    mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
+
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
+                    mRawAxes[MotionEvent.AXIS_RX], ERROR_TOLERANCE);
+            Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
+                    mRawAxes[MotionEvent.AXIS_RY], ERROR_TOLERANCE);
+
+            expectNoThumbstickButtons();
+        }
 
         assertMappedCommonStartSelectMetaButtons();
         assertMappedXYAxes();
         assertMappedHatAxisToDpadButtons();
         assertMappedZAndRZAxesToRightStick();
 
-        expectNoThumbstickButtons();
         assertMapping();
     }
 
diff --git a/docs/asan.md b/docs/asan.md
new file mode 100644
index 0000000..53940df
--- /dev/null
+++ b/docs/asan.md
@@ -0,0 +1,296 @@
+# AddressSanitizer (ASan)
+
+[AddressSanitizer](https://github.com/google/sanitizers) (ASan) is a fast memory
+error detector based on compiler instrumentation (LLVM). It is fully usable for
+Chrome on Linux and Mac. There's a mostly-functional Windows port in progress
+too. Additional info on the tool itself is available at
+http://clang.llvm.org/docs/AddressSanitizer.html.
+
+For the memory leak detector built into ASan, see
+[LeakSanitizer](https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer).
+If you want to debug memory leaks, please refer to the instructions on that page
+instead.
+
+## Buildbots and trybots
+
+The [Chromium Memory
+waterfall](https://ci.chromium.org/p/chromium/g/chromium.memory/console) (not to
+be confused with the Memory FYI waterfall) contains buildbots running Chromium
+tests under ASan on Linux (Linux ASan/LSan bots for the regular Linux build,
+Linux Chromium OS ASan for the chromeos=1 build running on Linux), OS X (both 32
+and 64 bits), Chromium OS (x86 and amd64 builds running inside VMs). Linux and
+Linux Chromium OS bots run with --no-sandbox, but there's an extra Linux bot
+that enables the sandbox (but disables LeakSanitizer).
+
+The trybots running Chromium tests on Linux and OSX are: linux_asan (everything
+except browser_tests and content_browsertests), linux_browser_asan
+(browser_tests and content_browsertests), mac_asan (many tests including
+browser_tests and content_browsertests), linux_chromeos_asan (the chromeos=1
+build running on a Linux machine, many tests including browser_tests and
+content_browsertests).
+
+(Outdated) Blink bots: WebKit Linux ASAN buildbot and linux_layout_asan trybot.
+
+## Pre-built Chrome binaries
+
+You can grab fresh Chrome binaries built with ASan
+[here](https://commondatastorage.googleapis.com/chromium-browser-asan/index.html).
+
+## Build tests with ASan
+
+If you're on mac or linux64, building with ASan is easy. Start by compiling
+`base_unittests` to verify the build is working for you (see below), then you
+can compile `chrome`, `browser_tests`, etc.. Make sure to compile release
+builds.
+
+Make sure you've run `tools/clang/scripts/update.py` (see
+https://chromium.googlesource.com/chromium/src/+/master/docs/clang.md for
+details).
+
+### Configuring the build
+
+Create an asan build directory by running:
+```
+gn args out/asan
+```
+
+Enter the following build variables in the editor that will pop up:
+```
+is_asan = true
+is_debug = false  # Release build.
+```
+
+Build with:
+```
+ninja -C out/asan base_unittests
+```
+
+### Goma build
+
+ASan builds should work seamlessly with Goma (except for Windows); just add
+`use_goma=1` to your `GYP_DEFINES` or `use_goma=true` in your "gn args" Don't
+forget to use ninja -j <jobs> to take advantage of goma.
+
+### Build options
+
+If you want your stack traces to be precise, you will have to disable inlining
+by setting the GN arg:
+```
+enable_full_stack_frames_for_profiling = true
+```
+
+Note that this incurs a significant performance hit. Please do not do this on
+buildbots.
+
+If you're working on reproducing ClusterFuzz reports, you might want to add:
+```
+v8_enable_verify_heap = true
+```
+
+in order to enable the --verify-heap command line flag for v8 in Release builds.
+
+## Verify the ASan tool works
+
+**ATTENTION (Linux only)**: These instructions are for running ASan in a way
+that is compatible with the sandbox. However, this is not compatible with
+LeakSanitizer. If you want to debug memory leaks, please use the instructions on
+the
+[LeakSanitizer](https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer)
+page instead.
+
+Now, check that the tool works. Run the following:
+```
+out/asan/base_unittests
+--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest
+--gtest_also_run_disabled_tests 2>&1 | tools/valgrind/asan/asan_symbolize.py
+```
+
+The test will crash with the following error report:
+```
+==26552== ERROR: AddressSanitizer stack-buffer-overflow on address 0x7fff338adb14 at pc 0xac20a7 bp 0x7fff338adad0 sp 0x7fff338adac8
+WRITE of size 4 at 0x7fff338adb14 thread T0
+    #0 0xac20a7 in base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody() ???:0
+    #1 0xcddbd6 in testing::Test::Run() testing/gtest/src/gtest.cc:2161
+    #2 0xcdf63b in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2338
+... lots more stuff
+Address 0x7fff338adb14 is located at offset 52 in frame <base::ToolsSanityTest_DISABLED_AddressSanitizerLocalOOBCrashTest_Test::TestBody()> of T0's stack:
+  This frame has 2 object(s):
+    [32, 52) 'array'
+    [96, 104) 'access'
+==26552== ABORTING
+... lots more stuff
+```
+
+Congrats, you have a working ASan build! 🙌
+
+## Run chrome under ASan
+
+And finally, have fun with the `out/Release/chrome binary`. The filter script
+`tools/valgrind/asan/asan_symbolize.py` should be used to symbolize the output.
+(Note that `asan_symbolize.py` is absolutely necessary if you need the symbols -
+there is no built-in symbolizer for ASan in Chrome).
+
+ASan should perfectly work with Chrome's sandbox. You should only need to run
+with `--no-sandbox` on Linux if you're debugging ASan.
+Note: you have to disable the sandbox on Windows until it is supported.
+
+You may need to run with `--disable-gpu` on Linux with NVIDIA driver older than
+295.20.
+
+You will likely need to define environment variable
+[`G_SLICE=always-malloc`](https://developer.gnome.org/glib/unstable/glib-running.html)
+to avoid crashes inside gtk.
+NSS_DISABLE_ARENA_FREE_LIST=1 and NSS_DISABLE_UNLOAD=1 are required as well.
+
+When filing a bug found by AddressSanitizer, please add a label
+`Stability-AddressSanitizer`.
+
+## ASan runtime options
+
+ASan's behavior can be changed by exporting the `ASAN_OPTIONS` env var. Some of
+the useful options are listed on this page, others can be obtained from running
+an ASanified binary with `ASAN_OPTIONS=help=1`. Note that Chromium sets its own
+defaults for some options, so the default behavior may be different from that
+observed in other projects.
+See `base/debug/sanitizer_options.cc` for more details.
+
+## NaCl support under ASan
+
+On Linux (and soon on Mac) you can build and run Chromium with NaCl under ASan.
+Untrusted code (nexe) itself is not instrumented with ASan in this mode, but
+everything else is.
+
+To do this, remove `disable_nacl=1` from `GYP_DEFINES`, and define
+`NACL_DANGEROUS_SKIP_QUALIFICATION_TEST=1` in your environment at run time.
+
+Pipe chromium output (stderr) through ``tools/valgrind/asan/asan_symbolize.py
+`pwd`/`` to get function names and line numbers in ASan reports.
+If you're seeing crashes within `nacl_helper_bootstrap`, try deleting `out/Release/nacl_helper`.
+
+## Building on iOS
+
+It's possible to build and run Chrome tests for iOS simulator (which are x86
+binaries essentially) under ASan. Note that you'll need a Chrome iOS checkout
+for that. It isn't currently possible to build iOS binaries targeting ARM.
+
+Configure your build with `is_asan = true` as described above. Replace your
+build directory as needed:
+```
+ninja -C out/Release-iphonesimulator base_unittests
+out/Release-iphonesimulator/iossim -d "iPhone" -s 7.0 out/Release-iphonesimulator/base_unittests.app/ \
+--gtest_filter=ToolsSanityTest.DISABLED_AddressSanitizerLocalOOBCrashTest --gtest_also_run_disabled_tests 2>&1 |
+tools/valgrind/asan/asan_symbolize.py
+```
+
+You'll see the same report as shown above (see the "Verify the ASan tool works"
+section), with a number of iOS-specific frames.
+
+## Building on Android
+
+Follow [AndroidBuildInstructions](android_build_instructions.md) with minor
+changes:
+
+    target_os="android"
+    is_clang=true
+    is_asan=true
+    is_debug=false
+
+Running ASan applications on Android requires additional device setup. Chromium
+testing scripts take care of this, so testing works as expected:
+```
+build/android/test_runner.py instrumentation --test-apk ContentShellTest
+--test_data content:content/test/data/android/device_files -v -v -v --tool=asan
+--release
+```
+
+To run stuff without Chromium testing script (ex. ContentShell.apk, or any third
+party apk or binary), device setup is needed:
+```
+tools/android/asan/third_party/asan_device_setup.sh --lib
+third_party/llvm-build/Release+Asserts/lib/clang/*/lib/linux/libclang_rt.asan-arm-android.so
+# wait a few seconds for the device to reload
+```
+
+It only needs to be run once per device. It is safe to run it multiple times.
+When this is done, the device will run ASan apks as well as normal apks without
+any further setup.
+
+To run command-line tools (i.e. binaries), prefix them with `asanwrapper`:
+```
+adb shell /system/bin/asanwrapper /path/to/binary
+```
+
+Use `build/android/asan_symbolize.py` to symbolize stack from `adb logcat`. It needs the `--output-directory` argument and takes care of translating the device path to the unstripped binary in the output directory.
+
+## Building with v8_target_arch=arm
+
+This is needed to detect addressability bugs in the ARM code emitted by V8 and
+running on an instrumented ARM emulator in a 32-bit x86 Linux Chromium. **You
+probably don't want this, and these instructions have bitrotted because they
+still reference GYP. If you do this successfully, please update!** See
+[http://crbug.com/324207](https://bugs.chromium.org/p/chromium/issues/detail?id=324207)
+for some context.
+
+First, you need to install the 32-bit chroot environment using the
+`build/install-chroot.sh` script (as described in
+https://code.google.com/p/chromium/wiki/LinuxBuild32On64). Second, install the
+build deps:
+```
+precise32 build/install-build-deps.sh  # assuming your schroot wrapper is called 'precise32'
+```
+
+You'll need to make two symlinks to avoid linking errors:
+```
+sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libc_nonshared.a /usr/lib/i386-linux-gnu/libc_nonshared.a
+sudo ln -s $CHROOT/usr/lib/i386-linux-gnu/libpthread_nonshared.a /usr/lib/i386-linux-gnu/libpthread_nonshared.a
+```
+
+Now configure and build your Chrome:
+```
+GYP_GENERATOR_FLAGS="output_dir=out_asan_chroot" GYP_DEFINES="asan=1 disable_nacl=1 v8_target_arch=arm sysroot=/var/lib/chroot/precise32bit/ chroot_cmd=precise32 host_arch=x86_64 target_arch=ia32" gclient runhooks
+ninja -C out_asan_chroot/Release chrome
+```
+
+**Note**: `disable_nacl=1` is needed for now.
+
+## AsanCoverage
+
+AsanCoverage is a minimalistic code coverage implementation built into ASan. For
+general information see
+[https://code.google.com/p/address-sanitizer/wiki/AsanCoverage](https://github.com/google/sanitizers)
+To use AsanCoverage in Chromium, add `use_sanitizer_coverage = true` to your GN
+args. See also the `sanitizer_coverage_flags` variable for configuring it.
+
+Chrome must be terminated gracefully in order for coverage to work. Either close
+the browser, or SIGTERM the browser process. Do not do `killall chrome` or send
+SIGKILL.
+```
+$ kill <browser_process_pid>
+$ ls
+...
+chrome.22575.sancov
+gpu.6916123572022919124.sancov.packed
+zygote.13651804083035800069.sancov.packed
+...
+```
+
+The `gpu.*.sancov.packed` file contains coverage data for the GPU process,
+whereas the `zygote.*.sancov.packed` file contains coverage data for the
+renderers (but not the zygote process). Unpack them to regular `.sancov` files
+like so:
+```
+$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py unpack *.sancov.packed
+sancov.py: unpacking gpu.6916123572022919124.sancov.packed
+sancov.py: extracting chrome.22610.sancov
+sancov.py: unpacking zygote.13651804083035800069.sancov.packed
+sancov.py: extracting libpdf.so.12.sancov
+sancov.py: extracting chrome.12.sancov
+sancov.py: extracting libpdf.so.10.sancov
+sancov.py: extracting chrome.10.sancov
+```
+
+Now, e.g., to list the offsets of covered functions in the libpdf.so binary in
+renderer with pid 10:
+```
+$ $LLVM/projects/compiler-rt/lib/sanitizer_common/scripts/sancov.py print libpdf.so.10.sancov
+```
diff --git a/docs/clang_tidy.md b/docs/clang_tidy.md
index 72e3d5c..b872670 100644
--- a/docs/clang_tidy.md
+++ b/docs/clang_tidy.md
@@ -2,13 +2,6 @@
 
 [TOC]
 
-## Danger, Will Robinson!
-
-Support for `clang-tidy` in Chromium is very experimental, and is somewhat
-painful to use. We are exploring making it easier and integrating with existing
-tools, but aren't there yet. If you don't want to wait and enjoy tinkering,
-forge ahead. Otherwise, feel free to turn back now.
-
 ## Introduction
 
 [clang-tidy](http://clang.llvm.org/extra/clang-tidy/) is a clang-based C++
@@ -16,63 +9,82 @@
 and fixing typical programming errors, like style violations, interface misuse,
 or bugs that can be deduced via static analysis.
 
-## Setting Up
+## Where is it?
 
-### Automatic Setup
+clang-tidy is available in two places in Chromium:
 
-The script [clang_tidy_tool.py](../tools/clang/scripts/clang_tidy_tool.py) will
-automatically fetch, build, and invoke `clang-tidy`. To do this manually, follow
-the steps in the next section.
+- In Chromium checkouts
+- In code review on Gerrit
 
-### Manual Setup
+Clang-tidy automatically runs on any CL that Chromium committers upload to
+Gerrit, and will leave code review comments there. This is the recommended way
+of using clang-tidy.
 
-In addition to a full Chromium checkout, you need the clang-tidy binary. We
-recommend checking llvm's clang source and building the clang-tidy binary
-directly. Instructions for getting started with clang are available from
-[llvm](http://clang.llvm.org/get_started.html). You'll need to get llvm,
-clang, and the extra clang tools (you won't need Compiler-RT or libcxx).
-If you don't have it, you'll also need to install CMake as a part of this
-process.
+## Enabled checks
 
-Instead of building with `"Unix Makefiles"`, generate build files for Ninja with
+Chromium globally enables a subset of all of clang-tidy's checks (see
+`${chromium}/src/.clang-tidy`). We want these checks to cover as much as we
+reasonably can, but we also strive to strike a reasonable balance between signal
+and noise on code reviews. Hence, a large number of clang-tidy checks are
+disabled.
+
+### Adding a new check
+
+If you'd like to propose the addition of a new check, please send an email to
+cxx@chromium.org describing why you think the check is helpful. If the proposed
+check is approved, you may turn it on, though please note that this is only
+provisional approval: we get signal from users clicking "Not Useful" on
+comments. If feedback is overwhelmingly "users don't find this useful," the
+check may be removed.
+
+## But I want to run it locally
+
+If you want to sync the officially-supported `clang-tidy` to your workstation,
+add the following to your .gclient file:
+
 ```
-cmake -GNinja \
-    -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra \
-    -DCMAKE_BUILD_TYPE=Release \
-    ../llvm
+solutions = [
+  {
+    'custom_vars': {
+      'checkout_clang_tidy': True,
+    },
+  },
+]
 ```
 
-Then, instead of using `make`, use ninja to build the clang-tidy binary with
-```
-ninja clang-tidy
-```
+If you already have `solutions` and `custom_vars`, just add
+`checkout_clang_tidy` to the existing `custom_vars` map.
 
-This binary will be at (build)/bin/clang-tidy.
+Once the above update has been made, run `gclient runhooks`, and clang-tidy
+should appear at `src/third_party/llvm-build/Release+Asserts/bin/clang-tidy` if
+your Chromium tree is sufficiently up-to-date.
 
-If you intend to use the `fix` feature of clang-tidy, you'll also need to build
-the `clang-apply-replacements` binary.
-```
-ninja clang-apply-replacements
-```
+### Running clang-tidy locally
 
-## Running clang-tidy
+**Note** that the local flows with clang-tidy are experimental, and require an
+LLVM checkout. Tricium is happy to run on WIP CLs, and we strongly encourage its
+use.
+
+That said, assuming you have the LLVM sources available, you'll need to bring
+your own `clang-apply-replacements` binary if you want to use the `-fix` option
+noted below.
 
 Running clang-tidy is (hopefully) simple.
 1.  Build chrome normally.
 ```
 ninja -C out/Release chrome
 ```
-2.  Generate the compilation database
-```
-tools/clang/scripts/generate_compdb.py -p out/Release > out/Release/compile_commands.json
-```
-3.  Enter the build directory.
+2.  Enter the build directory
 ```
 cd out/Release
 ```
+3.  Export Chrome's compile command database
+```
+gn gen . --export-compile-commands
+```
 4.  Run clang-tidy.
 ```
-<PATH_TO_LLVM_SRC>/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py \
+<PATH_TO_LLVM_SRC>/clang-tidy/tool/run-clang-tidy.py \
     -p . \# Set the root project directory, where compile_commands.json is.
     # Set the clang-tidy binary path, if it's not in your $PATH.
     -clang-tidy-binary <PATH_TO_LLVM_BUILD>/bin/clang-tidy \
@@ -102,7 +114,13 @@
 `clang-tidy`. I've had no problems building a component release build,
 both with and without goma. if you run into issues, let us know!
 
-## Questions
+### Questions
 
-Questions? Reach out to rdevlin.cronin@chromium.org or thakis@chromium.org.
+Questions about the local flow? Reach out to rdevlin.cronin@chromium.org,
+thakis@chromium.org, or gbiv@chromium.org.
+
+Questions about the Gerrit flow? Email tricium-dev@google.com or
+infra-dev+tricium@chromium.org, or file a bug against `Infra>Platform>Tricium`.
+Please CC gbiv@chromium.org on any of these.
+
 Discoveries? Update the doc!
diff --git a/docs/enterprise/add_new_policy.md b/docs/enterprise/add_new_policy.md
index 9608222..c66dc0c 100644
--- a/docs/enterprise/add_new_policy.md
+++ b/docs/enterprise/add_new_policy.md
@@ -1,20 +1,25 @@
 # Policy Settings in Chrome
 
-## Terms
+## Summary
 
--   User Policy: The most common kind. Associated with a user login.
--   Device Policy: (a.k.a. cloud policy) ChromeOS only. Configures device-wide
-    settings and affect unmanaged (i.e. some random gmail) users. Short list
-    compared to user policy. The most important device policy controls which
-    users can log into the device.
+Chrome exposes a different set of configurations to administrators. These
+configurations are called policy and they give administrators more advanced
+controls than the normal users. With different device management tools,
+administrator can deliver these polices to many users. Here is the
+[help center article](https://support.google.com/chrome/a/answer/9037717?hl=en)
+that talks about Chrome policy and its deployment.
 
-## Adding new policy settings
+## Do I need a policy
 
-This section describes the steps to add a new policy setting to Chromium, which
-administrators can then configure via Windows Group Policy, the G Suite Admin
-Console, etc. Administrator documentation about setting up Chrome management is
-[here](https://www.chromium.org/administrators) if you're looking for
-information on how to deploy policy settings to Chrome.
+Usually you need a policy when
+
+-   Launching a new feature. Create a policy so that the admin can disable or
+    enable the feature for all users.
+
+-   Deprecate an old feature. Create a policy to give enterprise users more time
+    to migrate away from the feature.
+
+## Adding a new policy
 
 1.  Think carefully about the name and the desired semantics of the new policy:
     -   Chose a name that is consistent with the existing naming scheme. Prefer
@@ -24,24 +29,31 @@
         future extensions or use cases.
     -   Negative policies (*Disable*, *Disallow*) are verboten because setting
         something to "true" to disable it confuses people.
-2.  Wire the feature you want to be controlled by policy to PrefService, so a
-    pref can be used to control your feature's behavior in the desired way.
-    -   For existing command line switches that are being turned into policy,
-        you will want to modify the `ChromeCommandLinePrefStore` in
-        [chrome/browser/prefs/chrome_command_line_pref_store.cc](https://cs.chromium.org/chromium/src/chrome/browser/prefs/chrome_command_line_pref_store.cc?sq=package:chromium&dr=CSs&g=0)
-        to set the property appropriately from the command line switch (the
-        managed policy will override this value from the command line
-        automagically when policy is set if you do it this way).
-3.  Add a policy to control the pref:
-    -   [components/policy/resources/policy_templates.json](https://cs.chromium.org/chromium/src/components/policy/resources/policy_templates.json) -
-        This file contains meta-level descriptions of all policies and is used
+2.  Declare the policy in the
+    [policy_templates.json](https://cs.chromium.org/chromium/src/components/policy/resources/policy_templates.json)
+    -   This file contains meta-level descriptions of all policies and is used
         to generated code, policy templates (ADM/ADMX for windows and the
-        application manifest for Mac), as well as documentation. When adding
-        your policy, please make sure you get the version and features flags
-        (such as dynamic_refresh and supported_on) right, since this is what
-        will later appear on
-        [http://dev.chromium.org/administrators/policy-list-3](http://dev.chromium.org/administrators/policy-list-3).
-        The textual policy description should include the following:
+        application manifest for Mac), as well as documentation.Please make sure
+        you get the version and features flags (such as dynamic_refresh and
+        supported_on) right.
+    -   Here are the most used attributes. Please note that, all attributes
+        below other than `supported_on` do not change the code behavior.
+        -   `supported_on`: It controls the platform and Chrome milestone the
+            policy supports.
+        -   `dynamic_refresh`: It tells admin if the policy value can be changed
+            and taken affected without re-launch Chrome.
+        -   `per_profile`: It tells the admin if different policy value can be
+            assigned to different profile.
+        -   `can_be_recommended`: It tells the admin if they can set the policy
+            in the recommended level and allow user override it with UI, command
+            line switch or extension.
+        -   `future`: It hides the policy from auto-generated templates and
+            documentation. It's used when your policy needs multiple milestone
+            development.
+    - The complete list of attributes and their expected values can be found in
+      the
+      [policy_templates.json](https://cs.chromium.org/chromium/src/components/policy/resources/policy_templates.json).
+    -   The textual policy description should include the following:
         -   What features of Chrome are affected.
         -   Which behavior and/or UI/UX changes the policy triggers.
         -   How the policy behaves if it's left unset or set to invalid/default
@@ -50,51 +62,58 @@
             traditionally, and we've seen requests from organizations to
             explicitly spell out the behavior for all possible values and for
             when the policy is unset.
-    -   [chrome/browser/policy/configuration_policy_handler_list_factory.cc](https://cs.chromium.org/chromium/src/chrome/browser/policy/configuration_policy_handler_list_factory.cc) -
-        for mapping the policy to the right pref.
-4.  If your feature can be controlled by GUI in `chrome://settings`, then you
-    will want `chrome://settings` to disable the GUI for the feature when the
-    policy controlling it is managed.
-    -   There is a method on PrefService::Preference to ask if it's managed.
-    -   You will also want `chrome://settings` to display the "some settings on
-        this page have been overridden by an administrator" banner. If you use
-        the pref attribute to connect your pref to the UI, this should happen
-        automagically. NB: There is work underway to replace the banner with
-        setting-level indicators. Once that's done, we'll update instructions
-        here.
-5.  Wherever possible, we would like to support dynamic policy refresh, that is,
-    the ability for an admin to change policy and Chrome to honor the change at
-    run-time without requiring a restart of the process.
-    -   This means that you should listen for preference change notifications
-        for your preference.
-    -   Don't forget to update `chrome://settings` when the preference changes.
-        Note that for standard elements like checkboxes, this works out of the
-        box when you use the `pref` attribute.
-6.  If you’re adding a device policy for Chrome OS:
-    -   Add a message for your policy in
-        components/policy/proto/chrome_device_policy.proto.
-    -   Add the end of the file, add an optional field to the message
-        ChromeDeviceSettingsProto.
-    -   Make sure you’ve updated
-        chrome/browser/chromeos/policy/device_policy_decoder_chromeos.{h,cc} so
-        the policy shows up on the chrome://policy page.
-7.  Build the `policy_templates` target to check that the ADM/ADMX, Mac app
-    manifests, and documentation are generated correctly.
-    -   The generated files are placed in `out/Debug/gen/chrome/app/policy/` (on
-        Linux, adjust for other build types/platforms).
-8.  Add an entry for the new policy in
-    `chrome/test/data/policy/policy_test_cases.json`.
-9.  By running `python tools/metrics/histograms/update_policies.py`, add an
-    entry for the new policy in `tools/metrics/histograms/enums.xml` in the
-    EnterprisePolicies enum. You need to check the result manually.
-10. Add a test that verifies that the policy is being enforced in
-    `chrome/browser/policy/<area>_policy_browsertest.cc` (see
-    https://crbug.com/1002483 about per-area test files for policy browser
-    tests). Ideally, your test would set the policy, fire up the browser, and
-    interact with the browser just as a user would do to check whether
-    the policy takes effect. This significantly helps Chrome QA which otherwise
-    has to test your new policy for each Chrome release.
-11. Manually testing your policy.
+3.  Create a preference and map the policy value to it.
+    -   All policy values need to be mapped into a prefs value before being used
+        unless the policy is needed before PrefService initialization.
+    -   To map the policy:
+        1.  Create a prefs and register the prefs in **Local State** or
+            **Profile Prefs**. Please note that, this must match the
+            `per_profile` attribute in the `policy_templates.json`. We also
+            strongly encourage developers to register the prefs with **Profile
+            Prefs** if possible, because this gives admin more flexiability of
+            policy setup.
+        2.  Most of policies can be mapped to prefs with `kSimplePolicyMap` in
+            [configuration_policy_handler_list_factory.cc](https://cs.chromium.org/chromium/src/chrome/browser/policy/configuration_policy_handler_list_factory.cc?type=cs&q=kSimplePolicyMap&g=0&l=150).
+            If the policy needs additional verification or processing, please
+            implement a `ConfigurationPolicyHandler` to do so.
+        3.  Test the mapping by adding policy to
+            [policy_test_cases.json](https://cs.chromium.org/chromium/src/chrome/test/data/policy/policy_test_cases.json?q=policy_test_case)
+4.  Disable the user setting UI when the policy is applied.
+    -   If your feature can be controlled by GUI in `chrome://settings`, the
+        associated option should be disabled when the policy controlling it is
+        managed.
+        -   `PrefService:Preference::IsManaged` reveals whether a prefs value
+            comes from policy or not.
+        -   The setting needs an
+            [indicator](https://cs.chromium.org/chromium/src/ui/webui/resources/images/business.svg)
+            to tell users that the setting is enforced by the administrator.
+5.  Support `dynamic_refresh` if possible.
+    -   We strongly encourage developers to make their policies support this
+        attribute. It means admin can change the policy value and Chrome will
+        honor the change at run-time wihtout requiring a restart of the browser.
+    -   Chrome OS does not support non-dynamic user policies.
+    -   Most of time, this requires a
+        [PrefChangeRegistrar](https://cs.chromium.org/chromium/src/components/prefs/pref_change_registrar.h)
+        to listen to the preference change notification. And update UI or
+        browser behavior right a way.
+6.  Adding a device policy for Chrome OS.
+    -   Most of policies that are used by browser can be shared by desktop and
+        Chrome OS. However, you need few additional steps for device policy on
+        Chrome OS.
+        -   Add a message for your policy in
+            `components/policy/proto/chrome_device_policy.proto`. Please note
+            that all proto fields are optional.
+        -   Update
+            `chrome/browser/chromeos/policy/device_policy_decoder_chromeos.{h,cc}`
+            for the new policy.
+7.  Test the policy.
+    -   Add a test to verify the policy. You can add a test in
+        `chrome/browser/policy/<area>_policy_browsertest.cc` or with the policy
+        implementation. For example, a network policy test can be put into
+        `chrome/browser/net`. Ideally, your test would set the policy, fire up
+        the browser, and interact with the browser just as a user would do to
+        check whether the policy takes effect.
+8.  Manually testing your policy.
     -   Windows: The simplest way to test is to write the registry keys manually
         to `Software\Policies\Chromium` (for Chromium builds) or
         `Software\Policies\Google\Chrome` (for Google Chrome branded builds). If
@@ -115,18 +134,19 @@
         If you'd just like to do a quick test for Chrome OS, the Linux code is
         also functional on CrOS, see
         [Linux Quick Start](https://www.chromium.org/administrators/linux-quick-start).
-12. If you are adding a new policy that supersedes an older one, verify that the
+9.  If you are adding a new policy that supersedes an older one, verify that the
     new policy works as expected even if the old policy is set (allowing us to
     set both during the transition time when Chrome versions honoring the old
     and the new policies coexist).
-13. If your policy has interactions with other policies, make sure to document,
+10. If your policy has interactions with other policies, make sure to document,
     test and cover these by automated tests.
 
 ## Examples
 
-Here's a CL that has the basic infrastructure work required to add a policy for
-an already existing preference. It's a good, simple place to get started:
-[http://codereview.chromium.org/8395007](http://codereview.chromium.org/8395007).
+Here is an example based on the instruction above. It's a good, simple place to
+get started:
+[https://chromium-review.googlesource.com/c/chromium/src/+/1742209](https://chromium-review.googlesource.com/c/chromium/src/+/1742209)
+
 
 ## Modifying existing policies
 
@@ -136,9 +156,9 @@
 There are a few noteworthy pitfalls that you should be aware of when updating
 code that handles existing policy settings, in particular:
 
-- Make sure the policy meta data is up-to-date, in particular supported_on, and
+- Make sure the policy meta data is up-to-date, in particular `supported_on`, and
 the feature flags.
-- In general, don’t change policy semantics in a way that is incompatible
+- In general, don't change policy semantics in a way that is incompatible
 (as determined by user/admin-visible behavior) with previous semantics. **In
 particular, consider that existing policy deployments may affect both old and
 new browser versions, and both should behave according to the admin's
@@ -167,7 +187,8 @@
 
 To enforce the above rules concerning policy modification and ensure no
 backwards incompatible changes are introduced, there will be presubmit checks
-performed on every change to policy_templates.json.
+performed on every change to
+[policy_templates.json](https://cs.chromium.org/chromium/src/components/policy/resources/policy_templates.json).
 
 The presubmit checks perform the following verifications:
 
@@ -175,8 +196,8 @@
     change. A policy is considered un-released if **any** of the following
     conditions are true:
 
-    1.  Is the unchanged policy marked as “future: true”.
-    2.  All the supported_versions of the policy satisfy **any** of the
+    1.  Is the unchanged policy marked as `future: true`.
+    2.  All the `supported_versions` of the policy satisfy **any** of the
         following conditions
         1.  The unchanged supported major version is >= the current major
             version stored in the VERSION file at tip of tree. This covers the
@@ -185,7 +206,7 @@
         2.  The changed supported version == unchanged supported version + 1 and
             the changed supported version is equal to the version stored in the
             VERSION file at tip of tree. This check covers the case of
-            “un-releasing” a policy after a new stable branch has been cut but
+            "un-releasing" a policy after a new stable branch has been cut but
             before a new stable release has rolled out. Normally such a change
             should eventually be merged into the stable branch before the
             release.
@@ -197,27 +218,27 @@
     policy.
 
     1.  Released policies cannot be removed.
-    2.  Released policies cannot have their type changed (e.g. from bool ->
+    2.  Released policies cannot have their type changed (e.g. from bool to
         Enum).
-    3.  Released policies cannot have the “future: true” flag added to it. This
+    3.  Released policies cannot have the `future: true` flag added to it. This
         flag can only be set on a new policy.
-    4.  Released policies can only add additional supported_on versions. They
+    4.  Released policies can only add additional `supported_on` versions. They
         cannot remove or modify existing values for this field except for the
         special case above for determining if a policy is released. Policy
-        support end version (adding “-xx”) can however be added to the
+        support end version (adding "-xx" ) can however be added to the
         supported_on version to specify that a policy will no longer be
-        supported going forward (as long as the initial supported_on version is
-        not changed).
+        supported going forward (as long as the initial `supported_on` version
+        is not changed).
     5.  Released policies cannot be renamed (this is the equivalent of a
-        delete + add). 1
-    6.  Released policies cannot change their device_only flag. This flag can
+        delete + add).
+    6.  Released policies cannot change their `device_only` flag. This flag can
         only be set on a new policy.
     7.  Released policies with non dict types cannot have their schema changed.
         1.  For enum types this means values cannot be renamed or removed (these
             should be marked as deprecated instead).
         2.  For int types, we will allow making the minimum and maximum values
             less restrictive than the existing values.
-        3.  For string types, we will allow the removal of the ‘pattern’
+        3.  For string types, we will allow the removal of the "pattern"
             property to allow the validation to be less restrictive.
         4.  We will allow addition to any list type values only at the end of
             the list of values and not in the middle or at the beginning (this
@@ -226,43 +247,28 @@
             schema definitions listed in a dictionary type policy.
     8.  Released dict policies cannot remove and modify any existing key in
         their schema. They can only add new keys to the schema.
-        1.  Dictionary policies can have some of their ‘required’ fields removed
+        1.  Dictionary policies can have some of their "required" fields removed
             in order to be less restrictive.
 
-## Updating Policy List in this Wiki
+## Post policy update
 
-Steps for updating the policy list on
-[http://dev.chromium.org/administrators/policy-list-3](http://dev.chromium.org/administrators/policy-list-3):
+Once the policy is added or modified, there is nothing else needs to be taken
+care of by the Chromium developers. However, there are few things will be
+updated based on the json file. Please note that, there is to ETA for
+everything listed below.
 
-1.  Use a recent checkout to build the GN target `policy_templates` with
-    `is_official_build=true` and `is_chrome_branded=true`.
-2.  Edit page
-    [http://dev.chromium.org/administrators/policy-list-3](http://dev.chromium.org/administrators/policy-list-3)
-    and select "Edit HTML", therein delete everything except "Last updated for
-    Chrome XX." and set XX to the latest version that has been officially
-    released.
-3.  Open
-    `<outdir>/gen/chrome/app/policy/common/html/en-US/chrome_policy_list.html`
-    in a text editor.
-4.  Cut&paste everything from the text editor into the wiki.
-5.  Add some <p>...</p> to format the paragraphs at the head of the page.
+* [Policy templates](https://dl.google.com/dl/edgedl/chrome/policy/policy_templates.zip)
+  will be updated automatically.
+* [Policy documentation](https://cloud.google.com/docs/chrome-enterprise/policies/)
+  will be updated automatically.
+* **For googlers only**: Cloud policy UI will be updated by the DPanel team
+  manually and the task is tracked with [go/dpanel-policy-requests](http://go/dpanel-policy-requests).
+  If you are interested in implementing the cloud policy UI by yourself, please
+  follow the instruction in
+  [go/dpanel-autosettings-guide](http://go/dpanel-autosettings-guide).
 
-## Updating ADM/ADMX/JSON templates
+------
 
-The
-[ZIP file of ADM/ADMX/JSON templates and documentation](https://dl.google.com/dl/edgedl/chrome/policy/policy_templates.zip)
-is updated upon every push of a new Chrome stable version as part of the release
-process.
+### Additional Notes
 
-## Updating YAPS
-
-Once your CL with your new policy lands, the next proto sync (currently done
-every Tuesday by hendrich@) will pick up the new policy and add it to YAPS. If
-you want to use your unpublished policies with YAPS during development, please
-refer to the "Custom update to the Policy Definitions" in
-(https://sites.google.com/a/google.com/chrome-enterprise-new/faq/using-yaps).
-
-## Updating Admin Console
-
-[See here for instructions](https://docs.google.com/document/d/1QgDTWISgOE8DVwQSSz8x5oKrI3O_qAvOmPryE5DQPcw/edit)
-on adding the policy to Admin Console (Google internal only).
+1. policy_templates.json is actually a python dictionary even the file name contains *json*.
diff --git a/docs/ui/android/mvc_testing.md b/docs/ui/android/mvc_testing.md
index 909c481a..8bdeface 100644
--- a/docs/ui/android/mvc_testing.md
+++ b/docs/ui/android/mvc_testing.md
@@ -51,7 +51,7 @@
 ### Best practices for testability for your View:
 
  * Tests for UI should be based on the [DummyUiActivity](/ui/android/javatests/src/org/chromium/ui/test/util/DummyUiActivity.java).  This activity does not have any dependencies on the Chrome browser and allows you to test your UI in isolation.  This ensures you are not competing against other Chrome tasks and can write a test that is much faster and less flaky than legacy UI instrumentation tests.
- * When adding tests for your UI component, add a [RenderTest](/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RENDER_TESTS.md) to ensure the UI is consistent from release to release unless you explicitly changed it.
+ * When adding tests for your UI component, add a [RenderTest](/ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md) to ensure the UI is consistent from release to release unless you explicitly changed it.
 
 ### Useful helpers / Links
 
diff --git a/docs/ui/android/night_mode.md b/docs/ui/android/night_mode.md
index 14b564f..c87b8b82 100644
--- a/docs/ui/android/night_mode.md
+++ b/docs/ui/android/night_mode.md
@@ -110,7 +110,7 @@
 
 ## Test new features in night mode
 ### Automatic Testing
-Render tests are the recommended way to verify the appearance of night mode UI. If you are not familiar with render tests, please take a look at [render test instructions](https://github.com/endlessm/chromium-browser/blob/master/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RENDER_TESTS.md) to learn about how to write a new render test and upload golden images.
+Render tests are the recommended way to verify the appearance of night mode UI. If you are not familiar with render tests, please take a look at [render test instructions](/ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md) to learn about how to write a new render test and upload golden images.
 
 **For tests using DummyUiActivity:**
 
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc
index b223bb1..c391872 100644
--- a/extensions/browser/api/messaging/message_service.cc
+++ b/extensions/browser/api/messaging/message_service.cc
@@ -265,10 +265,12 @@
         is_externally_connectable =
             externally_connectable->IdCanConnect(*source_endpoint.extension_id);
       } else {
+        DCHECK(source_render_frame_host);
+
         // Check that the web page URL matches.
         is_web_connection = true;
-        is_externally_connectable =
-            externally_connectable->matches.MatchesURL(source_url);
+        is_externally_connectable = externally_connectable->matches.MatchesURL(
+            source_render_frame_host->GetLastCommittedURL());
       }
     } else {
       // Default behaviour. Any extension or content script, no webpages.
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index cfe6469..5f57a23 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -115,6 +115,7 @@
 const char kMimeHandlerPrivateTestExtensionId[] =
     "oickdpebdnfbgkcaoklfcdhjniefkcji";
 const char kCameraAppId[] = "hfhhnacclhffhdffklopdkcgdhifgngh";
+const char kCameraAppDevId[] = "flgnmkgjffmkephdokeeliiopbjaafpm";
 const char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf";
 const char kFilesManagerAppId[] = "hhaomjibdihmijegdhdafkllkbggdgoj";
 const char kGoogleKeepAppId[] = "hmjkmjkepdijhoojdojkdfohbdgmmhki";
diff --git a/extensions/common/constants.h b/extensions/common/constants.h
index ba486054..edbf27c 100644
--- a/extensions/common/constants.h
+++ b/extensions/common/constants.h
@@ -195,6 +195,9 @@
 // The extension id of the Camera application.
 extern const char kCameraAppId[];
 
+// The extension id of the devoloper version of Camera application.
+extern const char kCameraAppDevId[];
+
 // The extension id of the Chrome component application.
 extern const char kChromeAppId[];
 
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn
index 157fd05..99fccf5 100644
--- a/fuchsia/engine/BUILD.gn
+++ b/fuchsia/engine/BUILD.gn
@@ -222,6 +222,11 @@
     "lib/libfuchsia_egl.so",
   ]
 }
+fuchsia_package_runner("web_engine_deprecated_runner") {
+  package = ":web_engine_deprecated"
+  package_name_override = "chromium"
+  install_only = true
+}
 
 fuchsia_package("web_engine") {
   binary = ":web_engine_exe"
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn
index 6d81a289..8926892 100644
--- a/fuchsia/runners/BUILD.gn
+++ b/fuchsia/runners/BUILD.gn
@@ -10,21 +10,14 @@
 import("//testing/test.gni")
 
 declare_args() {
-  # Allow the Cast Runner to use software decoders for rendering video.
-  # TODO(crbug.com/1000858): Revisit this value once hardware playback is fixed
-  #                          (fxb/13659).
-  enable_software_video_decoders = true
-
   # Set to a non-zero value to enable remote debugging on that port in WebRunner.
   web_runner_remote_debugging_port = 0
 }
 
 buildflag_header("buildflags") {
   header = "buildflags.h"
-  flags = [
-    "ENABLE_SOFTWARE_VIDEO_DECODERS=$enable_software_video_decoders",
-    "WEB_RUNNER_REMOTE_DEBUGGING_PORT=$web_runner_remote_debugging_port",
-  ]
+  flags =
+      [ "WEB_RUNNER_REMOTE_DEBUGGING_PORT=$web_runner_remote_debugging_port" ]
   visibility = [ ":*" ]
 }
 
diff --git a/fuchsia/runners/cast/main.cc b/fuchsia/runners/cast/main.cc
index aa9eeb1..a09f14a 100644
--- a/fuchsia/runners/cast/main.cc
+++ b/fuchsia/runners/cast/main.cc
@@ -29,10 +29,8 @@
       fuchsia::web::ContextFeatureFlags::AUDIO |
       fuchsia::web::ContextFeatureFlags::VULKAN |
       fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER |
-      fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM;
-
-  if (!BUILDFLAG(ENABLE_SOFTWARE_VIDEO_DECODERS))
-    features |= fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER_ONLY;
+      fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM |
+      fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER_ONLY;
 
   fuchsia::web::CreateContextParams create_context_params =
       WebContentRunner::BuildCreateContextParams(
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
index 8613f3cc..8082085 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
@@ -136,6 +136,11 @@
     INVALID_VALUE is generated if <sourceLevel> of the source texture is not
     defined.
 
+    INVALID_OPERATION is generated on ES 3.0 if <sourceId> refers to an
+    external texture (OES_EGL_image_external), <destId> refers to a texture
+    with an integer-type internal format, and the underlying context does not
+    support OES_EGL_image_external_essl3.
+
     The command
 
         CopySubTextureCHROMIUM
@@ -175,6 +180,11 @@
     INVALID_VALUE is generated if (<xoffset> + <width>) > destWidth,
     or (<yoffset> + <height>) > destHeight.
 
+    INVALID_OPERATION is generated on ES 2.0 if <sourceId> refers to an
+    external texture (OES_EGL_image_external), <destId> refers to a texture
+    with an integer-type internal format, and the underlying context does not
+    support OES_EGL_image_external_essl3.
+
     Table 1.0 Valid internal formats for CopyTextureCHROMIUM:
 
         <internalFormat>
diff --git a/gpu/command_buffer/build_raster_cmd_buffer.py b/gpu/command_buffer/build_raster_cmd_buffer.py
index 4e18014..cfc9e54 100755
--- a/gpu/command_buffer/build_raster_cmd_buffer.py
+++ b/gpu/command_buffer/build_raster_cmd_buffer.py
@@ -131,7 +131,7 @@
       'viz::ResourceFormat::R16_EXT',
       'viz::ResourceFormat::RGBX_8888',
       'viz::ResourceFormat::BGRX_8888',
-      'viz::ResourceFormat::RGBX_1010102',
+      'viz::ResourceFormat::RGBA_1010102',
       'viz::ResourceFormat::BGRX_1010102',
       'viz::ResourceFormat::YVU_420',
       'viz::ResourceFormat::YUV_420_BIPLANAR',
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 18298a1..4acc80f 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -7040,7 +7040,7 @@
     case GL_R16_EXT:
       return capabilities.texture_norm16;
     case GL_RGB10_A2_EXT:
-      return capabilities.image_xr30 || capabilities.image_xb30;
+      return capabilities.image_xr30 || capabilities.image_ab30;
     case GL_RGB_YCBCR_P010_CHROMIUM:
       return capabilities.image_ycbcr_p010;
     case GL_RED:
diff --git a/gpu/command_buffer/common/BUILD.gn b/gpu/command_buffer/common/BUILD.gn
index 8ebd59e..21631d9 100644
--- a/gpu/command_buffer/common/BUILD.gn
+++ b/gpu/command_buffer/common/BUILD.gn
@@ -206,6 +206,8 @@
 
 component("gles2_utils") {
   sources = [
+    "gles2_cmd_copy_texture_chromium_utils.cc",
+    "gles2_cmd_copy_texture_chromium_utils.h",
     "gles2_cmd_utils.cc",
     "gles2_cmd_utils.h",
     "gles2_utils_export.h",
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index f7947cc..8e47e309 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -132,6 +132,7 @@
   bool swap_buffers_with_bounds = false;
   bool commit_overlay_planes = false;
   bool egl_image_external = false;
+  bool egl_image_external_essl3 = false;
   bool texture_format_astc = false;
   bool texture_format_atc = false;
   bool texture_format_bgra8888 = false;
@@ -155,7 +156,7 @@
   bool image_ycbcr_420v = false;
   bool image_ycbcr_420v_disabled_for_video_frames = false;
   bool image_xr30 = false;
-  bool image_xb30 = false;
+  bool image_ab30 = false;
   bool image_ycbcr_p010 = false;
   bool render_buffer_format_bgra8888 = false;
   bool occlusion_query = false;
diff --git a/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.cc b/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.cc
new file mode 100644
index 0000000..3e5cfd9
--- /dev/null
+++ b/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
+
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+
+namespace gpu {
+namespace gles2 {
+
+bool CopyTextureCHROMIUMNeedsESSL3(uint32_t dest_format) {
+  return gpu::gles2::GLES2Util::IsIntegerFormat(dest_format);
+}
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h b/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h
new file mode 100644
index 0000000..753542b
--- /dev/null
+++ b/gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_COPY_TEXTURE_CHROMIUM_UTILS_H_
+#define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_COPY_TEXTURE_CHROMIUM_UTILS_H_
+
+#include <stdint.h>
+
+#include "gpu/command_buffer/common/gles2_utils_export.h"
+
+namespace gpu {
+namespace gles2 {
+
+bool GLES2_UTILS_EXPORT CopyTextureCHROMIUMNeedsESSL3(uint32_t dest_format);
+
+}  // namespace gles2
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_COPY_TEXTURE_CHROMIUM_UTILS_H_
diff --git a/gpu/command_buffer/common/gpu_memory_buffer_support.cc b/gpu/command_buffer/common/gpu_memory_buffer_support.cc
index fa6f40c..6fa7463 100644
--- a/gpu/command_buffer/common/gpu_memory_buffer_support.cc
+++ b/gpu/command_buffer/common/gpu_memory_buffer_support.cc
@@ -33,7 +33,7 @@
     case gfx::BufferFormat::BGRA_8888:
     case gfx::BufferFormat::BGRX_8888:
     case gfx::BufferFormat::BGRX_1010102:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::RGBA_F16:
       return true;
     case gfx::BufferFormat::YVU_420:
diff --git a/gpu/command_buffer/service/ahardwarebuffer_utils.cc b/gpu/command_buffer/service/ahardwarebuffer_utils.cc
index 2c061d51..1ed7d34 100644
--- a/gpu/command_buffer/service/ahardwarebuffer_utils.cc
+++ b/gpu/command_buffer/service/ahardwarebuffer_utils.cc
@@ -16,7 +16,7 @@
     case viz::RGB_565:
     case viz::RGBA_F16:
     case viz::RGBX_8888:
-    case viz::RGBX_1010102:
+    case viz::RGBA_1010102:
       return true;
     default:
       return false;
@@ -34,7 +34,7 @@
       return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
     case viz::RGBX_8888:
       return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
-    case viz::RGBX_1010102:
+    case viz::RGBA_1010102:
       return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
     default:
       NOTREACHED();
diff --git a/gpu/command_buffer/service/external_vk_image_backing.cc b/gpu/command_buffer/service/external_vk_image_backing.cc
index 2c10c80..b856a86 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -63,7 +63,7 @@
     {GL_RED, GL_UNSIGNED_SHORT, 2},                // R16_EXT
     {GL_RGBA, GL_UNSIGNED_BYTE, 4},                // RGBX_8888
     {GL_BGRA, GL_UNSIGNED_BYTE, 4},                // BGRX_8888
-    {GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4},  // RGBX_1010102
+    {GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4},  // RGBA_1010102
     {GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 4},  // BGRX_1010102
     {GL_ZERO, GL_ZERO, 0},                         // YVU_420
     {GL_ZERO, GL_ZERO, 0},                         // YUV_420_BIPLANAR
@@ -434,13 +434,13 @@
     const GrVkYcbcrConversionInfo& ycbcr_info,
     base::Optional<WGPUTextureFormat> wgpu_format,
     base::Optional<uint32_t> memory_type_index)
-    : SharedImageBacking(mailbox,
-                         format,
-                         size,
-                         color_space,
-                         usage,
-                         memory_size,
-                         false /* is_thread_safe */),
+    : ClearTrackingSharedImageBacking(mailbox,
+                                      format,
+                                      size,
+                                      color_space,
+                                      usage,
+                                      memory_size,
+                                      false /* is_thread_safe */),
       context_state_(context_state),
       backend_texture_(size.width(),
                        size.height(),
@@ -455,7 +455,35 @@
       memory_type_index_(memory_type_index) {}
 
 ExternalVkImageBacking::~ExternalVkImageBacking() {
-  DCHECK(!backend_texture_.isValid());
+  GrVkImageInfo image_info;
+  bool result = backend_texture_.getVkImageInfo(&image_info);
+  DCHECK(result);
+
+  auto* fence_helper = context_state()
+                           ->vk_context_provider()
+                           ->GetDeviceQueue()
+                           ->GetFenceHelper();
+  fence_helper->EnqueueImageCleanupForSubmittedWork(image_info.fImage,
+                                                    image_info.fAlloc.fMemory);
+  backend_texture_ = GrBackendTexture();
+
+  if (texture_) {
+    // Ensure that a context is current before removing the ref and calling
+    // glDeleteTextures.
+    if (!gl::GLContext::GetCurrent())
+      context_state()->MakeCurrent(nullptr, true /* need_gl */);
+    texture_->RemoveLightweightRef(have_context());
+  }
+
+  if (texture_passthrough_) {
+    // Ensure that a context is current before releasing |texture_passthrough_|,
+    // it calls glDeleteTextures.
+    if (!gl::GLContext::GetCurrent())
+      context_state()->MakeCurrent(nullptr, true /* need_gl */);
+    if (!have_context())
+      texture_passthrough_->MarkContextLost();
+    texture_passthrough_ = nullptr;
+  }
 }
 
 bool ExternalVkImageBacking::BeginAccess(
@@ -581,52 +609,12 @@
   }
 }
 
-bool ExternalVkImageBacking::IsCleared() const {
-  return is_cleared_;
-}
-
-void ExternalVkImageBacking::SetCleared() {
-  is_cleared_ = true;
-}
-
 void ExternalVkImageBacking::Update(std::unique_ptr<gfx::GpuFence> in_fence) {
   DCHECK(!in_fence);
   latest_content_ = kInSharedMemory;
   SetCleared();
 }
 
-void ExternalVkImageBacking::Destroy() {
-  GrVkImageInfo image_info;
-  bool result = backend_texture_.getVkImageInfo(&image_info);
-  DCHECK(result);
-
-  auto* fence_helper = context_state()
-                           ->vk_context_provider()
-                           ->GetDeviceQueue()
-                           ->GetFenceHelper();
-  fence_helper->EnqueueImageCleanupForSubmittedWork(image_info.fImage,
-                                                    image_info.fAlloc.fMemory);
-  backend_texture_ = GrBackendTexture();
-
-  if (texture_) {
-    // Ensure that a context is current before removing the ref and calling
-    // glDeleteTextures.
-    if (!gl::GLContext::GetCurrent())
-      context_state()->MakeCurrent(nullptr, true /* need_gl */);
-    texture_->RemoveLightweightRef(have_context());
-  }
-
-  if (texture_passthrough_) {
-    // Ensure that a context is current before releasing |texture_passthrough_|,
-    // it calls glDeleteTextures.
-    if (!gl::GLContext::GetCurrent())
-      context_state()->MakeCurrent(nullptr, true /* need_gl */);
-    if (!have_context())
-      texture_passthrough_->MarkContextLost();
-    texture_passthrough_ = nullptr;
-  }
-}
-
 bool ExternalVkImageBacking::ProduceLegacyMailbox(
     MailboxManager* mailbox_manager) {
   // It is not safe to produce a legacy mailbox because it would bypass the
@@ -751,7 +739,7 @@
     texture_->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE;
     // If the backing is already cleared, no need to clear it again.
     gfx::Rect cleared_rect;
-    if (is_cleared_)
+    if (IsCleared())
       cleared_rect = gfx::Rect(size());
 
     texture_->SetLevelInfo(GL_TEXTURE_2D, 0, internal_format, size().width(),
diff --git a/gpu/command_buffer/service/external_vk_image_backing.h b/gpu/command_buffer/service/external_vk_image_backing.h
index 6bab839..ca0a687 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.h
+++ b/gpu/command_buffer/service/external_vk_image_backing.h
@@ -24,7 +24,7 @@
 
 class VulkanCommandPool;
 
-class ExternalVkImageBacking final : public SharedImageBacking {
+class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
  public:
   static std::unique_ptr<ExternalVkImageBacking> Create(
       SharedContextState* context_state,
@@ -91,10 +91,7 @@
   void EndAccess(bool readonly, SemaphoreHandle semaphore_handle, bool is_gl);
 
   // SharedImageBacking implementation.
-  bool IsCleared() const override;
-  void SetCleared() override;
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
-  void Destroy() override;
   bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override;
 
  protected:
@@ -161,7 +158,6 @@
 
   SemaphoreHandle write_semaphore_handle_;
   std::vector<SemaphoreHandle> read_semaphore_handles_;
-  bool is_cleared_ = false;
 
   bool is_write_in_progress_ = false;
   uint32_t reads_in_progress_ = 0;
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 4381c016..1219afcd4 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -1032,6 +1032,15 @@
   if (gfx::HasExtension(extensions, "GL_OES_EGL_image_external")) {
     AddExtensionString("GL_OES_EGL_image_external");
     feature_flags_.oes_egl_image_external = true;
+
+    // In many places we check oes_egl_image_external to know whether
+    // TEXTURE_EXTERNAL_OES is valid. Drivers with the _essl3 version *should*
+    // have both. But to be safe, only enable the _essl3 version if the
+    // non-_essl3 version is available.
+    if (gfx::HasExtension(extensions, "GL_OES_EGL_image_external_essl3")) {
+      AddExtensionString("GL_OES_EGL_image_external_essl3");
+      feature_flags_.oes_egl_image_external_essl3 = true;
+    }
   }
   if (gfx::HasExtension(extensions, "GL_NV_EGL_stream_consumer_external")) {
     AddExtensionString("GL_NV_EGL_stream_consumer_external");
@@ -1131,13 +1140,13 @@
   // TODO(mcasas): connect in Windows, https://crbug.com/803451
   // XB30 support was introduced in GLES 3.0/ OpenGL 3.3, before that it was
   // signalled via a specific extension.
-  feature_flags_.chromium_image_xb30 =
+  feature_flags_.chromium_image_ab30 =
       gl_version_info_->IsAtLeastGL(3, 3) ||
       gl_version_info_->IsAtLeastGLES(3, 0) ||
       gfx::HasExtension(extensions, "GL_EXT_texture_type_2_10_10_10_REV");
 #endif
   if (feature_flags_.chromium_image_xr30 ||
-      feature_flags_.chromium_image_xb30) {
+      feature_flags_.chromium_image_ab30) {
     validators_.texture_internal_format.AddValue(GL_RGB10_A2_EXT);
     validators_.render_buffer_format.AddValue(GL_RGB10_A2_EXT);
     validators_.texture_internal_format_storage.AddValue(GL_RGB10_A2_EXT);
@@ -1147,9 +1156,9 @@
     feature_flags_.gpu_memory_buffer_formats.Add(
         gfx::BufferFormat::BGRX_1010102);
   }
-  if (feature_flags_.chromium_image_xb30) {
+  if (feature_flags_.chromium_image_ab30) {
     feature_flags_.gpu_memory_buffer_formats.Add(
-        gfx::BufferFormat::RGBX_1010102);
+        gfx::BufferFormat::RGBA_1010102);
   }
 
   if (feature_flags_.chromium_image_ycbcr_p010) {
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 2ca859e9..96ca1dd 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -53,6 +53,7 @@
     bool use_chromium_screen_space_antialiasing_via_shaders = false;
     bool oes_standard_derivatives = false;
     bool oes_egl_image_external = false;
+    bool oes_egl_image_external_essl3 = false;
     bool nv_egl_stream_consumer_external = false;
     bool oes_depth24 = false;
     bool oes_compressed_etc1_rgb8_texture = false;
@@ -102,7 +103,7 @@
     bool chromium_image_ycbcr_420v = false;
     bool chromium_image_ycbcr_422 = false;
     bool chromium_image_xr30 = false;
-    bool chromium_image_xb30 = false;
+    bool chromium_image_ab30 = false;
     bool chromium_image_ycbcr_p010 = false;
     bool emulate_primitive_restart_fixed_index = false;
     bool ext_render_buffer_format_bgra8888 = false;
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 4c459e41..c28a4c2 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <unordered_map>
 
+#include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
 #include "gpu/command_buffer/service/context_state.h"
 #include "gpu/command_buffer/service/decoder_context.h"
 #include "gpu/command_buffer/service/gl_utils.h"
@@ -83,36 +84,34 @@
   NUM_D_FORMAT
 };
 
+enum {
+  GLSL_ESSL100_OR_COMPATIBILITY_PROFILE,
+  GLSL_ESSL300,
+  GLSL_CORE_PROFILE,
+  NUM_GLSL
+};
+
 const unsigned kAlphaSize = 4;
 const unsigned kDitherSize = 2;
-const unsigned kNumVertexShaders = NUM_SAMPLERS;
-const unsigned kNumFragmentShaders =
-    kAlphaSize * kDitherSize * NUM_SAMPLERS * NUM_S_FORMAT * NUM_D_FORMAT;
+const unsigned kNumVertexShaders = NUM_GLSL;
+
+static_assert(std::numeric_limits<unsigned>::max() / NUM_GLSL / NUM_D_FORMAT /
+                      NUM_S_FORMAT / NUM_SAMPLERS / kDitherSize / kAlphaSize >
+                  0,
+              "ShaderId would overflow");
+const unsigned kNumFragmentShaders = kAlphaSize * kDitherSize * NUM_SAMPLERS *
+                                     NUM_S_FORMAT * NUM_D_FORMAT * NUM_GLSL;
 
 typedef unsigned ShaderId;
 
-ShaderId GetVertexShaderId(GLenum target) {
-  ShaderId id = 0;
-  switch (target) {
-    case GL_TEXTURE_2D:
-      id = SAMPLER_2D;
-      break;
-    case GL_TEXTURE_RECTANGLE_ARB:
-      id = SAMPLER_RECTANGLE_ARB;
-      break;
-    case GL_TEXTURE_EXTERNAL_OES:
-      id = SAMPLER_EXTERNAL_OES;
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-  return id;
+ShaderId GetVertexShaderId(unsigned glslVersion) {
+  return glslVersion;
 }
 
 // Returns the correct fragment shader id to evaluate the copy operation for
 // the premultiply alpha pixel store settings and target.
-ShaderId GetFragmentShaderId(bool premultiply_alpha,
+ShaderId GetFragmentShaderId(unsigned glslVersion,
+                             bool premultiply_alpha,
                              bool unpremultiply_alpha,
                              bool dither,
                              GLenum target,
@@ -297,11 +296,14 @@
       break;
   }
 
-  return alphaIndex + ditherIndex * kAlphaSize +
-         targetIndex * kAlphaSize * kDitherSize +
-         sourceFormatIndex * kAlphaSize * kDitherSize * NUM_SAMPLERS +
-         destFormatIndex * kAlphaSize * kDitherSize * NUM_SAMPLERS *
-             NUM_S_FORMAT;
+  ShaderId id = 0;
+  id = id * NUM_GLSL + glslVersion;
+  id = id * NUM_D_FORMAT + destFormatIndex;
+  id = id * NUM_S_FORMAT + sourceFormatIndex;
+  id = id * NUM_SAMPLERS + targetIndex;
+  id = id * kDitherSize + ditherIndex;
+  id = id * kAlphaSize + alphaIndex;
+  return id;
 }
 
 const char* kShaderPrecisionPreamble =
@@ -317,23 +319,35 @@
     "#define TexCoordPrecision\n"
     "#endif\n";
 
-std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info,
-                                  GLenum target) {
-  std::string source;
+void InsertVersionDirective(std::string* source, unsigned glslVersion) {
+  if (glslVersion == GLSL_CORE_PROFILE) {
+    *source += "#version 150\n";
+  } else if (glslVersion == GLSL_ESSL300) {
+    *source += "#version 300 es\n";
+  }
+}
 
-  if (gl_version_info.is_es || gl_version_info.IsLowerThanGL(3, 2)) {
-    if (gl_version_info.is_es3 && target != GL_TEXTURE_EXTERNAL_OES) {
-      source += "#version 300 es\n";
-      source +=
-          "#define ATTRIBUTE in\n"
-          "#define VARYING out\n";
-    } else {
-      source +=
-          "#define ATTRIBUTE attribute\n"
-          "#define VARYING varying\n";
-    }
+unsigned ChooseGLSLVersion(const gl::GLVersionInfo& gl_version_info,
+                           GLenum dest_format) {
+  bool use_essl300_features = CopyTextureCHROMIUMNeedsESSL3(dest_format);
+  if (use_essl300_features && gl_version_info.is_es) {
+    return GLSL_ESSL300;
+  } else if (gl_version_info.IsAtLeastGL(3, 2)) {
+    return GLSL_CORE_PROFILE;
   } else {
-    source += "#version 150\n";
+    return GLSL_ESSL100_OR_COMPATIBILITY_PROFILE;
+  }
+}
+
+std::string GetVertexShaderSource(unsigned glslVersion) {
+  std::string source;
+  InsertVersionDirective(&source, glslVersion);
+
+  if (glslVersion == GLSL_ESSL100_OR_COMPATIBILITY_PROFILE) {
+    source +=
+        "#define ATTRIBUTE attribute\n"
+        "#define VARYING varying\n";
+  } else {
     source +=
         "#define ATTRIBUTE in\n"
         "#define VARYING out\n";
@@ -357,7 +371,7 @@
   return source;
 }
 
-std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info,
+std::string GetFragmentShaderSource(unsigned glslVersion,
                                     bool premultiply_alpha,
                                     bool unpremultiply_alpha,
                                     bool dither,
@@ -366,21 +380,20 @@
                                     GLenum source_format,
                                     GLenum dest_format) {
   std::string source;
+  InsertVersionDirective(&source, glslVersion);
 
-  // Preamble for core and compatibility mode.
-  if (gl_version_info.is_es || gl_version_info.IsLowerThanGL(3, 2)) {
-    if (gl_version_info.is_es3 && target != GL_TEXTURE_EXTERNAL_OES) {
-      source += "#version 300 es\n";
-    }
-    if (target == GL_TEXTURE_EXTERNAL_OES) {
+  // #extension directives
+  if (target == GL_TEXTURE_EXTERNAL_OES) {
+    // If target is TEXTURE_EXTERNAL_OES, API must be ES.
+    if (glslVersion == GLSL_ESSL300) {
+      source += "#extension GL_OES_EGL_image_external_essl3 : enable\n";
+    } else {  // ESSL100
       source += "#extension GL_OES_EGL_image_external : enable\n";
-
-      if (nv_egl_stream_consumer_external) {
-        source += "#extension GL_NV_EGL_stream_consumer_external : enable\n";
-      }
     }
-  } else {
-    source += "#version 150\n";
+
+    if (nv_egl_stream_consumer_external) {
+      source += "#extension GL_NV_EGL_stream_consumer_external : enable\n";
+    }
   }
 
   // Preamble for texture precision.
@@ -390,6 +403,7 @@
   // format or unsigned normalized fixed-point format. |source_format| can only
   // be unsigned normalized fixed-point format.
   if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(dest_format)) {
+    DCHECK(glslVersion == GLSL_ESSL300 || glslVersion == GLSL_CORE_PROFILE);
     source += "#define TextureType uvec4\n";
     source += "#define ZERO 0u\n";
     source += "#define MAX_COLOR 255u\n";
@@ -401,8 +415,11 @@
     source += "#define MAX_COLOR 1.0\n";
     source += "#define ScaleValue 1.0\n";
   }
-  if (gl_version_info.is_es2 || gl_version_info.IsLowerThanGL(3, 2) ||
-      target == GL_TEXTURE_EXTERNAL_OES) {
+
+  if (glslVersion == GLSL_ESSL100_OR_COMPATIBILITY_PROFILE) {
+    source +=
+        "#define VARYING varying\n"
+        "#define FRAGCOLOR gl_FragColor\n";
     switch (target) {
       case GL_TEXTURE_2D:
       case GL_TEXTURE_EXTERNAL_OES:
@@ -415,10 +432,6 @@
         NOTREACHED();
         break;
     }
-
-    source +=
-        "#define VARYING varying\n"
-        "#define FRAGCOLOR gl_FragColor\n";
   } else {
     source +=
         "#define VARYING in\n"
@@ -1395,11 +1408,13 @@
     glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
   }
 
-  ShaderId vertex_shader_id = GetVertexShaderId(source_target);
+  unsigned glslVersion = ChooseGLSLVersion(gl_version_info, dest_format);
+
+  ShaderId vertex_shader_id = GetVertexShaderId(glslVersion);
   DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size());
   ShaderId fragment_shader_id =
-      GetFragmentShaderId(premultiply_alpha, unpremultiply_alpha, dither,
-                          source_target, source_format, dest_format);
+      GetFragmentShaderId(glslVersion, premultiply_alpha, unpremultiply_alpha,
+                          dither, source_target, source_format, dest_format);
   DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size());
 
   ProgramMapKey key(fragment_shader_id);
@@ -1410,8 +1425,7 @@
     GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id];
     if (!*vertex_shader) {
       *vertex_shader = glCreateShader(GL_VERTEX_SHADER);
-      std::string source =
-          GetVertexShaderSource(gl_version_info, source_target);
+      std::string source = GetVertexShaderSource(glslVersion);
       CompileShaderWithLog(*vertex_shader, source.c_str());
     }
     glAttachShader(info->program, *vertex_shader);
@@ -1419,7 +1433,7 @@
     if (!*fragment_shader) {
       *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
       std::string source = GetFragmentShaderSource(
-          gl_version_info, premultiply_alpha, unpremultiply_alpha, dither,
+          glslVersion, premultiply_alpha, unpremultiply_alpha, dither,
           nv_egl_stream_consumer_external_, source_target, source_format,
           dest_format);
       CompileShaderWithLog(*fragment_shader, source.c_str());
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
index c0952db..351e181a 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
 #include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/gpu_gles2_export.h"
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 199f046..f340164 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -39,6 +39,7 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "gpu/command_buffer/common/debug_marker_manager.h"
+#include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
@@ -3362,6 +3363,8 @@
 
 void BackRenderbuffer::Invalidate() {
   id_ = 0;
+  memory_tracker_.TrackMemFree(bytes_allocated_);
+  bytes_allocated_ = 0;
 }
 
 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
@@ -4232,6 +4235,8 @@
 
   caps.egl_image_external =
       feature_info_->feature_flags().oes_egl_image_external;
+  caps.egl_image_external_essl3 =
+      feature_info_->feature_flags().oes_egl_image_external_essl3;
   caps.texture_format_astc =
       feature_info_->feature_flags().ext_texture_format_astc;
   caps.texture_format_atc =
@@ -4302,7 +4307,7 @@
       group_->gpu_preferences()
           .disable_biplanar_gpu_memory_buffers_for_video_frames;
   caps.image_xr30 = feature_info_->feature_flags().chromium_image_xr30;
-  caps.image_xb30 = feature_info_->feature_flags().chromium_image_xb30;
+  caps.image_ab30 = feature_info_->feature_flags().chromium_image_ab30;
   caps.image_ycbcr_p010 =
       feature_info_->feature_flags().chromium_image_ycbcr_p010;
   caps.max_copy_texture_chromium_size =
@@ -18087,6 +18092,15 @@
     return;
   }
 
+  if (source_target == GL_TEXTURE_EXTERNAL_OES &&
+      CopyTextureCHROMIUMNeedsESSL3(internal_format) &&
+      !feature_info_->feature_flags().oes_egl_image_external_essl3) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
+                       "Copy*TextureCHROMIUM from EXTERNAL_OES to integer "
+                       "format requires OES_EGL_image_external_essl3");
+    return;
+  }
+
   if (feature_info_->feature_flags().desktop_srgb_support) {
     bool enable_framebuffer_srgb =
         GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
@@ -18350,6 +18364,15 @@
     return;
   }
 
+  if (source_target == GL_TEXTURE_EXTERNAL_OES &&
+      CopyTextureCHROMIUMNeedsESSL3(dest_internal_format) &&
+      !feature_info_->feature_flags().oes_egl_image_external_essl3) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
+                       "Copy*TextureCHROMIUM from EXTERNAL_OES to integer "
+                       "format requires OES_EGL_image_external_essl3");
+    return;
+  }
+
   if (feature_info_->feature_flags().desktop_srgb_support) {
     bool enable_framebuffer_srgb =
         GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 47f6dbf6..00211c7 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -1372,6 +1372,8 @@
 
   caps.egl_image_external =
       feature_info_->feature_flags().oes_egl_image_external;
+  caps.egl_image_external_essl3 =
+      feature_info_->feature_flags().oes_egl_image_external_essl3;
   caps.texture_format_astc =
       feature_info_->feature_flags().ext_texture_format_astc;
   caps.texture_format_atc =
@@ -1414,7 +1416,7 @@
       group_->gpu_preferences()
           .disable_biplanar_gpu_memory_buffers_for_video_frames;
   caps.image_xr30 = feature_info_->feature_flags().chromium_image_xr30;
-  caps.image_xb30 = feature_info_->feature_flags().chromium_image_xb30;
+  caps.image_ab30 = feature_info_->feature_flags().chromium_image_ab30;
   caps.image_ycbcr_p010 =
       feature_info_->feature_flags().chromium_image_ycbcr_p010;
   caps.max_copy_texture_chromium_size =
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc
index 97d5900f..bf28aeb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc
@@ -13,7 +13,8 @@
 namespace {
 static const uint32_t kNewServiceId = 431;
 
-class TestSharedImageBackingPassthrough : public SharedImageBacking {
+class TestSharedImageBackingPassthrough
+    : public ClearTrackingSharedImageBacking {
  public:
   class TestSharedImageRepresentationPassthrough
       : public SharedImageRepresentationGLTexturePassthrough {
@@ -46,21 +47,17 @@
                                     const gfx::ColorSpace& color_space,
                                     uint32_t usage,
                                     GLuint texture_id)
-      : SharedImageBacking(mailbox,
-                           format,
-                           size,
-                           color_space,
-                           usage,
-                           0 /* estimated_size */,
-                           false /* is_thread_safe */) {
+      : ClearTrackingSharedImageBacking(mailbox,
+                                        format,
+                                        size,
+                                        color_space,
+                                        usage,
+                                        0 /* estimated_size */,
+                                        false /* is_thread_safe */) {
     texture_passthrough_ =
         base::MakeRefCounted<TexturePassthrough>(texture_id, GL_TEXTURE_2D);
   }
 
-  bool IsCleared() const override { return false; }
-
-  void SetCleared() override {}
-
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
     DCHECK(!in_fence);
   }
@@ -69,8 +66,6 @@
     return false;
   }
 
-  void Destroy() override { texture_passthrough_.reset(); }
-
   void OnMemoryDump(const std::string& dump_name,
                     base::trace_event::MemoryAllocatorDump* dump,
                     base::trace_event::ProcessMemoryDump* pmd,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 76f6ab4..268c77c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "components/viz/common/resources/resource_format_utils.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
 #include "gpu/command_buffer/common/id_allocator.h"
@@ -3149,11 +3150,29 @@
                            false /* is_thread_safe */) {
     texture_ = new gles2::Texture(texture_id);
     texture_->SetLightweightRef();
+    texture_->SetTarget(GL_TEXTURE_2D, 1);
+    texture_->sampler_state_.min_filter = GL_LINEAR;
+    texture_->sampler_state_.mag_filter = GL_LINEAR;
+    texture_->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE;
+    texture_->sampler_state_.wrap_t = GL_CLAMP_TO_EDGE;
+    texture_->SetLevelInfo(
+        GL_TEXTURE_2D, 0, GLInternalFormat(format), size.width(), size.height(),
+        1, 0, GLDataFormat(format), GLDataType(format), gfx::Rect());
+    texture_->SetImmutable(true, true);
   }
 
-  bool IsCleared() const override { return false; }
+  ~TestSharedImageBacking() override {
+    texture_->RemoveLightweightRef(have_context());
+    texture_ = nullptr;
+  }
 
-  void SetCleared() override {}
+  gfx::Rect ClearedRect() const override {
+    return texture_->GetLevelClearedRect(texture_->target(), 0);
+  }
+
+  void SetClearedRect(const gfx::Rect& cleared_rect) override {
+    texture_->SetLevelClearedRect(texture_->target(), 0, cleared_rect);
+  }
 
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
     DCHECK(!in_fence);
@@ -3163,11 +3182,6 @@
     return false;
   }
 
-  void Destroy() override {
-    texture_->RemoveLightweightRef(have_context());
-    texture_ = nullptr;
-  }
-
   void OnMemoryDump(const std::string& dump_name,
                     base::trace_event::MemoryAllocatorDump* dump,
                     base::trace_event::ProcessMemoryDump* pmd,
diff --git a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
index 030b62f..aa10197 100644
--- a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
@@ -79,7 +79,7 @@
     viz::ResourceFormat::RG_88,        viz::ResourceFormat::LUMINANCE_F16,
     viz::ResourceFormat::RGBA_F16,     viz::ResourceFormat::R16_EXT,
     viz::ResourceFormat::RGBX_8888,    viz::ResourceFormat::BGRX_8888,
-    viz::ResourceFormat::RGBX_1010102, viz::ResourceFormat::BGRX_1010102,
+    viz::ResourceFormat::RGBA_1010102, viz::ResourceFormat::BGRX_1010102,
     viz::ResourceFormat::YVU_420,      viz::ResourceFormat::YUV_420_BIPLANAR,
 };
 
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 1fc503f..1cc69553 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -1811,6 +1811,21 @@
     return;
   }
 
+  gfx::Rect new_cleared_rect;
+  gfx::Rect old_cleared_rect = dest_shared_image->ClearedRect();
+  gfx::Rect dest_rect(xoffset, yoffset, width, height);
+  if (gles2::TextureManager::CombineAdjacentRects(old_cleared_rect, dest_rect,
+                                                  &new_cleared_rect)) {
+    DCHECK(old_cleared_rect.IsEmpty() ||
+           new_cleared_rect.Contains(old_cleared_rect));
+  } else {
+    // No users of RasterDecoder leverage this functionality. Clearing uncleared
+    // regions could be added here if needed.
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture",
+                       "Cannot clear non-combineable rects.");
+    return;
+  }
+
   gles2::TexturePassthrough* source_texture =
       source_shared_image->GetTexturePassthrough().get();
   gles2::TexturePassthrough* dest_texture =
@@ -1825,6 +1840,10 @@
       /*unpack_flip_y=*/false, /*unpack_premultiply_alpha=*/false,
       /*unpack_unmultiply_alpha=*/false);
   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTexture");
+
+  if (!dest_shared_image->IsCleared()) {
+    dest_shared_image->SetClearedRect(new_cleared_rect);
+  }
 }
 
 void RasterDecoderImpl::DoCopySubTextureINTERNALGL(
@@ -1931,14 +1950,11 @@
     DCHECK(old_cleared_rect.IsEmpty() ||
            new_cleared_rect.Contains(old_cleared_rect));
   } else {
-    // Otherwise clear part of texture level that is not already cleared.
-    if (!gles2::TextureManager::ClearTextureLevel(this, dest_texture,
-                                                  dest_target, dest_level)) {
-      LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTexture",
-                         "destination texture dimensions too big");
-      return;
-    }
-    new_cleared_rect = gfx::Rect(dest_size);
+    // No users of RasterDecoder leverage this functionality. Clearing uncleared
+    // regions could be added here if needed.
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture",
+                       "Cannot clear non-combineable rects.");
+    return;
   }
 
   ScopedTextureBinder binder(state(), dest_target, dest_texture->service_id(),
@@ -2105,6 +2121,20 @@
     return;
   }
 
+  gfx::Rect new_cleared_rect;
+  gfx::Rect old_cleared_rect = dest_shared_image->ClearedRect();
+  if (gles2::TextureManager::CombineAdjacentRects(old_cleared_rect, dest_rect,
+                                                  &new_cleared_rect)) {
+    DCHECK(old_cleared_rect.IsEmpty() ||
+           new_cleared_rect.Contains(old_cleared_rect));
+  } else {
+    // No users of RasterDecoder leverage this functionality. Clearing uncleared
+    // regions could be added here if needed.
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture",
+                       "Cannot clear non-combineable rects.");
+    return;
+  }
+
   // With OneCopyRasterBufferProvider, source_shared_image->BeginReadAccess()
   // will copy pixels from SHM GMB to the texture in |source_shared_image|,
   // and then use drawImageRect() to draw that texure to the target
@@ -2152,6 +2182,10 @@
       shared_context_state_->vk_context_provider(), &flush_info);
   dest_scoped_access->surface()->flush(
       SkSurface::BackendSurfaceAccess::kNoAccess, flush_info);
+
+  if (!dest_shared_image->IsCleared()) {
+    dest_shared_image->SetClearedRect(new_cleared_rect);
+  }
 }
 
 namespace {
diff --git a/gpu/command_buffer/service/raster_decoder_unittest.cc b/gpu/command_buffer/service/raster_decoder_unittest.cc
index 52844f9..16c3191 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -221,40 +221,74 @@
   gpu::Mailbox source_texture_mailbox =
       CreateFakeTexture(kNewServiceId, viz::ResourceFormat::RGBA_8888,
                         /*width=*/2, /*height=*/2,
-                        /*cleared=*/false);
+                        /*cleared=*/true);
   GLbyte mailboxes[sizeof(gpu::Mailbox) * 2];
   CopyMailboxes(mailboxes, source_texture_mailbox, client_texture_mailbox_);
 
+  SharedImageRepresentationFactory repr_factory(shared_image_manager(),
+                                                nullptr);
+  auto representation = repr_factory.ProduceGLTexture(client_texture_mailbox_);
+  EXPECT_FALSE(representation->IsCleared());
+
   // This will initialize the top half of destination.
   {
-    // Source is undefined, so first call to CopySubTexture will clear the
-    // source.
-    SetupClearTextureExpectations(kNewServiceId, kServiceTextureId,
-                                  GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
-                                  GL_UNSIGNED_BYTE, 0, 0, 2, 2, 0);
     SetScopedTextureBinderExpectations(GL_TEXTURE_2D);
     auto& cmd = *GetImmediateAs<cmds::CopySubTextureINTERNALImmediate>();
     cmd.Init(0, 0, 0, 0, 2, 1, mailboxes);
     EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(mailboxes)));
   }
+  EXPECT_EQ(gfx::Rect(0, 0, 2, 1), representation->ClearedRect());
+  EXPECT_FALSE(representation->IsCleared());
 
-  // This will initialize bottom right corner of the destination.
-  // CopySubTexture will clear the bottom half of the destination because a
-  // single rectangle is insufficient to keep track of the initialized area.
+  // This will initialize bottom half of the destination.
   {
-    SetupClearTextureExpectations(kServiceTextureId, kServiceTextureId,
-                                  GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
-                                  GL_UNSIGNED_BYTE, 0, 1, 2, 1, 0);
     SetScopedTextureBinderExpectations(GL_TEXTURE_2D);
     auto& cmd = *GetImmediateAs<cmds::CopySubTextureINTERNALImmediate>();
-    cmd.Init(1, 1, 0, 0, 1, 1, mailboxes);
+    cmd.Init(0, 1, 0, 0, 2, 1, mailboxes);
     EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(mailboxes)));
   }
+  EXPECT_TRUE(representation->IsCleared());
+}
+
+// Unlike the GLES2 version, RasterInterface's CopySubTexture does not allow
+// initializing a texture in parts *unless* the rectangles being cleared
+// can be trivially combined into a larger rectangle.
+TEST_P(RasterDecoderTest, CopyTexSubImage2DPartialFailsWithUnalignedRect) {
+  shared_context_state_->set_need_context_state_reset(true);
+  // Create uninitialized source texture.
+  gpu::Mailbox source_texture_mailbox =
+      CreateFakeTexture(kNewServiceId, viz::ResourceFormat::RGBA_8888,
+                        /*width=*/2, /*height=*/2,
+                        /*cleared=*/true);
+  GLbyte mailboxes[sizeof(gpu::Mailbox) * 2];
+  CopyMailboxes(mailboxes, source_texture_mailbox, client_texture_mailbox_);
 
   SharedImageRepresentationFactory repr_factory(shared_image_manager(),
                                                 nullptr);
   auto representation = repr_factory.ProduceGLTexture(client_texture_mailbox_);
-  EXPECT_TRUE(representation->GetTexture()->SafeToRenderFrom());
+  EXPECT_FALSE(representation->IsCleared());
+
+  // This will initialize the top half of destination.
+  {
+    SetScopedTextureBinderExpectations(GL_TEXTURE_2D);
+    auto& cmd = *GetImmediateAs<cmds::CopySubTextureINTERNALImmediate>();
+    cmd.Init(0, 0, 0, 0, 2, 1, mailboxes);
+    EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(mailboxes)));
+  }
+  EXPECT_EQ(gfx::Rect(0, 0, 2, 1), representation->ClearedRect());
+  EXPECT_FALSE(representation->IsCleared());
+
+  // This will attempt to initialize the bottom corner of the destination.  As
+  // the new rect cannot be trivially combined with the previous cleared rect,
+  // this will fail.
+  {
+    auto& cmd = *GetImmediateAs<cmds::CopySubTextureINTERNALImmediate>();
+    cmd.Init(1, 1, 0, 0, 1, 1, mailboxes);
+    EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(mailboxes)));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+  EXPECT_EQ(gfx::Rect(0, 0, 2, 1), representation->ClearedRect());
+  EXPECT_FALSE(representation->IsCleared());
 }
 
 TEST_P(RasterDecoderManualInitTest, CopyTexSubImage2DValidateColorFormat) {
diff --git a/gpu/command_buffer/service/shared_image_backing.cc b/gpu/command_buffer/service/shared_image_backing.cc
index bddce86..6492c0cc 100644
--- a/gpu/command_buffer/service/shared_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image_backing.cc
@@ -7,6 +7,7 @@
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/shared_context_state.h"
 #include "gpu/command_buffer/service/shared_image_representation.h"
+#include "gpu/command_buffer/service/texture_manager.h"
 
 namespace gpu {
 
@@ -109,9 +110,6 @@
     refs_[0]->tracker()->TrackMemAlloc(estimated_size_);
     return;
   }
-
-  // Last ref deleted, clean up.
-  Destroy();
 }
 
 bool SharedImageBacking::HasAnyRefs() const {
@@ -162,4 +160,42 @@
   return &shared_image_backing->lock_.value();
 }
 
+ClearTrackingSharedImageBacking::ClearTrackingSharedImageBacking(
+    const Mailbox& mailbox,
+    viz::ResourceFormat format,
+    const gfx::Size& size,
+    const gfx::ColorSpace& color_space,
+    uint32_t usage,
+    size_t estimated_size,
+    bool is_thread_safe)
+    : SharedImageBacking(mailbox,
+                         format,
+                         size,
+                         color_space,
+                         usage,
+                         estimated_size,
+                         is_thread_safe) {}
+
+gfx::Rect ClearTrackingSharedImageBacking::ClearedRect() const {
+  AutoLock auto_lock(this);
+  return ClearedRectInternal();
+}
+
+void ClearTrackingSharedImageBacking::SetClearedRect(
+    const gfx::Rect& cleared_rect) {
+  AutoLock auto_lock(this);
+  SetClearedRectInternal(cleared_rect);
+}
+
+gfx::Rect ClearTrackingSharedImageBacking::ClearedRectInternal() const {
+  AssertLockedIfNecessary();
+  return cleared_rect_;
+}
+
+void ClearTrackingSharedImageBacking::SetClearedRectInternal(
+    const gfx::Rect& cleared_rect) {
+  AssertLockedIfNecessary();
+  cleared_rect_ = cleared_rect;
+}
+
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing.h b/gpu/command_buffer/service/shared_image_backing.h
index 9e6f95c..5ba3035 100644
--- a/gpu/command_buffer/service/shared_image_backing.h
+++ b/gpu/command_buffer/service/shared_image_backing.h
@@ -18,6 +18,7 @@
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/gpu_gles2_export.h"
 #include "ui/gfx/color_space.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace base {
@@ -76,19 +77,14 @@
   // Notify backing a write access is succeeded.
   void OnWriteSucceeded();
 
-  // Tracks whether the backing has ever been cleared, or whether it may contain
-  // uninitialized pixels.
-  virtual bool IsCleared() const = 0;
+  // Returns the initialized / cleared region of the SharedImage.
+  virtual gfx::Rect ClearedRect() const = 0;
 
-  // Marks the backing as cleared, after which point it is assumed to contain no
-  // unintiailized pixels.
-  virtual void SetCleared() = 0;
+  // Marks the provided rect as cleared.
+  virtual void SetClearedRect(const gfx::Rect& cleared_rect) = 0;
 
   virtual void Update(std::unique_ptr<gfx::GpuFence> in_fence) = 0;
 
-  // Destroys the underlying backing. Must be called before destruction.
-  virtual void Destroy() = 0;
-
   virtual bool PresentSwapChain();
 
   // Allows the backing to attach additional data to the dump or dump
@@ -106,6 +102,12 @@
   // tracking.
   virtual size_t EstimatedSizeForMemTracking() const;
 
+  // Helper to determine if the entire SharedImage is cleared.
+  bool IsCleared() const { return ClearedRect() == gfx::Rect(size()); }
+
+  // Helper function which clears the entire image.
+  void SetCleared() { SetClearedRect(gfx::Rect(size())); }
+
  protected:
   // Used by SharedImageManager.
   friend class SharedImageManager;
@@ -188,6 +190,31 @@
   std::vector<SharedImageRepresentation*> refs_;
 };
 
+// Helper implementation of SharedImageBacking which tracks a simple
+// rectangular clear region. Classes which do not need more complex
+// implementations of SetClearedRect and ClearedRect can inherit from this.
+class GPU_GLES2_EXPORT ClearTrackingSharedImageBacking
+    : public SharedImageBacking {
+ public:
+  ClearTrackingSharedImageBacking(const Mailbox& mailbox,
+                                  viz::ResourceFormat format,
+                                  const gfx::Size& size,
+                                  const gfx::ColorSpace& color_space,
+                                  uint32_t usage,
+                                  size_t estimated_size,
+                                  bool is_thread_safe);
+
+  gfx::Rect ClearedRect() const override;
+  void SetClearedRect(const gfx::Rect& cleared_rect) override;
+
+ protected:
+  gfx::Rect ClearedRectInternal() const;
+  void SetClearedRectInternal(const gfx::Rect& cleared_rect);
+
+ private:
+  gfx::Rect cleared_rect_;
+};
+
 }  // namespace gpu
 
 #endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_BACKING_H_
diff --git a/gpu/command_buffer/service/shared_image_backing_egl_image.cc b/gpu/command_buffer/service/shared_image_backing_egl_image.cc
index 76f75feb..5eeff3d 100644
--- a/gpu/command_buffer/service/shared_image_backing_egl_image.cc
+++ b/gpu/command_buffer/service/shared_image_backing_egl_image.cc
@@ -91,35 +91,17 @@
     size_t estimated_size,
     GLuint gl_format,
     GLuint gl_type)
-    : SharedImageBacking(mailbox,
-                         format,
-                         size,
-                         color_space,
-                         usage,
-                         estimated_size,
-                         true /*is_thread_safe*/),
+    : ClearTrackingSharedImageBacking(mailbox,
+                                      format,
+                                      size,
+                                      color_space,
+                                      usage,
+                                      estimated_size,
+                                      true /*is_thread_safe*/),
       gl_format_(gl_format),
       gl_type_(gl_type) {}
 
-SharedImageBackingEglImage::~SharedImageBackingEglImage() {
-  // Check to make sure the resource was explicitly destroyed using Destroy()
-  // api before this destructor is called.
-  DCHECK(!egl_image_buffer_);
-}
-
-bool SharedImageBackingEglImage::IsCleared() const {
-  AutoLock auto_lock(this);
-
-  return is_cleared_;
-}
-
-void SharedImageBackingEglImage::SetCleared() {
-  // TODO(cblume): We could avoid this lock if we instead pass a flag to clear
-  // into EndWrite() or BeginRead()
-  AutoLock auto_lock(this);
-
-  is_cleared_ = true;
-}
+SharedImageBackingEglImage::~SharedImageBackingEglImage() {}
 
 void SharedImageBackingEglImage::Update(
     std::unique_ptr<gfx::GpuFence> in_fence) {
@@ -132,15 +114,6 @@
   return false;
 }
 
-void SharedImageBackingEglImage::Destroy() {
-  // TODO(vikassoni): Move this code to its destructor and remove this method.
-  // Do this for all the SharedImageBackings since this method is no longer
-  // required.
-  DCHECK(egl_image_buffer_);
-
-  egl_image_buffer_.reset();
-}
-
 std::unique_ptr<SharedImageRepresentationGLTexture>
 SharedImageBackingEglImage::ProduceGLTexture(SharedImageManager* manager,
                                              MemoryTypeTracker* tracker) {
diff --git a/gpu/command_buffer/service/shared_image_backing_egl_image.h b/gpu/command_buffer/service/shared_image_backing_egl_image.h
index b8e4084..15301b1 100644
--- a/gpu/command_buffer/service/shared_image_backing_egl_image.h
+++ b/gpu/command_buffer/service/shared_image_backing_egl_image.h
@@ -30,7 +30,7 @@
 // this backing uses EGL Image siblings. This backing is thread safe across
 // different threads running different GL contexts not part of same shared
 // group. This is achieved by using locks and fences for proper synchronization.
-class SharedImageBackingEglImage : public SharedImageBacking {
+class SharedImageBackingEglImage : public ClearTrackingSharedImageBacking {
  public:
   SharedImageBackingEglImage(const Mailbox& mailbox,
                              viz::ResourceFormat format,
@@ -43,11 +43,8 @@
 
   ~SharedImageBackingEglImage() override;
 
-  bool IsCleared() const override;
-  void SetCleared() override;
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
   bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override;
-  void Destroy() override;
 
   bool BeginWrite();
   void EndWrite(std::unique_ptr<gl::GLFenceEGL> end_write_fence);
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
index b3aa8b6..5f5bce3c 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -120,7 +120,7 @@
 // Implementation of SharedImageBacking that holds an AHardwareBuffer. This
 // can be used to create a GL texture or a VK Image from the AHardwareBuffer
 // backing.
-class SharedImageBackingAHB : public SharedImageBacking {
+class SharedImageBackingAHB : public ClearTrackingSharedImageBacking {
  public:
   SharedImageBackingAHB(const Mailbox& mailbox,
                         viz::ResourceFormat format,
@@ -134,11 +134,10 @@
 
   ~SharedImageBackingAHB() override;
 
-  bool IsCleared() const override;
-  void SetCleared() override;
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
   bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override;
-  void Destroy() override;
+  gfx::Rect ClearedRect() const override;
+  void SetClearedRect(const gfx::Rect& cleared_rect) override;
   base::android::ScopedHardwareBufferHandle GetAhbHandle() const;
 
   bool BeginWrite(base::ScopedFD* fd_to_wait_on);
@@ -443,38 +442,50 @@
     size_t estimated_size,
     bool is_thread_safe,
     base::ScopedFD initial_upload_fd)
-    : SharedImageBacking(mailbox,
-                         format,
-                         size,
-                         color_space,
-                         usage,
-                         estimated_size,
-                         is_thread_safe),
+    : ClearTrackingSharedImageBacking(mailbox,
+                                      format,
+                                      size,
+                                      color_space,
+                                      usage,
+                                      estimated_size,
+                                      is_thread_safe),
       hardware_buffer_handle_(std::move(handle)),
       write_sync_fd_(std::move(initial_upload_fd)) {
   DCHECK(hardware_buffer_handle_.is_valid());
 }
 
 SharedImageBackingAHB::~SharedImageBackingAHB() {
-  // Check to make sure buffer is explicitly destroyed using Destroy() api
-  // before this destructor is called.
-  DCHECK(!hardware_buffer_handle_.is_valid());
+  DCHECK(hardware_buffer_handle_.is_valid());
+  if (legacy_texture_) {
+    legacy_texture_->RemoveLightweightRef(have_context());
+    legacy_texture_ = nullptr;
+  }
+  hardware_buffer_handle_.reset();
 }
 
-bool SharedImageBackingAHB::IsCleared() const {
+gfx::Rect SharedImageBackingAHB::ClearedRect() const {
   AutoLock auto_lock(this);
-
-  return is_cleared_;
+  // If a |legacy_texture_| exists, defer to that. Once created,
+  // |legacy_texture_| is never destroyed, so no need to synchronize with
+  // ClearedRectInternal.
+  if (legacy_texture_) {
+    return legacy_texture_->GetLevelClearedRect(legacy_texture_->target(), 0);
+  } else {
+    return ClearedRectInternal();
+  }
 }
 
-void SharedImageBackingAHB::SetCleared() {
-  // TODO(cblume): We could avoid this lock if we instead pass a flag to clear
-  // into EndWrite() or BeginRead()
+void SharedImageBackingAHB::SetClearedRect(const gfx::Rect& cleared_rect) {
   AutoLock auto_lock(this);
-
-  if (legacy_texture_)
-    legacy_texture_->SetLevelCleared(legacy_texture_->target(), 0, true);
-  is_cleared_ = true;
+  // If a |legacy_texture_| exists, defer to that. Once created,
+  // |legacy_texture_| is never destroyed, so no need to synchronize with
+  // ClearedRectInternal.
+  if (legacy_texture_) {
+    legacy_texture_->SetLevelClearedRect(legacy_texture_->target(), 0,
+                                         cleared_rect);
+  } else {
+    SetClearedRectInternal(cleared_rect);
+  }
 }
 
 void SharedImageBackingAHB::Update(std::unique_ptr<gfx::GpuFence> in_fence) {
@@ -491,19 +502,13 @@
   legacy_texture_ = GenGLTexture();
   if (!legacy_texture_)
     return false;
+  // Make sure our |legacy_texture_| has the right initial cleared rect.
+  legacy_texture_->SetLevelClearedRect(legacy_texture_->target(), 0,
+                                       ClearedRectInternal());
   mailbox_manager->ProduceTexture(mailbox(), legacy_texture_);
   return true;
 }
 
-void SharedImageBackingAHB::Destroy() {
-  DCHECK(hardware_buffer_handle_.is_valid());
-  if (legacy_texture_) {
-    legacy_texture_->RemoveLightweightRef(have_context());
-    legacy_texture_ = nullptr;
-  }
-  hardware_buffer_handle_.reset();
-}
-
 base::android::ScopedHardwareBufferHandle SharedImageBackingAHB::GetAhbHandle()
     const {
   AutoLock auto_lock(this);
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
index 9bfe59f..2ce7098 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
@@ -468,6 +468,63 @@
   skia_representation.reset();
 }
 
+// Test to check that setting/unsetting legacy shared image mailboxes works as
+// expected.
+TEST_F(SharedImageBackingFactoryAHBTest, LegacyClearing) {
+  if (!base::AndroidHardwareBufferCompat::IsSupportAvailable())
+    return;
+
+  GlLegacySharedImage gl_legacy_shared_image{
+      backing_factory_.get(),     true /* is_thread_safe */,
+      &mailbox_manager_,          &shared_image_manager_,
+      memory_type_tracker_.get(), shared_image_representation_factory_.get()};
+
+  TextureBase* texture_base =
+      mailbox_manager_.ConsumeTexture(gl_legacy_shared_image.mailbox());
+  auto* texture = gles2::Texture::CheckedCast(texture_base);
+  EXPECT_TRUE(texture);
+  GLenum target = texture->target();
+
+  auto skia_representation = shared_image_representation_factory_->ProduceSkia(
+      gl_legacy_shared_image.mailbox(), context_state_.get());
+  EXPECT_TRUE(skia_representation);
+
+  // Check initial state.
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(skia_representation->IsCleared());
+
+  // Un-clear the representation.
+  skia_representation->SetClearedRect(gfx::Rect());
+  EXPECT_FALSE(texture->IsLevelCleared(target, 0));
+  EXPECT_FALSE(skia_representation->IsCleared());
+
+  // Partially clear the representation.
+  gfx::Rect partial_clear_rect(0, 0, 128, 128);
+  skia_representation->SetClearedRect(partial_clear_rect);
+  EXPECT_EQ(partial_clear_rect, texture->GetLevelClearedRect(target, 0));
+  EXPECT_EQ(partial_clear_rect, skia_representation->ClearedRect());
+
+  // Fully clear the representation.
+  skia_representation->SetCleared();
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(skia_representation->IsCleared());
+
+  // Un-clear the texture.
+  texture->SetLevelClearedRect(target, 0, gfx::Rect());
+  EXPECT_FALSE(texture->IsLevelCleared(target, 0));
+  EXPECT_FALSE(skia_representation->IsCleared());
+
+  // Partially clear the texture.
+  texture->SetLevelClearedRect(target, 0, partial_clear_rect);
+  EXPECT_EQ(partial_clear_rect, texture->GetLevelClearedRect(target, 0));
+  EXPECT_EQ(partial_clear_rect, skia_representation->ClearedRect());
+
+  // Fully clear the representation.
+  texture->SetLevelCleared(target, 0, true);
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(skia_representation->IsCleared());
+}
+
 GlLegacySharedImage::GlLegacySharedImage(
     SharedImageBackingFactoryAHB* backing_factory,
     bool is_thread_safe,
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
index 04890ada..9308011d 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
@@ -217,14 +217,26 @@
   }
 
   ~SharedImageBackingD3D() override {
-    // Destroy() is safe to call even if it's already been called.
-    Destroy();
+    if (texture_) {
+      texture_->RemoveLightweightRef(have_context());
+      texture_ = nullptr;
+    } else if (texture_passthrough_) {
+      if (!have_context())
+        texture_passthrough_->MarkContextLost();
+      texture_passthrough_ = nullptr;
+    }
+    swap_chain_ = nullptr;
+    d3d11_texture_.Reset();
+    dxgi_keyed_mutex_.Reset();
+    keyed_mutex_acquire_key_ = 0;
+    keyed_mutex_acquired_ = false;
+    shared_handle_.Close();
   }
 
   // Texture is cleared on initialization.
-  bool IsCleared() const override { return true; }
+  gfx::Rect ClearedRect() const override { return gfx::Rect(size()); }
 
-  void SetCleared() override {}
+  void SetClearedRect(const gfx::Rect& cleared_rect) override {}
 
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
     DLOG(ERROR) << "SharedImageBackingD3D::Update : Trying to update "
@@ -252,23 +264,6 @@
 #endif  // BUILDFLAG(USE_DAWN)
   }
 
-  void Destroy() override {
-    if (texture_) {
-      texture_->RemoveLightweightRef(have_context());
-      texture_ = nullptr;
-    } else if (texture_passthrough_) {
-      if (!have_context())
-        texture_passthrough_->MarkContextLost();
-      texture_passthrough_ = nullptr;
-    }
-    swap_chain_ = nullptr;
-    d3d11_texture_.Reset();
-    dxgi_keyed_mutex_.Reset();
-    keyed_mutex_acquire_key_ = 0;
-    keyed_mutex_acquired_ = false;
-    shared_handle_.Close();
-  }
-
   void OnMemoryDump(const std::string& dump_name,
                     base::trace_event::MemoryAllocatorDump* dump,
                     base::trace_event::ProcessMemoryDump* pmd,
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
index e34e6fd..6518ea5 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
@@ -134,8 +134,6 @@
         color_space, usage);
     EXPECT_TRUE(backings.front_buffer);
     EXPECT_TRUE(backings.back_buffer);
-    backings.front_buffer->Destroy();
-    backings.back_buffer->Destroy();
   }
   {
     auto valid_format = viz::BGRA_8888;
@@ -144,8 +142,6 @@
         color_space, usage);
     EXPECT_TRUE(backings.front_buffer);
     EXPECT_TRUE(backings.back_buffer);
-    backings.front_buffer->Destroy();
-    backings.back_buffer->Destroy();
   }
   {
     auto valid_format = viz::RGBA_F16;
@@ -154,8 +150,6 @@
         color_space, usage);
     EXPECT_TRUE(backings.front_buffer);
     EXPECT_TRUE(backings.back_buffer);
-    backings.front_buffer->Destroy();
-    backings.back_buffer->Destroy();
   }
   {
     auto invalid_format = viz::RGBA_4444;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
index 3778e41..6196caca 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -381,16 +381,22 @@
   }
 
   ~SharedImageBackingGLTexture() override {
-    DCHECK(!texture_);
-    DCHECK(!rgb_emulation_texture_);
+    DCHECK(texture_);
+    texture_->RemoveLightweightRef(have_context());
+    texture_ = nullptr;
+
+    if (rgb_emulation_texture_) {
+      rgb_emulation_texture_->RemoveLightweightRef(have_context());
+      rgb_emulation_texture_ = nullptr;
+    }
   }
 
-  bool IsCleared() const override {
-    return texture_->IsLevelCleared(texture_->target(), 0);
+  gfx::Rect ClearedRect() const override {
+    return texture_->GetLevelClearedRect(texture_->target(), 0);
   }
 
-  void SetCleared() override {
-    texture_->SetLevelCleared(texture_->target(), 0, true);
+  void SetClearedRect(const gfx::Rect& cleared_rect) override {
+    texture_->SetLevelClearedRect(texture_->target(), 0, cleared_rect);
   }
 
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
@@ -430,17 +436,6 @@
     return true;
   }
 
-  void Destroy() override {
-    DCHECK(texture_);
-    texture_->RemoveLightweightRef(have_context());
-    texture_ = nullptr;
-
-    if (rgb_emulation_texture_) {
-      rgb_emulation_texture_->RemoveLightweightRef(have_context());
-      rgb_emulation_texture_ = nullptr;
-    }
-  }
-
   void OnMemoryDump(const std::string& dump_name,
                     base::trace_event::MemoryAllocatorDump* dump,
                     base::trace_event::ProcessMemoryDump* pmd,
@@ -576,8 +571,7 @@
       const gfx::Size& size,
       const gfx::ColorSpace& color_space,
       uint32_t usage,
-      scoped_refptr<gles2::TexturePassthrough> passthrough_texture,
-      bool is_cleared)
+      scoped_refptr<gles2::TexturePassthrough> passthrough_texture)
       : SharedImageBackingWithReadAccess(mailbox,
                                          format,
                                          size,
@@ -585,17 +579,24 @@
                                          usage,
                                          passthrough_texture->estimated_size(),
                                          false /* is_thread_safe */),
-        texture_passthrough_(std::move(passthrough_texture)),
-        is_cleared_(is_cleared) {
+        texture_passthrough_(std::move(passthrough_texture)) {
     DCHECK(texture_passthrough_);
   }
 
   ~SharedImageBackingPassthroughGLTexture() override {
-    DCHECK(!texture_passthrough_);
+    DCHECK(texture_passthrough_);
+    if (!have_context())
+      texture_passthrough_->MarkContextLost();
+    texture_passthrough_.reset();
   }
 
-  bool IsCleared() const override { return is_cleared_; }
-  void SetCleared() override { is_cleared_ = true; }
+  gfx::Rect ClearedRect() const override {
+    // This backing is used exclusively with ANGLE which handles clear tracking
+    // internally. Act as though the texture is always cleared.
+    return gfx::Rect(size());
+  }
+
+  void SetClearedRect(const gfx::Rect& cleared_rect) override {}
 
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
     GLenum target = texture_passthrough_->target();
@@ -619,13 +620,6 @@
     return true;
   }
 
-  void Destroy() override {
-    DCHECK(texture_passthrough_);
-    if (!have_context())
-      texture_passthrough_->MarkContextLost();
-    texture_passthrough_.reset();
-  }
-
   void OnMemoryDump(const std::string& dump_name,
                     base::trace_event::MemoryAllocatorDump* dump,
                     base::trace_event::ProcessMemoryDump* pmd,
@@ -670,8 +664,6 @@
  private:
   scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
   sk_sp<SkPromiseImageTexture> cached_promise_texture_;
-
-  bool is_cleared_ = false;
 };
 
 SharedImageBackingFactoryGLTexture::SharedImageBackingFactoryGLTexture(
@@ -1126,7 +1118,7 @@
 
     return std::make_unique<SharedImageBackingPassthroughGLTexture>(
         mailbox, format, size, color_space, usage,
-        std::move(passthrough_texture), is_cleared);
+        std::move(passthrough_texture));
   } else {
     gles2::Texture* texture = new gles2::Texture(service_id);
     texture->SetLightweightRef();
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm
index 69e6129..fd0e252 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm
+++ b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm
@@ -354,7 +354,7 @@
 // guarded on the context provider already successfully using Metal.
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunguarded-availability"
-class SharedImageBackingIOSurface : public SharedImageBacking {
+class SharedImageBackingIOSurface : public ClearTrackingSharedImageBacking {
  public:
   SharedImageBackingIOSurface(const Mailbox& mailbox,
                               viz::ResourceFormat format,
@@ -364,26 +364,50 @@
                               base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
                               base::Optional<WGPUTextureFormat> dawn_format,
                               size_t estimated_size)
-      : SharedImageBacking(mailbox,
-                           format,
-                           size,
-                           color_space,
-                           usage,
-                           estimated_size,
-                           false /* is_thread_safe */),
+      : ClearTrackingSharedImageBacking(mailbox,
+                                        format,
+                                        size,
+                                        color_space,
+                                        usage,
+                                        estimated_size,
+                                        false /* is_thread_safe */),
         io_surface_(std::move(io_surface)),
         dawn_format_(dawn_format) {
     DCHECK(io_surface_);
   }
-  ~SharedImageBackingIOSurface() final { DCHECK(!io_surface_); }
+  ~SharedImageBackingIOSurface() final {
+    TRACE_EVENT0("gpu", "SharedImageBackingFactoryIOSurface::Destroy");
+    DCHECK(io_surface_);
 
-  bool IsCleared() const final { return is_cleared_; }
-  void SetCleared() final {
     if (legacy_texture_) {
-      legacy_texture_->SetLevelCleared(legacy_texture_->target(), 0, true);
+      legacy_texture_->RemoveLightweightRef(have_context());
+      legacy_texture_ = nullptr;
     }
+    mtl_texture_.reset();
+    io_surface_.reset();
+  }
 
-    is_cleared_ = true;
+  gfx::Rect ClearedRect() const final {
+    // If a |legacy_texture_| exists, defer to that. Once created,
+    // |legacy_texture_| is never destroyed, so no need to synchronize with
+    // ClearedRectInternal.
+    if (legacy_texture_) {
+      return legacy_texture_->GetLevelClearedRect(legacy_texture_->target(), 0);
+    } else {
+      return ClearedRectInternal();
+    }
+  }
+
+  void SetClearedRect(const gfx::Rect& cleared_rect) final {
+    // If a |legacy_texture_| exists, defer to that. Once created,
+    // |legacy_texture_| is never destroyed, so no need to synchronize with
+    // ClearedRectInternal.
+    if (legacy_texture_) {
+      legacy_texture_->SetLevelClearedRect(legacy_texture_->target(), 0,
+                                           cleared_rect);
+    } else {
+      SetClearedRectInternal(cleared_rect);
+    }
   }
 
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) final {}
@@ -396,20 +420,13 @@
       return false;
     }
 
+    // Make sure our |legacy_texture_| has the right initial cleared rect.
+    legacy_texture_->SetLevelClearedRect(legacy_texture_->target(), 0,
+                                         ClearedRectInternal());
+
     mailbox_manager->ProduceTexture(mailbox(), legacy_texture_);
     return true;
   }
-  void Destroy() final {
-    TRACE_EVENT0("gpu", "SharedImageBackingFactoryIOSurface::Destroy");
-    DCHECK(io_surface_);
-
-    if (legacy_texture_) {
-      legacy_texture_->RemoveLightweightRef(have_context());
-      legacy_texture_ = nullptr;
-    }
-    mtl_texture_.reset();
-    io_surface_.reset();
-  }
 
  protected:
   std::unique_ptr<SharedImageRepresentationGLTexture> ProduceGLTexture(
@@ -518,10 +535,7 @@
     }
 
     // If the backing is already cleared, no need to clear it again.
-    gfx::Rect cleared_rect;
-    if (is_cleared_) {
-      cleared_rect = gfx::Rect(size());
-    }
+    gfx::Rect cleared_rect = ClearedRect();
 
     // Manually create a gles2::Texture wrapping our driver texture.
     gles2::Texture* texture = new gles2::Texture(service_id);
@@ -547,7 +561,6 @@
   base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
   base::Optional<WGPUTextureFormat> dawn_format_;
   base::scoped_nsprotocol<id<MTLTexture>> mtl_texture_;
-  bool is_cleared_ = false;
 
   // A texture for the associated legacy mailbox.
   gles2::Texture* legacy_texture_ = nullptr;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
index 5b44273..46cb3d7f 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
@@ -254,6 +254,65 @@
   EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox));
 }
 
+// Test which ensures that legacy texture clear status is kept in sync with the
+// SharedImageBacking.
+TEST_F(SharedImageBackingFactoryIOSurfaceTest, LegacyClearing) {
+  Mailbox mailbox = Mailbox::GenerateForSharedImage();
+  viz::ResourceFormat format = viz::ResourceFormat::RGBA_8888;
+  gfx::Size size(256, 256);
+  gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
+  uint32_t usage = SHARED_IMAGE_USAGE_GLES2 | SHARED_IMAGE_USAGE_DISPLAY;
+
+  // Create a backing.
+  auto backing = backing_factory_->CreateSharedImage(
+      mailbox, format, size, color_space, usage, false /* is_thread_safe */);
+  EXPECT_TRUE(backing);
+  backing->SetCleared();
+  EXPECT_TRUE(backing->IsCleared());
+
+  // Also create a legacy mailbox.
+  EXPECT_TRUE(backing->ProduceLegacyMailbox(&mailbox_manager_));
+  TextureBase* texture_base = mailbox_manager_.ConsumeTexture(mailbox);
+  auto* texture = gles2::Texture::CheckedCast(texture_base);
+  EXPECT_TRUE(texture);
+  GLenum target = texture->target();
+
+  // Check initial state.
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(backing->IsCleared());
+
+  // Un-clear the representation.
+  backing->SetClearedRect(gfx::Rect());
+  EXPECT_FALSE(texture->IsLevelCleared(target, 0));
+  EXPECT_FALSE(backing->IsCleared());
+
+  // Partially clear the representation.
+  gfx::Rect partial_clear_rect(0, 0, 128, 128);
+  backing->SetClearedRect(partial_clear_rect);
+  EXPECT_EQ(partial_clear_rect, texture->GetLevelClearedRect(target, 0));
+  EXPECT_EQ(partial_clear_rect, backing->ClearedRect());
+
+  // Fully clear the representation.
+  backing->SetCleared();
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(backing->IsCleared());
+
+  // Un-clear the texture.
+  texture->SetLevelClearedRect(target, 0, gfx::Rect());
+  EXPECT_FALSE(texture->IsLevelCleared(target, 0));
+  EXPECT_FALSE(backing->IsCleared());
+
+  // Partially clear the texture.
+  texture->SetLevelClearedRect(target, 0, partial_clear_rect);
+  EXPECT_EQ(partial_clear_rect, texture->GetLevelClearedRect(target, 0));
+  EXPECT_EQ(partial_clear_rect, backing->ClearedRect());
+
+  // Fully clear the representation.
+  texture->SetLevelCleared(target, 0, true);
+  EXPECT_TRUE(texture->IsLevelCleared(target, 0));
+  EXPECT_TRUE(backing->IsCleared());
+}
+
 #if BUILDFLAG(USE_DAWN)
 // Test to check interaction between Dawn and skia GL representations.
 TEST_F(SharedImageBackingFactoryIOSurfaceTest, Dawn_SkiaGL) {
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.cc b/gpu/command_buffer/service/shared_image_backing_ozone.cc
index 4b80afc8..37eba5e9 100644
--- a/gpu/command_buffer/service/shared_image_backing_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_ozone.cc
@@ -95,12 +95,12 @@
 
 SharedImageBackingOzone::~SharedImageBackingOzone() = default;
 
-bool SharedImageBackingOzone::IsCleared() const {
+gfx::Rect SharedImageBackingOzone::ClearedRect() const {
   NOTIMPLEMENTED_LOG_ONCE();
-  return false;
+  return gfx::Rect();
 }
 
-void SharedImageBackingOzone::SetCleared() {
+void SharedImageBackingOzone::SetClearedRect(const gfx::Rect& cleared_rect) {
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
@@ -109,8 +109,6 @@
   return;
 }
 
-void SharedImageBackingOzone::Destroy() {}
-
 bool SharedImageBackingOzone::ProduceLegacyMailbox(
     MailboxManager* mailbox_manager) {
   NOTREACHED();
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.h b/gpu/command_buffer/service/shared_image_backing_ozone.h
index 1345030..4ad9fe5e 100644
--- a/gpu/command_buffer/service/shared_image_backing_ozone.h
+++ b/gpu/command_buffer/service/shared_image_backing_ozone.h
@@ -43,10 +43,9 @@
   ~SharedImageBackingOzone() override;
 
   // gpu::SharedImageBacking:
-  bool IsCleared() const override;
-  void SetCleared() override;
+  gfx::Rect ClearedRect() const override;
+  void SetClearedRect(const gfx::Rect& cleared_rect) override;
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
-  void Destroy() override;
   bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override;
 
  protected:
diff --git a/gpu/command_buffer/service/shared_image_manager.cc b/gpu/command_buffer/service/shared_image_manager.cc
index 9a7028c3..7f81b395 100644
--- a/gpu/command_buffer/service/shared_image_manager.cc
+++ b/gpu/command_buffer/service/shared_image_manager.cc
@@ -97,7 +97,6 @@
       (*lower_bound)->mailbox() == backing->mailbox()) {
     LOG(ERROR) << "SharedImageManager::Register: Trying to register an "
                   "already registered mailbox.";
-    backing->Destroy();
     return nullptr;
   }
 
diff --git a/gpu/command_buffer/service/shared_image_manager_unittest.cc b/gpu/command_buffer/service/shared_image_manager_unittest.cc
index f1b39a2..cd10ac8 100644
--- a/gpu/command_buffer/service/shared_image_manager_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_manager_unittest.cc
@@ -57,10 +57,9 @@
                            estimated_size,
                            false /* is_thread_safe */) {}
 
-  MOCK_CONST_METHOD0(IsCleared, bool());
-  MOCK_METHOD0(SetCleared, void());
+  MOCK_CONST_METHOD0(ClearedRect, gfx::Rect());
+  MOCK_METHOD1(SetClearedRect, void(const gfx::Rect&));
   MOCK_METHOD1(Update, void(std::unique_ptr<gfx::GpuFence>));
-  MOCK_METHOD0(Destroy, void());
   MOCK_METHOD1(ProduceLegacyMailbox, bool(MailboxManager*));
 
  private:
@@ -85,7 +84,6 @@
 
   auto mock_backing = std::make_unique<StrictMock<MockSharedImageBacking>>(
       mailbox, format, size, color_space, usage, kSizeBytes);
-  auto* mock_backing_ptr = mock_backing.get();
 
   auto factory_ref = manager.Register(std::move(mock_backing), tracker.get());
   EXPECT_EQ(kSizeBytes, tracker->GetMemRepresented());
@@ -106,8 +104,6 @@
     EXPECT_EQ(0u, tracker2->GetMemRepresented());
   }
 
-  // We should get one call to destroy when we release the factory ref.
-  EXPECT_CALL(*mock_backing_ptr, Destroy());
   factory_ref.reset();
   EXPECT_EQ(0u, tracker->GetMemRepresented());
 }
@@ -125,7 +121,6 @@
 
   auto mock_backing = std::make_unique<StrictMock<MockSharedImageBacking>>(
       mailbox, format, size, color_space, usage, kSizeBytes);
-  auto* mock_backing_ptr = mock_backing.get();
 
   auto factory_ref = manager.Register(std::move(mock_backing), tracker.get());
   EXPECT_EQ(kSizeBytes, tracker->GetMemRepresented());
@@ -137,8 +132,6 @@
   factory_ref.reset();
   EXPECT_EQ(kSizeBytes, tracker->GetMemRepresented());
 
-  // We should get one call to destroy when we release the gl representation.
-  EXPECT_CALL(*mock_backing_ptr, Destroy());
   gl_representation.reset();
   EXPECT_EQ(0u, tracker->GetMemRepresented());
 }
@@ -157,7 +150,6 @@
 
   auto mock_backing = std::make_unique<StrictMock<MockSharedImageBacking>>(
       mailbox, format, size, color_space, usage, kSizeBytes);
-  auto* mock_backing_ptr = mock_backing.get();
 
   auto factory_ref = manager.Register(std::move(mock_backing), tracker.get());
   EXPECT_EQ(kSizeBytes, tracker->GetMemRepresented());
@@ -176,8 +168,6 @@
   // We can now safely destroy the original tracker.
   tracker.reset();
 
-  // We should get one call to destroy when we release the gl representation.
-  EXPECT_CALL(*mock_backing_ptr, Destroy());
   gl_representation.reset();
   EXPECT_EQ(0u, tracker2->GetMemRepresented());
 }
diff --git a/gpu/command_buffer/service/shared_image_representation.h b/gpu/command_buffer/service/shared_image_representation.h
index b738bcc..96699f1 100644
--- a/gpu/command_buffer/service/shared_image_representation.h
+++ b/gpu/command_buffer/service/shared_image_representation.h
@@ -56,6 +56,10 @@
   MemoryTypeTracker* tracker() { return tracker_; }
   bool IsCleared() const { return backing_->IsCleared(); }
   void SetCleared() { backing_->SetCleared(); }
+  gfx::Rect ClearedRect() const { return backing_->ClearedRect(); }
+  void SetClearedRect(const gfx::Rect& cleared_rect) {
+    backing_->SetClearedRect(cleared_rect);
+  }
 
   // Indicates that the underlying graphics context has been lost, and the
   // backing should be treated as destroyed.
diff --git a/gpu/command_buffer/service/shared_image_video.cc b/gpu/command_buffer/service/shared_image_video.cc
index 71357ad..8a534000 100644
--- a/gpu/command_buffer/service/shared_image_video.cc
+++ b/gpu/command_buffer/service/shared_image_video.cc
@@ -148,11 +148,14 @@
     context_state_->RemoveContextLostObserver(this);
 }
 
-bool SharedImageVideo::IsCleared() const {
-  return true;
+gfx::Rect SharedImageVideo::ClearedRect() const {
+  // SharedImageVideo objects are always created from pre-initialized textures
+  // provided by the media decoder. Always treat these as cleared (return the
+  // full rectangle).
+  return gfx::Rect(size());
 }
 
-void SharedImageVideo::SetCleared() {}
+void SharedImageVideo::SetClearedRect(const gfx::Rect& cleared_rect) {}
 
 void SharedImageVideo::Update(std::unique_ptr<gfx::GpuFence> in_fence) {
   DCHECK(!in_fence);
@@ -165,8 +168,6 @@
   return true;
 }
 
-void SharedImageVideo::Destroy() {}
-
 size_t SharedImageVideo::EstimatedSizeForMemTracking() const {
   // This backing contributes to gpu memory only if its bound to the texture and
   // not when the backing is created.
diff --git a/gpu/command_buffer/service/shared_image_video.h b/gpu/command_buffer/service/shared_image_video.h
index 58800e2..22cb260 100644
--- a/gpu/command_buffer/service/shared_image_video.h
+++ b/gpu/command_buffer/service/shared_image_video.h
@@ -42,11 +42,10 @@
   ~SharedImageVideo() override;
 
   // SharedImageBacking implementation.
-  bool IsCleared() const override;
-  void SetCleared() override;
+  gfx::Rect ClearedRect() const override;
+  void SetClearedRect(const gfx::Rect& cleared_rect) override;
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
   bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override;
-  void Destroy() override;
   size_t EstimatedSizeForMemTracking() const override;
 
   // SharedContextState::ContextLostObserver implementation.
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 7759d86..ee6306ff 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -365,7 +365,7 @@
 
   if (internal_format == GL_RGB10_A2_EXT &&
       (feature_info->feature_flags().chromium_image_xr30 ||
-       feature_info->feature_flags().chromium_image_xb30)) {
+       feature_info->feature_flags().chromium_image_ab30)) {
     return true;
   }
 
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index 546f1b5..528b8f9 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -38,9 +38,12 @@
 
 namespace {
 
-class WrappedSkImage : public SharedImageBacking {
+class WrappedSkImage : public ClearTrackingSharedImageBacking {
  public:
   ~WrappedSkImage() override {
+    promise_texture_.reset();
+    gpu::DeleteSkImage(context_state_, std::move(image_));
+
     DCHECK(context_state_->context_lost() ||
            context_state_->IsCurrent(nullptr));
     if (!context_state_->context_lost())
@@ -52,15 +55,6 @@
     return false;
   }
 
-  void Destroy() override {
-    promise_texture_.reset();
-    gpu::DeleteSkImage(context_state_, std::move(image_));
-  }
-
-  bool IsCleared() const override { return cleared_; }
-
-  void SetCleared() override { cleared_ = true; }
-
   void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {}
 
   void OnMemoryDump(const std::string& dump_name,
@@ -113,13 +107,13 @@
                  uint32_t usage,
                  size_t estimated_size,
                  SharedContextState* context_state)
-      : SharedImageBacking(mailbox,
-                           format,
-                           size,
-                           color_space,
-                           usage,
-                           estimated_size,
-                           false /* is_thread_safe */),
+      : ClearTrackingSharedImageBacking(mailbox,
+                                        format,
+                                        size,
+                                        color_space,
+                                        usage,
+                                        estimated_size,
+                                        false /* is_thread_safe */),
         context_state_(context_state) {
     DCHECK(!!context_state_);
   }
@@ -224,8 +218,6 @@
   // TODO(penghuang): manage texture directly with GrBackendTexture,
   sk_sp<SkImage> image_;
 
-  bool cleared_ = false;
-
   uint64_t tracing_id_ = 0;
 
   DISALLOW_COPY_AND_ASSIGN(WrappedSkImage);
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
index d4dd711..1ea9b14 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -127,7 +127,7 @@
     case gfx::BufferFormat::RG_88:
       return GL_RG;
     case gfx::BufferFormat::BGR_565:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return GL_RGB;
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBA_8888:
@@ -160,7 +160,7 @@
       return libyuv::FOURCC_ABGR;
     case gfx::BufferFormat::BGRA_8888:
       return libyuv::FOURCC_ARGB;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return libyuv::FOURCC_AB30;
     case gfx::BufferFormat::BGRX_1010102:
       return libyuv::FOURCC_AR30;
@@ -261,9 +261,9 @@
     return;
   }
 
-  if (buffer_format == gfx::BufferFormat::RGBX_1010102 &&
-      !gl_.GetCapabilities().image_xb30) {
-    LOG(WARNING) << "image_xb30 not supported. Skipping test.";
+  if (buffer_format == gfx::BufferFormat::RGBA_1010102 &&
+      !gl_.GetCapabilities().image_ab30) {
+    LOG(WARNING) << "image_ab30 not supported. Skipping test.";
     return;
   }
 
@@ -476,7 +476,7 @@
                       gfx::BufferFormat::BGR_565,
                       gfx::BufferFormat::RGBA_4444,
                       gfx::BufferFormat::RGBA_8888,
-                      gfx::BufferFormat::RGBX_1010102,
+                      gfx::BufferFormat::RGBA_1010102,
                       gfx::BufferFormat::BGRX_1010102,
                       gfx::BufferFormat::BGRA_8888,
                       gfx::BufferFormat::RGBA_F16,
diff --git a/gpu/command_buffer/tests/gl_unittest.cc b/gpu/command_buffer/tests/gl_unittest.cc
index 05a6f01..07bcb24 100644
--- a/gpu/command_buffer/tests/gl_unittest.cc
+++ b/gpu/command_buffer/tests/gl_unittest.cc
@@ -122,7 +122,7 @@
   EXPECT_EQ(caps.image_ycbcr_422, flags.chromium_image_ycbcr_422);
   EXPECT_EQ(caps.image_ycbcr_420v, flags.chromium_image_ycbcr_420v);
   EXPECT_EQ(caps.image_xr30, flags.chromium_image_xr30);
-  EXPECT_EQ(caps.image_xb30, flags.chromium_image_xb30);
+  EXPECT_EQ(caps.image_ab30, flags.chromium_image_ab30);
   EXPECT_EQ(caps.image_ycbcr_p010, flags.chromium_image_ycbcr_p010);
   EXPECT_EQ(caps.render_buffer_format_bgra8888,
             flags.ext_render_buffer_format_bgra8888);
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index 2b57912..ea805f3 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -66,16 +66,14 @@
     "GpuUseDisplayThreadPriority", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-// Allow GPU watchdog to keep waiting for ackowledgement if one is already
-// issued from the monitored thread.
-const base::Feature kGpuWatchdogNoTerminationAwaitingAcknowledge{
-    "GpuWatchdogNoTerminationAwaitingAcknowledge",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Gpu watchdog V2 to simplify the logic and reduce GPU hangs
 const base::Feature kGpuWatchdogV2{"GpuWatchdogV2",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Use a different set of watchdog timeouts on V1
+const base::Feature kGpuWatchdogV1NewTimeout{"GpuWatchdogV1NewTimeout",
+                                             base::FEATURE_ENABLED_BY_DEFAULT};
+
 #if defined(OS_MACOSX)
 // Enable use of Metal for OOP rasterization.
 const base::Feature kMetal{"Metal", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index 9e84005..9da970b 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -33,11 +33,10 @@
 
 GPU_EXPORT extern const base::Feature kGpuUseDisplayThreadPriority;
 
-GPU_EXPORT extern const base::Feature
-    kGpuWatchdogNoTerminationAwaitingAcknowledge;
-
 GPU_EXPORT extern const base::Feature kGpuWatchdogV2;
 
+GPU_EXPORT extern const base::Feature kGpuWatchdogV1NewTimeout;
+
 #if defined(OS_MACOSX)
 GPU_EXPORT extern const base::Feature kMetal;
 #endif
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
index 545aeb5..837bb8dd 100644
--- a/gpu/config/software_rendering_list.json
+++ b/gpu/config/software_rendering_list.json
@@ -359,14 +359,6 @@
             "value": "9.2.1"
           },
           "gl_renderer": ".*SVGA3D.*"
-        },
-        {
-          "driver_vendor": "Mesa",
-          "driver_version": {
-            "op": ">=",
-            "value": "10.1.3"
-          },
-          "gl_renderer": ".*llvmpipe.*"
         }
       ],
       "features": [
@@ -935,23 +927,6 @@
       ]
     },
     {
-      "id": 110,
-      "description": "Only enable WebGL for the Mesa Gallium llvmpipe driver",
-      "cr_bugs": [571899],
-      "os": {
-        "type": "linux"
-      },
-      "driver_vendor": "Mesa",
-      "gl_vendor": "VMware.*",
-      "gl_renderer": ".*llvmpipe.*",
-      "features": [
-        "all",
-        {"exceptions": [
-          "accelerated_webgl"
-        ]}
-      ]
-    },
-    {
       "id": 111,
       "description": "Apple Software Renderer used under VMWare experiences synchronization issues with GPU Raster",
       "cr_bugs": [607829],
diff --git a/gpu/ipc/common/gpu_command_buffer_traits_multi.h b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
index bc89051..7ec4699 100644
--- a/gpu/ipc/common/gpu_command_buffer_traits_multi.h
+++ b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
@@ -125,7 +125,7 @@
   IPC_STRUCT_TRAITS_MEMBER(image_ycbcr_420v)
   IPC_STRUCT_TRAITS_MEMBER(image_ycbcr_420v_disabled_for_video_frames)
   IPC_STRUCT_TRAITS_MEMBER(image_xr30)
-  IPC_STRUCT_TRAITS_MEMBER(image_xb30)
+  IPC_STRUCT_TRAITS_MEMBER(image_ab30)
   IPC_STRUCT_TRAITS_MEMBER(render_buffer_format_bgra8888)
   IPC_STRUCT_TRAITS_MEMBER(occlusion_query)
   IPC_STRUCT_TRAITS_MEMBER(occlusion_query_boolean)
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc
index a97204a0..f3a7b1a 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc
@@ -192,7 +192,7 @@
     case gfx::BufferFormat::BGRA_8888:
     case gfx::BufferFormat::BGRX_8888:
     case gfx::BufferFormat::BGRX_1010102:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::RGBA_F16:
       return true;
     case gfx::BufferFormat::YVU_420:
diff --git a/gpu/ipc/common/gpu_watchdog_timeout.h b/gpu/ipc/common/gpu_watchdog_timeout.h
index f67352a..258f0e8e2 100644
--- a/gpu/ipc/common/gpu_watchdog_timeout.h
+++ b/gpu/ipc/common/gpu_watchdog_timeout.h
@@ -17,9 +17,12 @@
 #if defined(CYGPROFILE_INSTRUMENTATION)
 constexpr base::TimeDelta kGpuWatchdogTimeout =
     base::TimeDelta::FromSeconds(30);
-#elif defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(OS_WIN) || defined(OS_ANDROID)
 constexpr base::TimeDelta kGpuWatchdogTimeout =
     base::TimeDelta::FromSeconds(15);
+#elif defined(OS_MACOSX)
+constexpr base::TimeDelta kGpuWatchdogTimeout =
+    base::TimeDelta::FromSeconds(17);
 #else
 constexpr base::TimeDelta kGpuWatchdogTimeout =
     base::TimeDelta::FromSeconds(10);
diff --git a/gpu/ipc/host/gpu_memory_buffer_support.cc b/gpu/ipc/host/gpu_memory_buffer_support.cc
index 9c46b54..3a0fc593 100644
--- a/gpu/ipc/host/gpu_memory_buffer_support.cc
+++ b/gpu/ipc/host/gpu_memory_buffer_support.cc
@@ -23,7 +23,7 @@
       gfx::BufferFormat::RG_88,        gfx::BufferFormat::BGR_565,
       gfx::BufferFormat::RGBA_4444,    gfx::BufferFormat::RGBX_8888,
       gfx::BufferFormat::RGBA_8888,    gfx::BufferFormat::BGRX_8888,
-      gfx::BufferFormat::BGRX_1010102, gfx::BufferFormat::RGBX_1010102,
+      gfx::BufferFormat::BGRX_1010102, gfx::BufferFormat::RGBA_1010102,
       gfx::BufferFormat::BGRA_8888,    gfx::BufferFormat::RGBA_F16,
       gfx::BufferFormat::YVU_420,      gfx::BufferFormat::YUV_420_BIPLANAR,
       gfx::BufferFormat::P010};
diff --git a/gpu/ipc/service/gpu_watchdog_thread.cc b/gpu/ipc/service/gpu_watchdog_thread.cc
index ded1eed8..675e43dc 100644
--- a/gpu/ipc/service/gpu_watchdog_thread.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -19,6 +19,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "gpu/config/gpu_crash_keys.h"
+#include "gpu/config/gpu_finch_features.h"
 #include "ui/gl/shader_tracking.h"
 
 #if defined(OS_WIN)
@@ -41,6 +42,18 @@
 const int kGpuTimeout = 10000;
 #endif
 
+// The same set of timeouts from Watchdog V2 so we can compare the results
+// between V1 and V2.
+#if defined(CYGPROFILE_INSTRUMENTATION)
+const int kNewGpuTimeout = 30000;
+#elif defined(OS_WIN) || defined(OS_ANDROID)
+const int kNewGpuTimeout = 15000;
+#elif defined(OS_MACOSX)
+const int kNewGpuTimeout = 17000;
+#else
+const int kNewGpuTimeout = 10000;
+#endif
+
 #if defined(USE_X11)
 const base::FilePath::CharType kTtyFilePath[] =
     FILE_PATH_LITERAL("/sys/class/tty/tty0/active");
@@ -50,7 +63,6 @@
 
 GpuWatchdogThreadImplV1::GpuWatchdogThreadImplV1()
     : watched_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      timeout_(base::TimeDelta::FromMilliseconds(kGpuTimeout)),
       armed_(false),
       task_observer_(this),
       use_thread_cpu_time_(true),
@@ -65,6 +77,11 @@
       host_tty_(-1)
 #endif
 {
+  if (base::FeatureList::IsEnabled(features::kGpuWatchdogV1NewTimeout))
+    timeout_ = base::TimeDelta::FromMilliseconds(kNewGpuTimeout);
+  else
+    timeout_ = base::TimeDelta::FromMilliseconds(kGpuTimeout);
+
   base::subtle::NoBarrier_Store(&awaiting_acknowledge_, false);
 
 #if defined(OS_WIN)
diff --git a/gpu/ipc/service/gpu_watchdog_thread_v2.cc b/gpu/ipc/service/gpu_watchdog_thread_v2.cc
index 790a842f..b355678 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_v2.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread_v2.cc
@@ -379,6 +379,8 @@
   DCHECK(!in_power_suspension_);
   DCHECK(!is_paused_);
 
+  base::TimeTicks on_watchdog_timeout_start = base::TimeTicks::Now();
+
   // If this metric is added too early (eg. watchdog creation time), it cannot
   // be persistent. The histogram data will be lost after crash or browser exit.
   // Delay the recording of kGpuWatchdogStart until the firs
@@ -420,7 +422,7 @@
   // An experiment for all platforms: Wait for max_wait_time_ and see if GPU
   // will response.
   GpuWatchdogTimeoutHistogram(GpuWatchdogTimeoutEvent::kTimeoutWait);
-  if (GpuRespondsAfterWaiting()) {
+  if (GpuRespondsAfterWaiting(on_watchdog_timeout_start)) {
     last_on_watchdog_timeout_timeticks_ = base::TimeTicks::Now();
     last_arm_disarm_counter_ =
         base::subtle::NoBarrier_Load(&arm_disarm_counter_);
@@ -525,14 +527,14 @@
 
 // This is an experiment on all platforms to see whether GPU will response
 // after waiting longer.
-bool GpuWatchdogThreadImplV2::GpuRespondsAfterWaiting() {
+bool GpuWatchdogThreadImplV2::GpuRespondsAfterWaiting(
+    base::TimeTicks on_watchdog_timeout_start) {
   base::TimeDelta duration;
-  base::TimeTicks start_timeticks = base::TimeTicks::Now();
 
   while (duration < max_wait_time_) {
     // Sleep for 1 seconds each time and check if the GPU makes a progress.
     base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
-    duration = base::TimeTicks::Now() - start_timeticks;
+    duration = base::TimeTicks::Now() - on_watchdog_timeout_start;
 
     if (GpuIsAlive()) {
       GpuWatchdogTimeoutHistogram(GpuWatchdogTimeoutEvent::kProgressAfterWait);
@@ -747,9 +749,9 @@
     GpuWatchdogTimeoutHistogram(
         GpuWatchdogTimeoutEvent::kContinueOnNonHostServerTty);
     return true;
-  } else
+  }
 #endif
-    return false;
+  return false;
 }
 
 // For gpu testing only. Return whether a GPU hang was detected or not.
diff --git a/gpu/ipc/service/gpu_watchdog_thread_v2.h b/gpu/ipc/service/gpu_watchdog_thread_v2.h
index 944d2af..bb13a17 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_v2.h
+++ b/gpu/ipc/service/gpu_watchdog_thread_v2.h
@@ -109,7 +109,7 @@
 #if defined(OS_WIN)
   base::ThreadTicks GetWatchedThreadTime();
 #endif
-  bool GpuRespondsAfterWaiting();
+  bool GpuRespondsAfterWaiting(base::TimeTicks on_watchdog_timeout_start);
 
   // Do not change the function name. It is used for [GPU HANG] carsh reports.
   void DeliberatelyTerminateToRecoverFromHang();
diff --git a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
index 90f087e..7d8ab3f3 100644
--- a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
+++ b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc
@@ -14,11 +14,6 @@
 HeadlessPrintRenderFrameHelperDelegate::
     ~HeadlessPrintRenderFrameHelperDelegate() = default;
 
-bool HeadlessPrintRenderFrameHelperDelegate::CancelPrerender(
-    content::RenderFrame* render_frame) {
-  return false;
-}
-
 blink::WebElement HeadlessPrintRenderFrameHelperDelegate::GetPdfElement(
     blink::WebLocalFrame* frame) {
   return blink::WebElement();
diff --git a/headless/lib/renderer/headless_print_render_frame_helper_delegate.h b/headless/lib/renderer/headless_print_render_frame_helper_delegate.h
index d3d3a2c..c5c070d 100644
--- a/headless/lib/renderer/headless_print_render_frame_helper_delegate.h
+++ b/headless/lib/renderer/headless_print_render_frame_helper_delegate.h
@@ -18,7 +18,6 @@
 
  private:
   // printing::PrintRenderFrameHelper::Delegate:
-  bool CancelPrerender(content::RenderFrame* render_frame) override;
   bool IsPrintPreviewEnabled() override;
   bool OverridePrint(blink::WebLocalFrame* frame) override;
   blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override;
diff --git a/infra/config/buckets/try.star b/infra/config/buckets/try.star
index 111d4aa..d1f24c5 100644
--- a/infra/config/buckets/try.star
+++ b/infra/config/buckets/try.star
@@ -172,6 +172,14 @@
 )
 
 android_builder(
+    name = 'android-pie-arm64-coverage-rel',
+    cores = 16,
+    goma_jobs = goma.jobs.J300,
+    ssd = True,
+    use_clang_coverage = True,
+)
+
+android_builder(
     name = 'android-pie-arm64-rel',
     cores = 16,
     goma_jobs = goma.jobs.J300,
@@ -1241,6 +1249,7 @@
 def mac_builder(
     *,
     name,
+    builderless=True,
     cores=None,
     goma_backend=goma.backend.RBE_PROD,
     os=os.MAC_ANY,
@@ -1251,13 +1260,13 @@
       goma_backend = goma_backend,
       mastername = 'tryserver.chromium.mac',
       os = os,
+      builderless = builderless,
       ssd = True,
       **kwargs
   )
 
 mac_builder(
     name = 'mac-osxbeta-rel',
-    builderless = True,
     os = os.MAC_DEFAULT,
 )
 
@@ -1266,22 +1275,18 @@
 # The 10.xx version translates to which bots will run isolated tests.
 mac_builder(
     name = 'mac_chromium_10.10',
-    builderless = True,
 )
 
 mac_builder(
     name = 'mac_chromium_10.12_rel_ng',
-    builderless = True,
 )
 
 mac_builder(
     name = 'mac_chromium_10.13_rel_ng',
-    builderless = True,
 )
 
 mac_builder(
     name = 'mac_chromium_10.14_rel_ng',
-    builderless = True,
 )
 
 mac_builder(
@@ -1295,7 +1300,6 @@
 
 mac_builder(
     name = 'mac_chromium_compile_dbg_ng',
-    builderless = True,
     goma_jobs = goma.jobs.J150,
     os = os.MAC_10_13,
     tryjob = tryjob(),
@@ -1303,16 +1307,15 @@
 
 mac_builder(
     name = 'mac_chromium_compile_rel_ng',
-    builderless = True,
 )
 
 mac_builder(
     name = 'mac_chromium_dbg_ng',
-    builderless = True,
 )
 
 mac_builder(
     name = 'mac_upload_clang',
+    builderless = False,
     caches = [
         swarming.cache(
             name = 'xcode_mac_9a235',
@@ -1348,18 +1351,10 @@
 
 mac_ios_builder(
     name = 'ios-device',
-    tryjob = tryjob(
-        # https://crbug.com/739556; make this non-experimental ASAP.
-        experiment_percentage = 10,
-    ),
 )
 
 mac_ios_builder(
     name = 'ios-device-xcode-clang',
-    tryjob = tryjob(
-        # https://crbug.com/739556
-        experiment_percentage = 10,
-    ),
 )
 
 mac_ios_builder(
@@ -1403,10 +1398,6 @@
 
 mac_ios_builder(
     name = 'ios-simulator-xcode-clang',
-    tryjob = tryjob(
-        # https://crbug.com/739556
-        experiment_percentage = 10,
-    ),
 )
 
 mac_ios_builder(
diff --git a/infra/config/consoles/luci.chromium.try.star b/infra/config/consoles/luci.chromium.try.star
index 506e77d4..246f6d9 100644
--- a/infra/config/consoles/luci.chromium.try.star
+++ b/infra/config/consoles/luci.chromium.try.star
@@ -5,6 +5,7 @@
         'try/android-kitkat-arm-rel',
         'try/android-marshmallow-arm64-rel',
         'try/android-oreo-arm64-cts-networkservice-dbg',
+        'try/android-pie-arm64-coverage-rel',
         'try/android-pie-arm64-rel',
         'try/android-webview-pie-arm64-fyi-rel',
         'try/android_archive_rel_ng',
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg
index 12c1bd49..4681ae2 100644
--- a/infra/config/generated/commit-queue.cfg
+++ b/infra/config/generated/commit-queue.cfg
@@ -78,6 +78,10 @@
         includable_only: true
       >
       builders: <
+        name: "chromium/try/android-pie-arm64-coverage-rel"
+        includable_only: true
+      >
+      builders: <
         name: "chromium/try/android-pie-arm64-dbg"
         location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+"
         location_regexp: ".+/[+]/chrome/browser/vr/.+"
@@ -579,11 +583,11 @@
       >
       builders: <
         name: "chromium/try/ios-device"
-        experiment_percentage: 10
+        includable_only: true
       >
       builders: <
         name: "chromium/try/ios-device-xcode-clang"
-        experiment_percentage: 10
+        includable_only: true
       >
       builders: <
         name: "chromium/try/ios-simulator"
@@ -613,7 +617,7 @@
       >
       builders: <
         name: "chromium/try/ios-simulator-xcode-clang"
-        experiment_percentage: 10
+        includable_only: true
       >
       builders: <
         name: "chromium/try/ios13-beta-simulator"
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md
index 6afb4d3..c1bb1ba 100644
--- a/infra/config/generated/cq-builders.md
+++ b/infra/config/generated/cq-builders.md
@@ -321,12 +321,3 @@
 * [fuchsia-compile-x64-dbg](https://ci.chromium.org/p/chromium/builders/try/fuchsia-compile-x64-dbg) ([definition](https://cs.chromium.org/search?q=package:%5Echromium$+file:/cq.star$+-file:/beta/+-file:/stable/+fuchsia-compile-x64-dbg)) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+fuchsia-compile-x64-dbg))
   * Experiment percentage: 50
 
-* [ios-device](https://ci.chromium.org/p/chromium/builders/try/ios-device) ([definition](https://cs.chromium.org/search?q=package:%5Echromium$+file:/cq.star$+-file:/beta/+-file:/stable/+ios-device)) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+ios-device))
-  * Experiment percentage: 10
-
-* [ios-device-xcode-clang](https://ci.chromium.org/p/chromium/builders/try/ios-device-xcode-clang) ([definition](https://cs.chromium.org/search?q=package:%5Echromium$+file:/cq.star$+-file:/beta/+-file:/stable/+ios-device-xcode-clang)) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+ios-device-xcode-clang))
-  * Experiment percentage: 10
-
-* [ios-simulator-xcode-clang](https://ci.chromium.org/p/chromium/builders/try/ios-simulator-xcode-clang) ([definition](https://cs.chromium.org/search?q=package:%5Echromium$+file:/cq.star$+-file:/beta/+-file:/stable/+ios-simulator-xcode-clang)) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+ios-simulator-xcode-clang))
-  * Experiment percentage: 10
-
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index f207bd5..a8dd608 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -11532,6 +11532,36 @@
       >
     >
     builders: <
+      name: "android-pie-arm64-coverage-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      swarming_tags: "vpython:native-python-wrapper"
+      dimensions: "builderless:1"
+      dimensions: "cores:16"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-16.04"
+      dimensions: "ssd:1"
+      recipe: <
+        name: "chromium_trybot"
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/master"
+        properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}"
+        properties_j: "$build/goma:{\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}"
+        properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}"
+        properties_j: "mastername:\"tryserver.chromium.android\""
+      >
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      caches: <
+        name: "win_toolchain"
+        path: "win_toolchain"
+      >
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage: <
+        value: 5
+      >
+    >
+    builders: <
       name: "android-pie-arm64-dbg"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
@@ -16839,9 +16869,10 @@
       name: "mac-rel"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
-      dimensions: "builder:mac-rel"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac"
+      dimensions: "ssd:1"
       recipe: <
         name: "chromium_trybot"
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
@@ -17147,7 +17178,7 @@
       name: "mac_chromium_archive_rel_ng"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
-      dimensions: "builder:mac_chromium_archive_rel_ng"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac"
       dimensions: "ssd:1"
@@ -17175,7 +17206,7 @@
       name: "mac_chromium_asan_rel_ng"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
-      dimensions: "builder:mac_chromium_asan_rel_ng"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac"
       dimensions: "ssd:1"
@@ -18545,10 +18576,11 @@
       name: "mac-rel"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
-      dimensions: "builder:mac-rel"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:1"
       recipe: <
         name: "chromium_trybot"
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
@@ -18859,10 +18891,11 @@
       name: "mac-rel"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
-      dimensions: "builder:mac-rel"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:1"
       recipe: <
         name: "chromium_trybot"
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg
index 71bf751..14f330b4 100644
--- a/infra/config/generated/luci-milo.cfg
+++ b/infra/config/generated/luci-milo.cfg
@@ -9679,6 +9679,9 @@
     name: "buildbucket/luci.chromium.try/android-oreo-arm64-cts-networkservice-dbg"
   >
   builders: <
+    name: "buildbucket/luci.chromium.try/android-pie-arm64-coverage-rel"
+  >
+  builders: <
     name: "buildbucket/luci.chromium.try/android-pie-arm64-rel"
   >
   builders: <
diff --git a/infra/config/versioned/milestones/m79/buckets/try.star b/infra/config/versioned/milestones/m79/buckets/try.star
index ea3c644..8631abc 100644
--- a/infra/config/versioned/milestones/m79/buckets/try.star
+++ b/infra/config/versioned/milestones/m79/buckets/try.star
@@ -218,6 +218,8 @@
       goma_backend = goma_backend,
       mastername = 'tryserver.chromium.mac',
       os = os,
+      builderless = True,
+      ssd = True,
       **kwargs
   )
 
diff --git a/infra/config/versioned/milestones/m80/buckets/try.star b/infra/config/versioned/milestones/m80/buckets/try.star
index d683f999..798b55f1 100644
--- a/infra/config/versioned/milestones/m80/buckets/try.star
+++ b/infra/config/versioned/milestones/m80/buckets/try.star
@@ -201,6 +201,8 @@
       goma_backend = goma_backend,
       mastername = 'tryserver.chromium.mac',
       os = os,
+      builderless = True,
+      ssd = True,
       **kwargs
   )
 
diff --git a/infra/config/versioned/trunk/buckets/try.star b/infra/config/versioned/trunk/buckets/try.star
index d683f999..798b55f1 100644
--- a/infra/config/versioned/trunk/buckets/try.star
+++ b/infra/config/versioned/trunk/buckets/try.star
@@ -201,6 +201,8 @@
       goma_backend = goma_backend,
       mastername = 'tryserver.chromium.mac',
       os = os,
+      builderless = True,
+      ssd = True,
       **kwargs
   )
 
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 45ba1d5..c0c0235 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -1700,9 +1700,10 @@
       UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL));
   urlLoadParams.web_params.transition_type = ui::PAGE_TRANSITION_TYPED;
 
-  [_tabSwitcher dismissWithNewTabAnimationToModel:self.mainTabModel
-                                withUrlLoadParams:urlLoadParams
-                                          atIndex:self.mainTabModel.count];
+  Browser* mainBrowser = self.interfaceProvider.mainInterface.browser;
+  [_tabSwitcher dismissWithNewTabAnimationToBrowser:mainBrowser
+                                  withUrlLoadParams:urlLoadParams
+                                            atIndex:self.mainTabModel.count];
   return YES;
 }
 
@@ -1977,9 +1978,9 @@
       self.NTPActionAfterTabSwitcherDismissal =
           [_startupParameters postOpeningAction];
       [self setStartupParameters:nil];
-      [_tabSwitcher dismissWithNewTabAnimationToModel:targetInterface.tabModel
-                                    withUrlLoadParams:urlLoadParams
-                                              atIndex:tabIndex];
+      [_tabSwitcher dismissWithNewTabAnimationToBrowser:targetInterface.browser
+                                      withUrlLoadParams:urlLoadParams
+                                                atIndex:tabIndex];
     }
   } else {
     if (!self.currentBVC.presentedViewController) {
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn
index 51b95f20..4f9bd8e 100644
--- a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn
+++ b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn
@@ -30,6 +30,8 @@
     "breadcrumb_manager_keyed_service_factory.cc",
     "breadcrumb_manager_keyed_service_factory.h",
     "breadcrumb_manager_observer.h",
+    "breadcrumb_manager_tab_helper.h",
+    "breadcrumb_manager_tab_helper.mm",
     "breadcrumb_persistent_storage_keyed_service.cc",
     "breadcrumb_persistent_storage_keyed_service.h",
     "breadcrumb_persistent_storage_keyed_service_factory.cc",
@@ -57,6 +59,7 @@
   sources = [
     "breadcrumb_manager_keyed_service_unittest.mm",
     "breadcrumb_manager_observer_unittest.mm",
+    "breadcrumb_manager_tab_helper_unittest.mm",
     "breadcrumb_persistent_storage_keyed_service_unittest.mm",
     "breadcrumb_persistent_storage_util_unittest.mm",
   ]
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h
new file mode 100644
index 0000000..b93bd644
--- /dev/null
+++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h
@@ -0,0 +1,69 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_
+#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_
+
+#include "ios/web/public/web_state_observer.h"
+#import "ios/web/public/web_state_user_data.h"
+
+namespace web {
+class WebState;
+}  // namespace web
+
+// Handles logging of Breadcrumb events associated with |web_state_| based on
+// calls from WebStateObserver.
+class BreadcrumbManagerTabHelper
+    : public web::WebStateObserver,
+      public web::WebStateUserData<BreadcrumbManagerTabHelper> {
+ public:
+  ~BreadcrumbManagerTabHelper() override;
+
+  // Returns a unique identifier to be used in breadcrumb event logs to identify
+  // events associated with the underlying WebState. This value is unique across
+  // this application run only and is NOT persisted and will change across
+  // launches.
+  int GetUniqueId() const { return unique_id_; }
+
+ private:
+  friend class web::WebStateUserData<BreadcrumbManagerTabHelper>;
+
+  explicit BreadcrumbManagerTabHelper(web::WebState* web_state);
+
+  BreadcrumbManagerTabHelper(const BreadcrumbManagerTabHelper&) = delete;
+  BreadcrumbManagerTabHelper& operator=(const BreadcrumbManagerTabHelper&) =
+      delete;
+
+  // Logs an event for the associated WebState.
+  void LogEvent(const std::string& event);
+
+  // web::WebStateObserver implementation.
+  void WasShown(web::WebState* web_state) override;
+  void WasHidden(web::WebState* web_state) override;
+  void DidStartNavigation(web::WebState* web_state,
+                          web::NavigationContext* navigation_context) override;
+  void DidFinishNavigation(web::WebState* web_state,
+                           web::NavigationContext* navigation_context) override;
+  void DidStartLoading(web::WebState* web_state) override;
+  void DidStopLoading(web::WebState* web_state) override;
+  void PageLoaded(
+      web::WebState* web_state,
+      web::PageLoadCompletionStatus load_completion_status) override;
+  void DidChangeBackForwardState(web::WebState* web_state) override;
+  void TitleWasSet(web::WebState* web_state) override;
+  void DidChangeVisibleSecurityState(web::WebState* web_state) override;
+  void FaviconUrlUpdated(
+      web::WebState* web_state,
+      const std::vector<web::FaviconURL>& candidates) override;
+  void RenderProcessGone(web::WebState* web_state) override;
+  void WebStateDestroyed(web::WebState* web_state) override;
+
+  // The webstate associated with this tab helper.
+  web::WebState* web_state_ = nullptr;
+  int unique_id_ = -1;
+
+  WEB_STATE_USER_DATA_KEY_DECL();
+};
+
+#endif  // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.mm
new file mode 100644
index 0000000..99f2749
--- /dev/null
+++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.mm
@@ -0,0 +1,104 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h"
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h"
+#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h"
+#include "ios/web/public/favicon/favicon_url.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+BreadcrumbManagerTabHelper::BreadcrumbManagerTabHelper(web::WebState* web_state)
+    : web_state_(web_state) {
+  DCHECK(web_state_);
+  web_state_->AddObserver(this);
+
+  static int next_unique_id = 1;
+  unique_id_ = next_unique_id++;
+}
+
+BreadcrumbManagerTabHelper::~BreadcrumbManagerTabHelper() = default;
+
+void BreadcrumbManagerTabHelper::LogEvent(const std::string& event) {
+  ios::ChromeBrowserState* chrome_browser_state =
+      ios::ChromeBrowserState::FromBrowserState(web_state_->GetBrowserState());
+  BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(chrome_browser_state)
+      ->AddEvent(base::StringPrintf("%d %s", unique_id_, event.c_str()));
+}
+
+void BreadcrumbManagerTabHelper::WasShown(web::WebState* web_state) {
+  LogEvent("WasShown");
+}
+
+void BreadcrumbManagerTabHelper::WasHidden(web::WebState* web_state) {
+  LogEvent("WasHidden");
+}
+
+void BreadcrumbManagerTabHelper::DidStartNavigation(
+    web::WebState* web_state,
+    web::NavigationContext* navigation_context) {
+  LogEvent("DidStartNavigation");
+}
+
+void BreadcrumbManagerTabHelper::DidFinishNavigation(
+    web::WebState* web_state,
+    web::NavigationContext* navigation_context) {
+  LogEvent("DidFinishNavigation");
+}
+
+void BreadcrumbManagerTabHelper::DidStartLoading(web::WebState* web_state) {
+  LogEvent("DidStartLoading");
+}
+
+void BreadcrumbManagerTabHelper::DidStopLoading(web::WebState* web_state) {
+  LogEvent("DidStopLoading");
+}
+
+void BreadcrumbManagerTabHelper::PageLoaded(
+    web::WebState* web_state,
+    web::PageLoadCompletionStatus load_completion_status) {
+  switch (load_completion_status) {
+    case web::PageLoadCompletionStatus::SUCCESS:
+      LogEvent("PageLoaded: Success");
+      break;
+    case web::PageLoadCompletionStatus::FAILURE:
+      LogEvent("PageLoaded: Failure");
+      break;
+  }
+}
+
+void BreadcrumbManagerTabHelper::DidChangeBackForwardState(
+    web::WebState* web_state) {
+  LogEvent("DidChangeBackForwardState");
+}
+
+void BreadcrumbManagerTabHelper::TitleWasSet(web::WebState* web_state) {
+  LogEvent("TitleWasSet");
+}
+
+void BreadcrumbManagerTabHelper::DidChangeVisibleSecurityState(
+    web::WebState* web_state) {
+  LogEvent("DidChangeVisibleSecurityState");
+}
+
+void BreadcrumbManagerTabHelper::FaviconUrlUpdated(
+    web::WebState* web_state,
+    const std::vector<web::FaviconURL>& candidates) {
+  LogEvent(base::StringPrintf("FaviconUrlUpdated %lu", candidates.size()));
+}
+
+void BreadcrumbManagerTabHelper::RenderProcessGone(web::WebState* web_state) {
+  LogEvent("RenderProcessGone");
+}
+
+void BreadcrumbManagerTabHelper::WebStateDestroyed(web::WebState* web_state) {
+  LogEvent("WebStateDestroyed");
+  web_state->RemoveObserver(this);
+}
+
+WEB_STATE_USER_DATA_KEY_IMPL(BreadcrumbManagerTabHelper)
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm
new file mode 100644
index 0000000..baa145c
--- /dev/null
+++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper_unittest.mm
@@ -0,0 +1,92 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h"
+
+#include "base/test/task_environment.h"
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h"
+#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h"
+#import "ios/web/public/test/fakes/test_web_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#import "testing/gtest_mac.h"
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// Test fixture for TabIdTabHelper class.
+class BreadcrumbManagerTabHelperTest : public PlatformTest {
+ protected:
+  void SetUp() override {
+    PlatformTest::SetUp();
+    TestChromeBrowserState::Builder test_cbs_builder;
+    chrome_browser_state_ = test_cbs_builder.Build();
+
+    first_web_state_.SetBrowserState(chrome_browser_state_.get());
+    second_web_state_.SetBrowserState(chrome_browser_state_.get());
+
+    breadcrumb_manager_ = static_cast<BreadcrumbManagerKeyedService*>(
+        BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
+            chrome_browser_state_.get()));
+  }
+
+  base::test::TaskEnvironment task_environment_;
+  std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
+  web::TestWebState first_web_state_;
+  web::TestWebState second_web_state_;
+  BreadcrumbManagerKeyedService* breadcrumb_manager_;
+};
+
+// Tests that the identifier returned for a WebState is unique.
+TEST_F(BreadcrumbManagerTabHelperTest, UniqueIdentifiers) {
+  BreadcrumbManagerTabHelper::CreateForWebState(&first_web_state_);
+  BreadcrumbManagerTabHelper::CreateForWebState(&second_web_state_);
+
+  int first_tab_identifier =
+      BreadcrumbManagerTabHelper::FromWebState(&first_web_state_)
+          ->GetUniqueId();
+  int second_tab_identifier =
+      BreadcrumbManagerTabHelper::FromWebState(&second_web_state_)
+          ->GetUniqueId();
+
+  EXPECT_GT(first_tab_identifier, 0);
+  EXPECT_GT(second_tab_identifier, 0);
+  EXPECT_NE(first_tab_identifier, second_tab_identifier);
+}
+
+// Tests that BreadcrumbManagerTabHelper events are logged to the associated
+// BreadcrumbManagerKeyedService. This test does not attempt to validate that
+// every observer method is correctly called as that is done in the
+// WebStateObserverTest tests.
+TEST_F(BreadcrumbManagerTabHelperTest, EventsLogged) {
+  BreadcrumbManagerTabHelper::CreateForWebState(&first_web_state_);
+
+  EXPECT_EQ(0ul, breadcrumb_manager_->GetEvents(0).size());
+  first_web_state_.SetLoading(true);
+  std::list<std::string> events = breadcrumb_manager_->GetEvents(0);
+  EXPECT_EQ(1ul, events.size());
+  EXPECT_NE(std::string::npos, events.back().find("DidStartLoading"));
+  first_web_state_.SetLoading(false);
+  events = breadcrumb_manager_->GetEvents(0);
+  EXPECT_EQ(2ul, events.size());
+  EXPECT_NE(std::string::npos, events.back().find("DidStopLoading"));
+}
+
+// Tests that BreadcrumbManagerTabHelper events logged from seperate WebStates
+// are unique.
+TEST_F(BreadcrumbManagerTabHelperTest, UniqueEvents) {
+  BreadcrumbManagerTabHelper::CreateForWebState(&first_web_state_);
+  first_web_state_.SetLoading(true);
+
+  BreadcrumbManagerTabHelper::CreateForWebState(&second_web_state_);
+  second_web_state_.SetLoading(true);
+
+  std::list<std::string> events = breadcrumb_manager_->GetEvents(0);
+  EXPECT_EQ(2ul, events.size());
+  EXPECT_STRNE(events.front().c_str(), events.back().c_str());
+  EXPECT_NE(std::string::npos, events.front().find("DidStartLoading"));
+  EXPECT_NE(std::string::npos, events.back().find("DidStartLoading"));
+}
diff --git a/ios/chrome/browser/infobars/overlays/BUILD.gn b/ios/chrome/browser/infobars/overlays/BUILD.gn
index bf929f6..7ae5cce 100644
--- a/ios/chrome/browser/infobars/overlays/BUILD.gn
+++ b/ios/chrome/browser/infobars/overlays/BUILD.gn
@@ -10,6 +10,8 @@
     "infobar_overlay_request_factory.h",
     "infobar_overlay_request_factory_impl.h",
     "infobar_overlay_request_factory_impl.mm",
+    "infobar_overlay_request_inserter.h",
+    "infobar_overlay_request_inserter.mm",
     "infobar_overlay_tab_helper.h",
     "infobar_overlay_tab_helper.mm",
     "infobar_overlay_type.h",
@@ -49,6 +51,7 @@
   sources = [
     "infobar_overlay_request_cancel_handler_unittest.mm",
     "infobar_overlay_request_factory_impl_unittest.mm",
+    "infobar_overlay_request_inserter_unittest.mm",
     "infobar_overlay_tab_helper_unittest.mm",
   ]
   deps = [
diff --git a/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h b/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h
index 4d2014d..4cc8689 100644
--- a/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h
+++ b/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h
@@ -10,7 +10,7 @@
 class OverlayRequest;
 
 // Fake version of InfobarOverlayRequestFactory.  Creates OverlayRequests that
-// are only configured with an InfobarOverlayData.
+// are only configured with an InfobarOverlayRequestConfig.
 class FakeInfobarOverlayRequestFactory : public InfobarOverlayRequestFactory {
  public:
   FakeInfobarOverlayRequestFactory();
diff --git a/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.mm b/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.mm
index 9203e71..c31aa0e 100644
--- a/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.mm
+++ b/ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h"
 
-#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h"
+#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -19,5 +19,5 @@
 FakeInfobarOverlayRequestFactory::CreateInfobarRequest(
     infobars::InfoBar* infobar,
     InfobarOverlayType type) {
-  return OverlayRequest::CreateWithConfig<InfobarOverlayData>(infobar);
+  return OverlayRequest::CreateWithConfig<InfobarOverlayRequestConfig>(infobar);
 }
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler_unittest.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler_unittest.mm
index fa7c222..a51a307 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler_unittest.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler_unittest.mm
@@ -7,6 +7,7 @@
 #include "components/infobars/core/infobar.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #include "ios/chrome/browser/infobars/test/fake_infobar_delegate.h"
+#import "ios/chrome/browser/infobars/test/fake_infobar_ios.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #include "ios/chrome/browser/overlays/public/overlay_request_queue.h"
 #include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h"
@@ -31,8 +32,7 @@
         std::make_unique<web::TestNavigationManager>());
     InfoBarManagerImpl::CreateForWebState(&web_state_);
     // Create a test InfoBar and add it to the manager.
-    std::unique_ptr<InfoBar> infobar =
-        std::make_unique<InfoBar>(std::make_unique<FakeInfobarDelegate>());
+    std::unique_ptr<InfoBar> infobar = std::make_unique<FakeInfobarIOS>();
     infobar_ = infobar.get();
     manager()->AddInfoBar(std::move(infobar));
     // Create a fake OverlayRequest and add it to the infobar banner queue using
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
index 35046ac..00e64308 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory_impl.h"
 
-#include "components/infobars/core/infobar.h"
 #import "ios/chrome/browser/infobars/infobar_ios.h"
 #import "ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h"
 #import "ios/chrome/browser/ui/infobars/infobar_ui_delegate.h"
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h
new file mode 100644
index 0000000..1bb3250
--- /dev/null
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h
@@ -0,0 +1,55 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_INFOBAR_OVERLAY_REQUEST_INSERTER_H_
+#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_INFOBAR_OVERLAY_REQUEST_INSERTER_H_
+
+#include <map>
+#include <memory>
+
+#include "ios/chrome/browser/infobars/overlays/infobar_overlay_type.h"
+
+namespace infobars {
+class InfoBar;
+}
+class InfobarOverlayRequestFactory;
+class OverlayRequestQueue;
+namespace web {
+class WebState;
+}
+
+// Helper object that creates OverlayRequests for InfoBars and inserts them into
+// a WebState's OverlayRequestQueues.
+class InfobarOverlayRequestInserter {
+ public:
+  // Constructor for an inserter that uses |factory| to construct
+  // OverlayRequests to insert into |web_state|'s OverlayRequestQueues.  Both
+  // |web_state| and |factory| must be non-null.
+  InfobarOverlayRequestInserter(
+      web::WebState* web_state,
+      std::unique_ptr<InfobarOverlayRequestFactory> factory);
+  ~InfobarOverlayRequestInserter();
+
+  // Creates an OverlayRequest for |type| configured with |infobar| and adds it
+  // to the back of the OverlayRequestQueue at |type|'s modality.
+  void AddOverlayRequest(infobars::InfoBar* infobar,
+                         InfobarOverlayType type) const;
+
+  // Creates an OverlayRequest for |type| configured with |infobar| and adds it
+  // at |index| to the OverlayRequestQueue at |type|'s modality.  |index| must
+  // be less than or equal to the size of the queue.
+  void InsertOverlayRequest(infobars::InfoBar* infobar,
+                            InfobarOverlayType type,
+                            size_t index) const;
+
+ private:
+  // The WebState whose queues are being inserted into.
+  web::WebState* web_state_ = nullptr;
+  // The factory used to create OverlayRequests.
+  std::unique_ptr<InfobarOverlayRequestFactory> request_factory_;
+  // Map of the OverlayRequestQueues to use for each InfobarOverlayType.
+  std::map<InfobarOverlayType, OverlayRequestQueue*> queues_;
+};
+
+#endif  // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_INFOBAR_OVERLAY_REQUEST_INSERTER_H_
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm
new file mode 100644
index 0000000..196a6a2
--- /dev/null
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.mm
@@ -0,0 +1,57 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h"
+
+#include "base/logging.h"
+#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler.h"
+#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory.h"
+#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
+#include "ios/chrome/browser/overlays/public/overlay_modality.h"
+#include "ios/chrome/browser/overlays/public/overlay_request.h"
+#import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+InfobarOverlayRequestInserter::InfobarOverlayRequestInserter(
+    web::WebState* web_state,
+    std::unique_ptr<InfobarOverlayRequestFactory> factory)
+    : web_state_(web_state), request_factory_(std::move(factory)) {
+  DCHECK(web_state_);
+  DCHECK(request_factory_);
+  // Populate |queues_| with the request queues at the appropriate modalities.
+  queues_[InfobarOverlayType::kBanner] = OverlayRequestQueue::FromWebState(
+      web_state_, OverlayModality::kInfobarBanner);
+  queues_[InfobarOverlayType::kDetailSheet] = OverlayRequestQueue::FromWebState(
+      web_state_, OverlayModality::kInfobarModal);
+  queues_[InfobarOverlayType::kModal] = OverlayRequestQueue::FromWebState(
+      web_state_, OverlayModality::kInfobarModal);
+}
+
+InfobarOverlayRequestInserter::~InfobarOverlayRequestInserter() = default;
+
+void InfobarOverlayRequestInserter::AddOverlayRequest(
+    infobars::InfoBar* infobar,
+    InfobarOverlayType type) const {
+  InsertOverlayRequest(infobar, type, queues_.at(type)->size());
+}
+
+void InfobarOverlayRequestInserter::InsertOverlayRequest(
+    infobars::InfoBar* infobar,
+    InfobarOverlayType type,
+    size_t index) const {
+  // Create the request and its cancel handler.
+  std::unique_ptr<OverlayRequest> request =
+      request_factory_->CreateInfobarRequest(infobar, type);
+  DCHECK(request.get());
+  DCHECK_EQ(infobar,
+            request->GetConfig<InfobarOverlayRequestConfig>()->infobar());
+  OverlayRequestQueue* queue = queues_.at(type);
+  std::unique_ptr<OverlayRequestCancelHandler> cancel_handler =
+      std::make_unique<InfobarOverlayRequestCancelHandler>(request.get(), queue,
+                                                           infobar);
+  queue->InsertRequest(index, std::move(request), std::move(cancel_handler));
+}
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter_unittest.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter_unittest.mm
new file mode 100644
index 0000000..5f0e972
--- /dev/null
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter_unittest.mm
@@ -0,0 +1,107 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h"
+
+#include "components/infobars/core/infobar.h"
+#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
+#import "ios/chrome/browser/infobars/overlays/fake_infobar_overlay_request_factory.h"
+#import "ios/chrome/browser/infobars/test/fake_infobar_delegate.h"
+#import "ios/chrome/browser/infobars/test/fake_infobar_ios.h"
+#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
+#include "ios/chrome/browser/overlays/public/overlay_request.h"
+#include "ios/chrome/browser/overlays/public/overlay_request_queue.h"
+#import "ios/web/public/test/fakes/test_navigation_manager.h"
+#import "ios/web/public/test/fakes/test_web_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using infobars::InfoBar;
+using infobars::InfoBarManager;
+
+// Test fixture for InfobarOverlayRequestInserter.
+class InfobarOverlayRequestInserterTest : public PlatformTest {
+ public:
+  InfobarOverlayRequestInserterTest()
+      : inserter_(&web_state_,
+                  std::make_unique<FakeInfobarOverlayRequestFactory>()) {
+    web_state_.SetNavigationManager(
+        std::make_unique<web::TestNavigationManager>());
+    InfoBarManagerImpl::CreateForWebState(&web_state_);
+  }
+
+  // Accessors.
+  InfobarOverlayRequestInserter* inserter() { return &inserter_; }
+  InfoBarManager* manager() {
+    return InfoBarManagerImpl::FromWebState(&web_state_);
+  }
+  OverlayRequestQueue* GetQueue(InfobarOverlayType type) {
+    OverlayModality modality = type == InfobarOverlayType::kBanner
+                                   ? OverlayModality::kInfobarBanner
+                                   : OverlayModality::kInfobarModal;
+    return OverlayRequestQueue::FromWebState(&web_state_, modality);
+  }
+
+  // Adds an InfoBar created with a test delegate to the manager.  Returns a
+  // pointer to the added InfoBar.
+  InfoBar* CreateInfobar() {
+    std::unique_ptr<InfoBar> added_infobar = std::make_unique<FakeInfobarIOS>();
+    InfoBar* infobar = added_infobar.get();
+    manager()->AddInfoBar(std::move(added_infobar));
+    return infobar;
+  }
+
+ private:
+  web::TestWebState web_state_;
+  InfobarOverlayRequestInserter inserter_;
+};
+
+// Tests that the inserter adds banner OverlayRequests to the correct queue.
+TEST_F(InfobarOverlayRequestInserterTest, InsertBanner) {
+  OverlayRequestQueue* queue = GetQueue(InfobarOverlayType::kBanner);
+  ASSERT_EQ(0U, queue->size());
+  // Insert |infobar| at front of queue and check that the queue is updated
+  // correctly.
+  InfoBar* infobar = CreateInfobar();
+  inserter()->AddOverlayRequest(infobar, InfobarOverlayType::kBanner);
+  EXPECT_EQ(1U, queue->size());
+  EXPECT_EQ(infobar, queue->front_request()
+                         ->GetConfig<InfobarOverlayRequestConfig>()
+                         ->infobar());
+  // Insert |inserted_infobar| in front of |infobar| and check that it is now
+  // the front request.
+  InfoBar* inserted_infobar = CreateInfobar();
+  inserter()->InsertOverlayRequest(inserted_infobar,
+                                   InfobarOverlayType::kBanner, 0);
+  EXPECT_EQ(2U, queue->size());
+  EXPECT_EQ(inserted_infobar, queue->front_request()
+                                  ->GetConfig<InfobarOverlayRequestConfig>()
+                                  ->infobar());
+}
+
+// Tests that the inserter adds banner OverlayRequests to the correct queue.
+TEST_F(InfobarOverlayRequestInserterTest, AddBanner) {
+  OverlayRequestQueue* queue = GetQueue(InfobarOverlayType::kBanner);
+  ASSERT_EQ(0U, queue->size());
+  // Add |infobar| to the back of the queue and check that the it is updated
+  // correctly.
+  InfoBar* infobar = CreateInfobar();
+  inserter()->AddOverlayRequest(infobar, InfobarOverlayType::kBanner);
+  EXPECT_EQ(1U, queue->size());
+  EXPECT_EQ(infobar, queue->front_request()
+                         ->GetConfig<InfobarOverlayRequestConfig>()
+                         ->infobar());
+  // Add |second_infobar| in to the queue and check that it is second in the
+  // queue.
+  InfoBar* second_infobar = CreateInfobar();
+  inserter()->AddOverlayRequest(second_infobar, InfobarOverlayType::kBanner);
+  EXPECT_EQ(2U, queue->size());
+  EXPECT_EQ(second_infobar, queue->GetRequest(1)
+                                ->GetConfig<InfobarOverlayRequestConfig>()
+                                ->infobar());
+}
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.h b/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.h
index eee19f9..0bcc777 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.h
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.h
@@ -9,10 +9,11 @@
 
 #include "base/scoped_observer.h"
 #include "components/infobars/core/infobar_manager.h"
+#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h"
 #import "ios/web/public/web_state_user_data.h"
 
 class InfobarOverlayRequestFactory;
-class OverlayRequestQueue;
+class InfobarOverlayRequestInserter;
 
 // Helper class that creates OverlayRequests for the banner UI for InfoBars
 // added to an InfoBarManager.
@@ -35,13 +36,17 @@
   friend class web::WebStateUserData<InfobarOverlayTabHelper>;
   WEB_STATE_USER_DATA_KEY_DECL();
 
+  // Getter for the request inserter.
+  const InfobarOverlayRequestInserter* request_inserter() const {
+    return &request_inserter_;
+  }
+
   // Helper object that schedules OverlayRequests for the banner UI for InfoBars
   // added to a WebState's InfoBarManager.
   class OverlayRequestScheduler : public infobars::InfoBarManager::Observer {
    public:
-    OverlayRequestScheduler(
-        web::WebState* web_state,
-        std::unique_ptr<InfobarOverlayRequestFactory> request_factory);
+    OverlayRequestScheduler(web::WebState* web_state,
+                            InfobarOverlayTabHelper* tab_helper);
     ~OverlayRequestScheduler() override;
 
    private:
@@ -50,18 +55,16 @@
     void OnManagerShuttingDown(infobars::InfoBarManager* manager) override;
 
    private:
-    // The request queue for the owning WebState.
-    OverlayRequestQueue* queue_ = nullptr;
-    // The request factory passed on initialization.  Used to create
-    // OverlayRequests for InfoBars added to the InfoBarManager.
-    std::unique_ptr<InfobarOverlayRequestFactory> request_factory_;
-
+    // The owning tab helper.
+    InfobarOverlayTabHelper* tab_helper_ = nullptr;
     ScopedObserver<infobars::InfoBarManager, infobars::InfoBarManager::Observer>
         scoped_observer_;
   };
 
+  // The inserter used to add infobar OverlayRequests to the WebState's queue.
+  InfobarOverlayRequestInserter request_inserter_;
   // The scheduler used to create OverlayRequests for InfoBars added to the
   // corresponding WebState's InfoBarManagerImpl.
-  OverlayRequestScheduler overlay_request_scheduler_;
+  OverlayRequestScheduler request_scheduler_;
 };
 #endif  // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_INFOBAR_OVERLAY_TAB_HELPER_H_
diff --git a/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.mm b/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.mm
index 299e7f6..8c32ba1 100644
--- a/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.mm
+++ b/ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.mm
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
-#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler.h"
 #import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_factory.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
@@ -37,7 +36,8 @@
 InfobarOverlayTabHelper::InfobarOverlayTabHelper(
     web::WebState* web_state,
     std::unique_ptr<InfobarOverlayRequestFactory> request_factory)
-    : overlay_request_scheduler_(web_state, std::move(request_factory)) {}
+    : request_inserter_(web_state, std::move(request_factory)),
+      request_scheduler_(web_state, this) {}
 
 InfobarOverlayTabHelper::~InfobarOverlayTabHelper() = default;
 
@@ -45,14 +45,9 @@
 
 InfobarOverlayTabHelper::OverlayRequestScheduler::OverlayRequestScheduler(
     web::WebState* web_state,
-    std::unique_ptr<InfobarOverlayRequestFactory> request_factory)
-    : queue_(
-          OverlayRequestQueue::FromWebState(web_state,
-                                            OverlayModality::kInfobarBanner)),
-      request_factory_(std::move(request_factory)),
-      scoped_observer_(this) {
-  DCHECK(queue_);
-  DCHECK(request_factory_);
+    InfobarOverlayTabHelper* tab_helper)
+    : tab_helper_(tab_helper), scoped_observer_(this) {
+  DCHECK(tab_helper_);
   InfoBarManager* manager = InfoBarManagerImpl::FromWebState(web_state);
   DCHECK(manager);
   scoped_observer_.Add(manager);
@@ -63,14 +58,8 @@
 
 void InfobarOverlayTabHelper::OverlayRequestScheduler::OnInfoBarAdded(
     InfoBar* infobar) {
-  std::unique_ptr<OverlayRequest> request =
-      request_factory_->CreateInfobarRequest(infobar,
-                                             InfobarOverlayType::kBanner);
-  DCHECK(request);
-  std::unique_ptr<OverlayRequestCancelHandler> cancel_handler =
-      std::make_unique<InfobarOverlayRequestCancelHandler>(request.get(),
-                                                           queue_, infobar);
-  queue_->AddRequest(std::move(request), std::move(cancel_handler));
+  tab_helper_->request_inserter()->AddOverlayRequest(
+      infobar, InfobarOverlayType::kBanner);
 }
 
 void InfobarOverlayTabHelper::OverlayRequestScheduler::OnManagerShuttingDown(
diff --git a/ios/chrome/browser/main/BUILD.gn b/ios/chrome/browser/main/BUILD.gn
index 5e1ab5f..e1841333 100644
--- a/ios/chrome/browser/main/BUILD.gn
+++ b/ios/chrome/browser/main/BUILD.gn
@@ -2,15 +2,32 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("main") {
+source_set("public") {
   sources = [
     "browser.h",
+    "browser_user_data.h",
+  ]
+  deps = [
+    "//base",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
+source_set("main") {
+  sources = [
+    "browser_agent_util.h",
+    "browser_agent_util.mm",
     "browser_impl.h",
     "browser_impl.mm",
     "browser_observer.h",
     "browser_web_state_list_delegate.h",
     "browser_web_state_list_delegate.mm",
   ]
+
+  public_deps = [
+    ":public",
+  ]
+
   deps = [
     "//base",
     "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/main/browser_agent_util.h b/ios/chrome/browser/main/browser_agent_util.h
new file mode 100644
index 0000000..fa659b2
--- /dev/null
+++ b/ios/chrome/browser/main/browser_agent_util.h
@@ -0,0 +1,13 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_MAIN_BROWSER_AGENT_UTIL_H_
+#define IOS_CHROME_BROWSER_MAIN_BROWSER_AGENT_UTIL_H_
+
+class Browser;
+
+// Attaches browser agents to |browser|.
+void AttachBrowserAgents(Browser* browser);
+
+#endif  // IOS_CHROME_BROWSER_MAIN_BROWSER_AGENT_UTIL_H_
diff --git a/ios/chrome/browser/main/browser_agent_util.mm b/ios/chrome/browser/main/browser_agent_util.mm
new file mode 100644
index 0000000..b997fb1e
--- /dev/null
+++ b/ios/chrome/browser/main/browser_agent_util.mm
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/main/browser_agent_util.h"
+
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+void AttachBrowserAgents(Browser* browser) {
+  TabInsertionBrowserAgent::CreateForBrowser(browser);
+}
diff --git a/ios/chrome/browser/main/browser_impl.mm b/ios/chrome/browser/main/browser_impl.mm
index 32971024..d0865977 100644
--- a/ios/chrome/browser/main/browser_impl.mm
+++ b/ios/chrome/browser/main/browser_impl.mm
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/main/browser_agent_util.h"
 #import "ios/chrome/browser/main/browser_observer.h"
 #import "ios/chrome/browser/main/browser_web_state_list_delegate.h"
 #import "ios/chrome/browser/sessions/session_service_ios.h"
@@ -77,5 +78,8 @@
 // static
 std::unique_ptr<Browser> Browser::Create(
     ios::ChromeBrowserState* browser_state) {
-  return std::make_unique<BrowserImpl>(browser_state);
+  std::unique_ptr<Browser> browser =
+      std::make_unique<BrowserImpl>(browser_state);
+  AttachBrowserAgents(browser.get());
+  return browser;
 }
diff --git a/ios/chrome/browser/main/browser_user_data.h b/ios/chrome/browser/main/browser_user_data.h
new file mode 100644
index 0000000..f649f22b
--- /dev/null
+++ b/ios/chrome/browser/main/browser_user_data.h
@@ -0,0 +1,68 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_
+#define IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/supports_user_data.h"
+#import "ios/chrome/browser/main/browser.h"
+
+// This macro declares a static variable inside the class that inherits from
+// BrwoserUserData. The address of this static variable is used as the key to
+// store/retrieve an instance of the class on/from a WebState.
+#define BROWSER_USER_DATA_KEY_DECL() static constexpr int kUserDataKey = 0
+
+// This macro instantiates the static variable declared by the previous macro.
+// It must live in a .mm/.cc file to ensure that there is only one instantiation
+// of the static variable.
+#define BROWSER_USER_DATA_KEY_IMPL(Type) const int Type::kUserDataKey;
+
+// A base class for classes attached to, and scoped to, the lifetime of a
+// Browser. For example:
+//
+// --- in foo_browser_agent.h ---
+// class FooBrowserAgent : public BrowserUserData<FooBrowserAgent> {
+//  public:
+//   ~FooBrowserAgent() override;
+//   // ... more public stuff here ...
+//  private:
+//   explicit FooBrowserAgent(Browser* browser);
+//   friend class BrowserUserData<FooBrowserAgent>;
+//   BROWSER_USER_DATA_KEY_DECL();
+//   // ... more private stuff here ...
+// };
+//
+// --- in foo_browser_agent.cc ---
+// BROWSER_USER_DATA_KEY_IMPL(FooBrowserAgent)
+template <typename T>
+class BrowserUserData : public base::SupportsUserData::Data {
+ public:
+  // Creates an object of type T, and attaches it to the specified WebState.
+  // If an instance is already attached, does nothing.
+  static void CreateForBrowser(Browser* browser) {
+    if (!FromBrowser(browser))
+      browser->SetUserData(UserDataKey(), base::WrapUnique(new T(browser)));
+  }
+
+  // Retrieves the instance of type T that was attached to the specified
+  // Browser (via CreateForBrowser above) and returns it. If no instance
+  // of the type was attached, returns nullptr.
+  static T* FromBrowser(Browser* browser) {
+    return static_cast<T*>(browser->GetUserData(UserDataKey()));
+  }
+  static const T* FromBrowser(const Browser* browser) {
+    return static_cast<const T*>(browser->GetUserData(UserDataKey()));
+  }
+
+  // Removes the instance attached to the specified Browser.
+  static void RemoveFromBrowser(Browser* browser) {
+    browser->RemoveUserData(UserDataKey());
+  }
+
+  static const void* UserDataKey() { return &T::kUserDataKey; }
+};
+
+#endif  // IOS_CHROME_BROWSER_MAIN_BROWSER_USER_DATA_H_
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn
index 9a35d54..690ea68 100644
--- a/ios/chrome/browser/metrics/BUILD.gn
+++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -150,6 +150,7 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/prerender",
+    "//ios/chrome/browser/sessions:restoration_observer",
     "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder.h b/ios/chrome/browser/metrics/tab_usage_recorder.h
index 02ef996..bc78a45 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder.h
+++ b/ios/chrome/browser/metrics/tab_usage_recorder.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "ios/chrome/browser/metrics/tab_usage_recorder_metrics.h"
+#include "ios/chrome/browser/sessions/session_restoration_observer.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer.h"
 #include "ios/web/public/web_state_observer.h"
 
@@ -25,7 +26,8 @@
 
 // Reports usage about the lifecycle of a single TabModel's tabs.
 class TabUsageRecorder : public web::WebStateObserver,
-                         public WebStateListObserver {
+                         public WebStateListObserver,
+                         public SessionRestorationObserver {
  public:
   // Initializes the TabUsageRecorder to watch |web_state_list|.
   TabUsageRecorder(WebStateList* web_state_list,
@@ -142,6 +144,10 @@
                            int active_index,
                            int reason) override;
 
+  // SessionRestorationObserver implementation.
+  void SessionRestorationFinished(
+      const std::vector<web::WebState*>& restored_web_states) override;
+
   // Keep track of when the most recent tab restore begins, to record the time
   // between evicted-tab-reloads.
   base::TimeTicks restore_start_time_;
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder.mm b/ios/chrome/browser/metrics/tab_usage_recorder.mm
index aa695bcd..a8a8778e 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder.mm
@@ -494,3 +494,9 @@
   if (reason & WebStateListObserver::CHANGE_REASON_USER_ACTION)
     RecordTabSwitched(old_web_state, new_web_state);
 }
+
+void TabUsageRecorder::SessionRestorationFinished(
+    const std::vector<web::WebState*>& restored_web_states) {
+  InitialRestoredTabs(web_state_list_->GetActiveWebState(),
+                      restored_web_states);
+}
diff --git a/ios/chrome/browser/overlays/BUILD.gn b/ios/chrome/browser/overlays/BUILD.gn
index 164b467..1c396c2 100644
--- a/ios/chrome/browser/overlays/BUILD.gn
+++ b/ios/chrome/browser/overlays/BUILD.gn
@@ -4,7 +4,9 @@
 
 source_set("overlays") {
   public = [
+    "public/overlay_callback_manager.h",
     "public/overlay_dismissal_callback.h",
+    "public/overlay_dispatch_callback_storage.h",
     "public/overlay_modality.h",
     "public/overlay_presentation_callback.h",
     "public/overlay_presentation_context.h",
@@ -21,6 +23,9 @@
   sources = [
     "default_overlay_request_cancel_handler.h",
     "default_overlay_request_cancel_handler.mm",
+    "overlay_callback_manager_impl.cc",
+    "overlay_callback_manager_impl.h",
+    "overlay_dispatch_callback_storage.cc",
     "overlay_presenter_impl.h",
     "overlay_presenter_impl.mm",
     "overlay_presenter_observer_bridge.mm",
@@ -49,6 +54,7 @@
   testonly = true
   sources = [
     "default_overlay_request_cancel_handler_unittest.mm",
+    "overlay_callback_manager_impl_unittest.cc",
     "overlay_presenter_impl_unittest.mm",
     "overlay_presenter_observer_bridge_unittest.mm",
     "overlay_request_impl_unittest.cc",
diff --git a/ios/chrome/browser/overlays/README.md b/ios/chrome/browser/overlays/README.md
index e967994..a994ca11 100644
--- a/ios/chrome/browser/overlays/README.md
+++ b/ios/chrome/browser/overlays/README.md
@@ -15,10 +15,23 @@
 ##### OverlayResponse
 
 OverlayResponses are provided to each OverlayRequest to describe the user's
-interaction with the overlay UI.  Clients should create OverlayResponses with an
-OverlayUserData subclass with the overlay UI user interaction information
+interaction with the overlay UI.  Clients should create OverlayResponses with 
+OverlayUserData subclasses with the overlay UI user interaction information
 necessary to execute the callback for that overlay.
 
+##### OverlayCallbackManager
+
+Each OverlayRequest owns an OverlayCallbackManager, which is used to communicate
+user interaction events from the overlay UI to the requesting site.  It supports
+two types of callbacks: completion callbacks and dispatch callbacks.  Completion
+callbacks are executed when the overlay UI is dismissed or the OverlayRequest is
+cancelled.  These callbacks are executed with a completion OverlayResponse.  In
+order to handle model updates for user interaction events for ongoing overlay
+UI, the callback manager also supports callbacks for OverlayResponses dispatched
+before overlay completion.  OverlayPresenter clients can register callbacks to
+be executed upon every dispatch of an OverlayResponse created with a specific
+type of response info type.
+
 ##### OverlayRequestQueue
 
 Each WebState has an OverlayRequestQueue at each OverlayModality that stores the
@@ -32,18 +45,19 @@
 OverlayPresenter drives the presentation of the UI for OverlayRequests added to
 queues for WebStates in a Browser.
 
-#### OverlayPresentationContext
+##### OverlayPresentationContext
 
 Clients must provide a presentation context to a Browser's OverlayPresenter that
 handles the presentation of overlay UI for that presenter's modality and
 Browser.
 
-#### OverlayPresenterObserver
+##### OverlayPresenterObserver
 
 Objects that care about the presentation and dismissal of overlay UI by the
 presenter should add themselves as observers to the presenter.  This can be used
 to respond to update UI for UI presentation, for example to update the location
-bar text while a dialog is displayed.
+bar text while a dialog is displayed.  Additionally, observers can use these
+hook points to add additional callbacks to the request.
 
 ## Setting up OverlayPresenter:
 
@@ -59,7 +73,7 @@
 
 ### Showing an alert with a title, message, an OK button, and a Cancel button
 
-#####1. Create OverlayUserData subclasses for the requests and responses:
+##### 1. Create OverlayUserData subclasses for the requests and responses:
 
 A request configuration user data should be created with the information
 necessary to set up the overlay UI being requested.
@@ -68,9 +82,9 @@
      public:
       const std::string& title() const;
       const std::string& message() const;
-      const std::vector<std::string>& button\_titles() const;
+      const std::vector<std::string>& button_titles() const;
      private:
-      OVERLAY\_USER\_DATA\_SETUP(AlertConfig);
+      OVERLAY_USER_DATA_SETUP(AlertConfig);
       AlertConfig(const std::string& title, const std::string& message);
     };
 
@@ -79,13 +93,13 @@
 
     class AlertInfo : public OverlayUserData<AlertInfo> {
      public:
-      const size\_t tapped\_button\_index() const;
+      const size_t tapped_button_index() const;
      private:
-      OVERLAY\_USER\_DATA\_SETUP(AlertInfo);
-      AlertInfo(size\_t tapped\_button\_index);
+      OVERLAY_USER_DATA_SETUP(AlertInfo);
+      AlertInfo(size_t tapped_button_index);
     };
 
-#####2. Request an overlay using the request config user data.
+##### 2. Request an overlay using the request config user data.
 
 An OverlayRequest for the alert can be created using:
 
@@ -94,14 +108,14 @@
 
 A callback can be added to the request to use the response info:
 
-    OverlayCallback callback =
+    OverlayCompletionCallback callback =
         base::BindOnce(base::RetainBlock(^(OverlayResponse* response) {
       if (!response)
         return;
       AlertInfo* info = response->GetInfo<AlertInfo>();
-      /* Handle button tap at info->tapped\_button\_index() */
+      /* Handle button tap at info->tapped_button_index() */
     }));
-    request->set_callback(std::move(callback));
+    request->GetCallbackManager()->AddCompletionCallback(std::move(callback));
 
 Clients can then supply this request to the OverlayRequestQueue corresponding
 with the WebState alongside which the overlay should be shown:
@@ -111,11 +125,83 @@
     OverlayRequestQueue::FromWebState(web_state, modality)->
         AddRequest(std::move(request));
 
-#####3. Supply a response to the request.
+##### 3. Supply a response to the request.
 
 Upon the user tapping a button on the alert, say at index 0, a response can be
 created and supplied to that request.
 
-    OverlayRequestQueue::FromWebState(web_state, modality)->front_request()->
-        set_response(OverlayResponse::CreateWithInfo<AlertInfo>(0));
+    OverlayRequestQueue::FromWebState(web_state, modality)
+        ->front_request()
+        ->GetCallbackManager()
+        ->SetCompletionResponse(OverlayResponse::CreateWithInfo<AlertInfo>(0));
+
+### Dispatching responses for ongoing overlays
+
+This section documents how to update model objects for user interaction events
+in overlay UI that has not been dismissed yet.  As an example situation, let's
+say that there's a non-modal account picking screen.  When the user taps on an
+account, we want to update the username text in a separate view without
+dismissing the overlay UI.  This can be accomplished by dispatching responses
+through the callback manager.
+
+##### 1. Create OverlayUserData subclasses for the dispatched response:
+
+OverlayRequests configured with AccountChooserUserInfos will be dispatched via
+the OverlayRequest's callback manager in order to update the username label in
+a browser view.
+
+    class AccountChooserUserInfo :
+        public OverlayUserData<AccountChooserUserInfo> {
+     public:
+      const std::string& username() const;
+     private:
+      OVERLAY_USER_DATA_SETUP(AccountChooserUserInfo);
+      AccountChooserUserInfo(const std::string& username);
+    };
+
+##### 2. Use OverlayPresenterObserver to add a dispatch callback:
+
+The mediator for the UI showing the username label should register itself as an
+OverlayPresenterObserver so that it can be aware of the presentation of UI.
+
+    @interface UsernameLabelMediator ()<OverlayPresenterObserving>
+    @end
+
+    @implementation UsernameLabelMediator
+
+    - (void)overlayPresenter:(OverlayPresenter\*)presenter
+        willShowOverlayForRequest:(OverlayRequest*)request {
+      // Only add the dispatch callback for requests created with the desired
+      // config.  This mediator only cares about requests for the account
+      // chooser UI (AccountChooserRequestConfig definition not shown).
+      if (!request->GetConfig<AccountChooserRequestConfig>())
+        return;
+      __weak __typeof__(self) weakSelf = self;
+      OverlayDispatchCallback callback =
+          base::BindRepeating(^(OverlayResponse* response) {
+        weakSelf.consumer.usernameText = base::SysUTF8ToNSString(
+            response->GetInfo<AccountChooserUserInfo>()->username());
+      });
+      request->GetCallbackManager()->AddDispatchCallback(std::move(callback));
+    }
+
+    @end
+
+##### 3. Dispatch OverlayResponses for non-dismissing UI events
+
+When the user taps on a row in the account chooser overlay UI, the overlay's
+mediator would handle this event by dispatching an OverlayRequest created with
+an AccountChooserUserInfo in order to trigger callbacks for that type of
+response.
+
+    @implementation AccountChooserOverlayMediator
+
+    - (void)didTapOnAccountWithUsername:(NSString\*)username {
+      self.request->GetCallbackManager()->DispatchResponse(
+          OverlayResponse::CreateWithInfo<AccountChooserUserInfo>(
+          base::SysNSStringToUTF8(username)));
+    }
+
+    @end
+
 
diff --git a/ios/chrome/browser/overlays/overlay_callback_manager_impl.cc b/ios/chrome/browser/overlays/overlay_callback_manager_impl.cc
new file mode 100644
index 0000000..474dda4
--- /dev/null
+++ b/ios/chrome/browser/overlays/overlay_callback_manager_impl.cc
@@ -0,0 +1,48 @@
+// 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 "ios/chrome/browser/overlays/overlay_callback_manager_impl.h"
+
+#include "base/logging.h"
+
+OverlayCallbackManagerImpl::OverlayCallbackManagerImpl() = default;
+
+OverlayCallbackManagerImpl::~OverlayCallbackManagerImpl() {
+  // The completion callbacks must be executed before destruction.
+  DCHECK(completion_callbacks_.empty());
+}
+
+void OverlayCallbackManagerImpl::ExecuteCompletionCallbacks() {
+  for (auto& callback : completion_callbacks_) {
+    DCHECK(!callback.is_null());
+    std::move(callback).Run(GetCompletionResponse());
+  }
+  completion_callbacks_.clear();
+}
+
+void OverlayCallbackManagerImpl::SetCompletionResponse(
+    std::unique_ptr<OverlayResponse> response) {
+  completion_response_ = std::move(response);
+}
+
+OverlayResponse* OverlayCallbackManagerImpl::GetCompletionResponse() const {
+  return completion_response_.get();
+}
+
+void OverlayCallbackManagerImpl::AddCompletionCallback(
+    OverlayCompletionCallback callback) {
+  DCHECK(!callback.is_null());
+  completion_callbacks_.emplace_back(std::move(callback));
+}
+
+void OverlayCallbackManagerImpl::DispatchResponse(
+    std::unique_ptr<OverlayResponse> response) {
+  DCHECK(response);
+  dispatch_callback_storage_.DispatchResponse(response.get());
+}
+
+OverlayDispatchCallbackStorage*
+OverlayCallbackManagerImpl::GetDispatchCallbackStorage() {
+  return &dispatch_callback_storage_;
+}
diff --git a/ios/chrome/browser/overlays/overlay_callback_manager_impl.h b/ios/chrome/browser/overlays/overlay_callback_manager_impl.h
new file mode 100644
index 0000000..17d3efe
--- /dev/null
+++ b/ios/chrome/browser/overlays/overlay_callback_manager_impl.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_CALLBACK_MANAGER_IMPL_H_
+#define IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_CALLBACK_MANAGER_IMPL_H_
+
+#include <vector>
+
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
+#include "ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h"
+#include "ios/chrome/browser/overlays/public/overlay_response.h"
+
+// Implementation of OverlayCallbackManager.
+class OverlayCallbackManagerImpl : public OverlayCallbackManager {
+ public:
+  OverlayCallbackManagerImpl();
+  ~OverlayCallbackManagerImpl() override;
+  OverlayCallbackManagerImpl(const OverlayCallbackManagerImpl&) = delete;
+
+  // Executes the completion callbacks.
+  void ExecuteCompletionCallbacks();
+
+  // OverlayCallbackManager:
+  void SetCompletionResponse(
+      std::unique_ptr<OverlayResponse> response) override;
+  OverlayResponse* GetCompletionResponse() const override;
+  void AddCompletionCallback(OverlayCompletionCallback callback) override;
+  void DispatchResponse(std::unique_ptr<OverlayResponse> response) override;
+  OverlayDispatchCallbackStorage* GetDispatchCallbackStorage() override;
+
+ private:
+  // The completion response and callbacks.
+  std::unique_ptr<OverlayResponse> completion_response_;
+  std::vector<OverlayCompletionCallback> completion_callbacks_;
+  // The storage holding OverlayDispatchCallbacks.
+  OverlayDispatchCallbackStorage dispatch_callback_storage_;
+};
+
+#endif  // IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_CALLBACK_MANAGER_IMPL_H_
diff --git a/ios/chrome/browser/overlays/overlay_callback_manager_impl_unittest.cc b/ios/chrome/browser/overlays/overlay_callback_manager_impl_unittest.cc
new file mode 100644
index 0000000..433b009e
--- /dev/null
+++ b/ios/chrome/browser/overlays/overlay_callback_manager_impl_unittest.cc
@@ -0,0 +1,101 @@
+// 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 "ios/chrome/browser/overlays/overlay_callback_manager_impl.h"
+
+#include "base/bind.h"
+#include "ios/chrome/browser/overlays/public/overlay_response.h"
+#include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h"
+#include "testing/platform_test.h"
+
+namespace {
+// Fake dispatch response info types.
+class FirstResponseInfo : public OverlayUserData<FirstResponseInfo> {
+ private:
+  OVERLAY_USER_DATA_SETUP(FirstResponseInfo);
+};
+OVERLAY_USER_DATA_SETUP_IMPL(FirstResponseInfo);
+class SecondResponseInfo : public OverlayUserData<SecondResponseInfo> {
+ private:
+  OVERLAY_USER_DATA_SETUP(SecondResponseInfo);
+};
+OVERLAY_USER_DATA_SETUP_IMPL(SecondResponseInfo);
+}  // namespace
+
+using OverlayCallbackManagerImplTest = PlatformTest;
+
+// Tests that OverlayCallbackManagerImpl can add and execute completion
+// callbacks.
+TEST_F(OverlayCallbackManagerImplTest, CompletionCallbacks) {
+  OverlayCallbackManagerImpl manager;
+  void* kResponseData = &kResponseData;
+  // Add two completion callbacks that increment |callback_execution_count|.
+  __block size_t callback_execution_count = 0;
+  void (^callback_block)(OverlayResponse* response) =
+      ^(OverlayResponse* response) {
+        if (!response)
+          return;
+        if (response->GetInfo<FakeOverlayUserData>()->value() != kResponseData)
+          return;
+        ++callback_execution_count;
+      };
+  manager.AddCompletionCallback(
+      base::BindOnce(base::RetainBlock(callback_block)));
+  manager.AddCompletionCallback(
+      base::BindOnce(base::RetainBlock(callback_block)));
+
+  // Add a response to the queue with a fake info using kResponseData.
+  manager.SetCompletionResponse(
+      OverlayResponse::CreateWithInfo<FakeOverlayUserData>(kResponseData));
+  OverlayResponse* response = manager.GetCompletionResponse();
+  ASSERT_TRUE(response);
+  EXPECT_EQ(kResponseData, response->GetInfo<FakeOverlayUserData>()->value());
+
+  // Execute the callbacks and verify that both are called once.
+  ASSERT_EQ(0U, callback_execution_count);
+  manager.ExecuteCompletionCallbacks();
+  EXPECT_EQ(2U, callback_execution_count);
+}
+
+// Tests that OverlayCallbackManagerImpl can add and execute dispatch
+// callbacks, and that the callbacks are only executed for dispatched responses
+// of the appropriate type.
+TEST_F(OverlayCallbackManagerImplTest, DispatchCallbacks) {
+  OverlayCallbackManagerImpl manager;
+  // Add two dispatch callbacks for each fake response info type.
+  __block size_t first_execution_count = 0;
+  void (^first_callback_block)(OverlayResponse* response) =
+      ^(OverlayResponse* response) {
+        ++first_execution_count;
+      };
+  __block size_t second_execution_count = 0;
+  void (^second_callback_block)(OverlayResponse* response) =
+      ^(OverlayResponse* response) {
+        ++second_execution_count;
+      };
+  manager.AddDispatchCallback<FirstResponseInfo>(
+      base::BindRepeating(base::RetainBlock(first_callback_block)));
+  manager.AddDispatchCallback<SecondResponseInfo>(
+      base::BindRepeating(base::RetainBlock(second_callback_block)));
+  ASSERT_EQ(0U, first_execution_count);
+  ASSERT_EQ(0U, second_execution_count);
+
+  // Send two response with the first response info.
+  manager.DispatchResponse(
+      OverlayResponse::CreateWithInfo<FirstResponseInfo>());
+  manager.DispatchResponse(
+      OverlayResponse::CreateWithInfo<FirstResponseInfo>());
+
+  EXPECT_EQ(2U, first_execution_count);
+  EXPECT_EQ(0U, second_execution_count);
+
+  // Send two response with the second response info.
+  manager.DispatchResponse(
+      OverlayResponse::CreateWithInfo<SecondResponseInfo>());
+  manager.DispatchResponse(
+      OverlayResponse::CreateWithInfo<SecondResponseInfo>());
+
+  EXPECT_EQ(2U, first_execution_count);
+  EXPECT_EQ(2U, second_execution_count);
+}
diff --git a/ios/chrome/browser/overlays/overlay_dispatch_callback_storage.cc b/ios/chrome/browser/overlays/overlay_dispatch_callback_storage.cc
new file mode 100644
index 0000000..8246a342
--- /dev/null
+++ b/ios/chrome/browser/overlays/overlay_dispatch_callback_storage.cc
@@ -0,0 +1,39 @@
+// 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 "ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h"
+
+#pragma mark - OverlayDispatchCallbackStorage
+
+OverlayDispatchCallbackStorage::OverlayDispatchCallbackStorage() = default;
+
+OverlayDispatchCallbackStorage::~OverlayDispatchCallbackStorage() = default;
+
+void OverlayDispatchCallbackStorage::DispatchResponse(
+    OverlayResponse* response) {
+  for (auto& list_pair : callback_lists_) {
+    list_pair.second->ExecuteCallbacks(response);
+  }
+}
+
+#pragma mark - OverlayDispatchCallbackStorage::CallbackList
+
+OverlayDispatchCallbackStorage::CallbackList::CallbackList() = default;
+
+OverlayDispatchCallbackStorage::CallbackList::~CallbackList() = default;
+
+void OverlayDispatchCallbackStorage::CallbackList::AddCallback(
+    OverlayDispatchCallback callback) {
+  DCHECK(!callback.is_null());
+  callbacks_.emplace_back(std::move(callback));
+}
+
+void OverlayDispatchCallbackStorage::CallbackList::ExecuteCallbacks(
+    OverlayResponse* response) {
+  if (!ShouldExecuteForResponse(response))
+    return;
+  for (auto& callback : callbacks_) {
+    callback.Run(response);
+  }
+}
diff --git a/ios/chrome/browser/overlays/overlay_request_impl.cc b/ios/chrome/browser/overlays/overlay_request_impl.cc
index b76d06b..2dbac92 100644
--- a/ios/chrome/browser/overlays/overlay_request_impl.cc
+++ b/ios/chrome/browser/overlays/overlay_request_impl.cc
@@ -14,22 +14,11 @@
 OverlayRequestImpl::OverlayRequestImpl() {}
 
 OverlayRequestImpl::~OverlayRequestImpl() {
-  if (!callback_.is_null())
-    std::move(callback_).Run(response());
+  callback_manager_.ExecuteCompletionCallbacks();
 }
 
-void OverlayRequestImpl::set_response(
-    std::unique_ptr<OverlayResponse> response) {
-  response_ = std::move(response);
-}
-
-OverlayResponse* OverlayRequestImpl::response() const {
-  return response_.get();
-}
-
-void OverlayRequestImpl::set_callback(OverlayCallback callback) {
-  DCHECK(callback_.is_null());
-  callback_ = std::move(callback);
+OverlayCallbackManager* OverlayRequestImpl::GetCallbackManager() {
+  return &callback_manager_;
 }
 
 base::SupportsUserData* OverlayRequestImpl::data() {
diff --git a/ios/chrome/browser/overlays/overlay_request_impl.h b/ios/chrome/browser/overlays/overlay_request_impl.h
index bc452d4..1e879a3 100644
--- a/ios/chrome/browser/overlays/overlay_request_impl.h
+++ b/ios/chrome/browser/overlays/overlay_request_impl.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "ios/chrome/browser/overlays/overlay_callback_manager_impl.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 
 // Internal implementation of OverlayRequest.
@@ -17,17 +18,11 @@
   ~OverlayRequestImpl() override;
 
   // OverlayRequest:
-  void set_response(std::unique_ptr<OverlayResponse> response) override;
-  OverlayResponse* response() const override;
-  void set_callback(OverlayCallback callback) override;
+  OverlayCallbackManager* GetCallbackManager() override;
   base::SupportsUserData* data() override;
 
  private:
-  // The response containing the user interaction information for the overlay
-  // resulting from this response.
-  std::unique_ptr<OverlayResponse> response_;
-  // The callback to be executed upon dismissal of the overlay.
-  OverlayCallback callback_;
+  OverlayCallbackManagerImpl callback_manager_;
 };
 
 #endif  // IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_REQUEST_IMPL_H_
diff --git a/ios/chrome/browser/overlays/overlay_request_impl_unittest.cc b/ios/chrome/browser/overlays/overlay_request_impl_unittest.cc
index 823dc3c8..5a8fe1fd 100644
--- a/ios/chrome/browser/overlays/overlay_request_impl_unittest.cc
+++ b/ios/chrome/browser/overlays/overlay_request_impl_unittest.cc
@@ -5,6 +5,7 @@
 #include "ios/chrome/browser/overlays/overlay_request_impl.h"
 
 #include "base/bind.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #include "ios/chrome/browser/overlays/public/overlay_response.h"
 #include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h"
 #include "testing/platform_test.h"
@@ -16,17 +17,14 @@
   void* kResponseData = &kResponseData;
   std::unique_ptr<OverlayRequest> request =
       OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
-  OverlayRequestImpl* request_impl =
-      static_cast<OverlayRequestImpl*>(request.get());
   __block bool callback_executed = false;
-  OverlayCallback callback =
+  request->GetCallbackManager()->AddCompletionCallback(
       base::BindOnce(base::RetainBlock(^(OverlayResponse* response) {
         callback_executed =
             response &&
             response->GetInfo<FakeOverlayUserData>()->value() == kResponseData;
-      }));
-  request_impl->set_callback(std::move(callback));
-  request->set_response(
+      })));
+  request->GetCallbackManager()->SetCompletionResponse(
       OverlayResponse::CreateWithInfo<FakeOverlayUserData>(kResponseData));
   request = nullptr;
   EXPECT_TRUE(callback_executed);
diff --git a/ios/chrome/browser/overlays/public/common/infobars/BUILD.gn b/ios/chrome/browser/overlays/public/common/infobars/BUILD.gn
index 68aea5ae..eeba13c 100644
--- a/ios/chrome/browser/overlays/public/common/infobars/BUILD.gn
+++ b/ios/chrome/browser/overlays/public/common/infobars/BUILD.gn
@@ -4,8 +4,8 @@
 
 source_set("infobars") {
   sources = [
-    "infobar_overlay.h",
-    "infobar_overlay.mm",
+    "infobar_overlay_request_config.h",
+    "infobar_overlay_request_config.mm",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
@@ -13,6 +13,9 @@
   deps = [
     "//base",
     "//components/infobars/core",
+    "//ios/chrome/browser/infobars",
+    "//ios/chrome/browser/infobars:public",
     "//ios/chrome/browser/overlays",
+    "//ios/chrome/browser/ui/infobars:infobars_ui",
   ]
 }
diff --git a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h
deleted file mode 100644
index 9e64da0..0000000
--- a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_H_
-#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_H_
-
-#include "ios/chrome/browser/overlays/public/overlay_user_data.h"
-
-namespace infobars {
-class InfoBar;
-}
-
-// OverlayUserData used to hold a pointer to an InfoBar.  Used as auxilliary
-// data for OverlayRequests for InfoBars.
-class InfobarOverlayData : public OverlayUserData<InfobarOverlayData> {
- public:
-  ~InfobarOverlayData() override;
-
-  // The InfoBar that triggered this OverlayRequest.
-  infobars::InfoBar* infobar() const { return infobar_; }
-
- private:
-  OVERLAY_USER_DATA_SETUP(InfobarOverlayData);
-  explicit InfobarOverlayData(infobars::InfoBar* infobar);
-
-  // The InfoBar causing this overlay.
-  infobars::InfoBar* infobar_ = nullptr;
-};
-
-#endif  // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_H_
diff --git a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.mm b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.mm
deleted file mode 100644
index d3af80fa..0000000
--- a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.mm
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h"
-
-#include "base/logging.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-using infobars::InfoBar;
-
-OVERLAY_USER_DATA_SETUP_IMPL(InfobarOverlayData);
-
-InfobarOverlayData::InfobarOverlayData(InfoBar* infobar) : infobar_(infobar) {
-  DCHECK(infobar_);
-}
-
-InfobarOverlayData::~InfobarOverlayData() = default;
diff --git a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h
new file mode 100644
index 0000000..e089f55
--- /dev/null
+++ b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_REQUEST_CONFIG_H_
+#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_REQUEST_CONFIG_H_
+
+#import "ios/chrome/browser/infobars/infobar_type.h"
+#include "ios/chrome/browser/overlays/public/overlay_user_data.h"
+
+namespace infobars {
+class InfoBar;
+}
+
+// OverlayUserData used to hold a pointer to an InfoBar.  Used as auxiliary
+// data for OverlayRequests for InfoBars.
+class InfobarOverlayRequestConfig
+    : public OverlayUserData<InfobarOverlayRequestConfig> {
+ public:
+  ~InfobarOverlayRequestConfig() override;
+
+  // The InfoBar that triggered this OverlayRequest.
+  infobars::InfoBar* infobar() const { return infobar_; }
+  // |infobar_|'s type.
+  InfobarType infobar_type() const { return infobar_type_; }
+  // Whether |infobar_| has a badge.
+  bool has_badge() const { return has_badge_; }
+
+ private:
+  OVERLAY_USER_DATA_SETUP(InfobarOverlayRequestConfig);
+  explicit InfobarOverlayRequestConfig(infobars::InfoBar* infobar);
+
+  infobars::InfoBar* infobar_ = nullptr;
+  InfobarType infobar_type_;
+  bool has_badge_ = false;
+};
+
+#endif  // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_COMMON_INFOBARS_INFOBAR_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm
new file mode 100644
index 0000000..689eb74
--- /dev/null
+++ b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
+
+#include "base/logging.h"
+#import "ios/chrome/browser/infobars/infobar_ios.h"
+#import "ios/chrome/browser/ui/infobars/infobar_ui_delegate.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using infobars::InfoBar;
+
+OVERLAY_USER_DATA_SETUP_IMPL(InfobarOverlayRequestConfig);
+
+InfobarOverlayRequestConfig::InfobarOverlayRequestConfig(InfoBar* infobar)
+    : infobar_(infobar),
+      infobar_type_(
+          static_cast<InfoBarIOS*>(infobar)->InfobarUIDelegate().infobarType),
+      has_badge_(
+          static_cast<InfoBarIOS*>(infobar)->InfobarUIDelegate().hasBadge) {}
+
+InfobarOverlayRequestConfig::~InfobarOverlayRequestConfig() = default;
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.mm b/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.mm
index 73026dd..50d43db 100644
--- a/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.mm
+++ b/ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.mm
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "components/infobars/core/infobar.h"
-#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay.h"
+#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
 #import "ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -32,5 +32,5 @@
 
 void SavePasswordInfobarBannerOverlayRequestConfig::CreateAuxilliaryData(
     base::SupportsUserData* user_data) {
-  InfobarOverlayData::CreateForUserData(user_data, infobar_);
+  InfobarOverlayRequestConfig::CreateForUserData(user_data, infobar_);
 }
diff --git a/ios/chrome/browser/overlays/public/overlay_callback_manager.h b/ios/chrome/browser/overlays/public/overlay_callback_manager.h
new file mode 100644
index 0000000..1fed74f8
--- /dev/null
+++ b/ios/chrome/browser/overlays/public/overlay_callback_manager.h
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_CALLBACK_MANAGER_H_
+#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_CALLBACK_MANAGER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h"
+#include "ios/chrome/browser/overlays/public/overlay_user_data.h"
+
+class OverlayResponse;
+
+// Completion callback for OverlayRequests.  If an overlay requires a completion
+// block to be executed after its UI is dismissed, OverlayPresenter clients can
+// provide a callback that uses the OverlayResponse provided to the request.
+// |response| may be null if no response has been provided.
+typedef base::OnceCallback<void(OverlayResponse* response)>
+    OverlayCompletionCallback;
+
+// Helper object owned by an OverlayRequest that is used to communicate overlay
+// UI interaction information back to the overlay's requester.  Supports
+// completion calllbacks, which are executed when the overlay is finished.
+class OverlayCallbackManager {
+ public:
+  OverlayCallbackManager() = default;
+  virtual ~OverlayCallbackManager() = default;
+
+  // The completion response object for the request whose callbacks are being
+  // managed by this object.  |response| is passed as the argument for
+  // completion callbacks when the overlay UI is finished or the request is
+  // cancelled.
+  virtual void SetCompletionResponse(
+      std::unique_ptr<OverlayResponse> response) = 0;
+  virtual OverlayResponse* GetCompletionResponse() const = 0;
+
+  // Adds a completion callback.  Provided callbacks are guaranteed to be
+  // executed once with the completion response when the overlay UI is finished
+  // or the request is cancelled.
+  virtual void AddCompletionCallback(OverlayCompletionCallback callback) = 0;
+
+  // Dispatches |response| to all callbacks that have been added for its
+  // info type.  Used to send user interaction information back to the overlay's
+  // requester for ongoing overlay UI.
+  virtual void DispatchResponse(std::unique_ptr<OverlayResponse> response) = 0;
+
+  // Adds |callback| to be executed for dispatched responses with InfoType.  The
+  // provided callbacks are not guaranteed to be called, as there is no
+  // guarantee that an InfoType response will be sent for the overlay.
+  template <class InfoType>
+  void AddDispatchCallback(OverlayDispatchCallback callback) {
+    DCHECK(!callback.is_null());
+    GetDispatchCallbackStorage()->AddDispatchCallback<InfoType>(callback);
+  }
+
+ protected:
+  // Returns the dispatch callback storage.
+  virtual OverlayDispatchCallbackStorage* GetDispatchCallbackStorage() = 0;
+};
+
+#endif  // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_CALLBACK_MANAGER_H_
diff --git a/ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h b/ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h
new file mode 100644
index 0000000..a706fd6
--- /dev/null
+++ b/ios/chrome/browser/overlays/public/overlay_dispatch_callback_storage.h
@@ -0,0 +1,90 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_DISPATCH_CALLBACK_STORAGE_H_
+#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_DISPATCH_CALLBACK_STORAGE_H_
+
+#include <map>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "ios/chrome/browser/overlays/public/overlay_response.h"
+
+// Callback for OverlayResponses dispatched for user interaction events
+// occurring in an ongoing overlay.
+typedef base::RepeatingCallback<void(OverlayResponse* response)>
+    OverlayDispatchCallback;
+
+// Storage object used to hold OverlayDispatchCallbacks and execute them for
+// dispatched responses.
+class OverlayDispatchCallbackStorage {
+ public:
+  OverlayDispatchCallbackStorage();
+  ~OverlayDispatchCallbackStorage();
+
+  // Adds |callback| to the storage to be executed whenever DispatchResponse()
+  // is called with an OverlayResponse created with InfoType.
+  template <class InfoType>
+  void AddDispatchCallback(OverlayDispatchCallback callback) {
+    DCHECK(!callback.is_null());
+    GetCallbackList<InfoType>()->AddCallback(std::move(callback));
+  }
+
+  // Executes the added callbacks for |response|.
+  void DispatchResponse(OverlayResponse* response);
+
+ protected:
+  // Helper object that stores OverlayDispatchCallbacks for OverlayResponses
+  // created with a specific info type.
+  class CallbackList {
+   public:
+    CallbackList();
+    virtual ~CallbackList();
+
+    // Adds the callback to the list.
+    void AddCallback(OverlayDispatchCallback callback);
+    // Executes the callbacks with |response| if it's supported.
+    void ExecuteCallbacks(OverlayResponse* response);
+
+   protected:
+    // Returns whether the callbacks in the list have been registered for
+    // |response|'s info type.
+    virtual bool ShouldExecuteForResponse(OverlayResponse* response) = 0;
+
+    // The callbacks stored in this list.
+    std::vector<OverlayDispatchCallback> callbacks_;
+  };
+
+  // Template used to create CallbackList instantiations for a specific info
+  // type.
+  template <class InfoType>
+  class CallbackListImpl : public CallbackList {
+   public:
+    CallbackListImpl() = default;
+    ~CallbackListImpl() override = default;
+
+   private:
+    // CallbackList:
+    bool ShouldExecuteForResponse(OverlayResponse* response) override {
+      return !!response->GetInfo<InfoType>();
+    }
+  };
+
+  // Returns the CallbackList for OverlayRequests created with InfoType,
+  // creating one if necessary.
+  template <class InfoType>
+  CallbackList* GetCallbackList() {
+    auto& callback_list = callback_lists_[InfoType::UserDataKey()];
+    if (!callback_list)
+      callback_list = std::make_unique<CallbackListImpl<InfoType>>();
+    return callback_list.get();
+  }
+
+  // Map storing the CallbackList under the user data key for each supported
+  // OverlayRequest info type.
+  std::map<const void*, std::unique_ptr<CallbackList>> callback_lists_;
+};
+
+#endif  // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_DISPATCH_CALLBACK_STORAGE_H_
diff --git a/ios/chrome/browser/overlays/public/overlay_request.h b/ios/chrome/browser/overlays/public/overlay_request.h
index 6c34fda..89409783 100644
--- a/ios/chrome/browser/overlays/public/overlay_request.h
+++ b/ios/chrome/browser/overlays/public/overlay_request.h
@@ -7,16 +7,9 @@
 
 #include <memory>
 
-#include "base/callback.h"
 #include "base/supports_user_data.h"
 
-class OverlayResponse;
-
-// Callback for OverlayRequests.  If an overlay requires a completion block to
-// be executed after its UI is dismissed, OverlayManager clients can provide a
-// callback that uses the OverlayResponse provided to the request.  |response|
-// may be null if no response has been provided.
-typedef base::OnceCallback<void(OverlayResponse* response)> OverlayCallback;
+class OverlayCallbackManager;
 
 // Model object used to track overlays requested for OverlayManager.
 class OverlayRequest {
@@ -47,17 +40,9 @@
     return ConfigType::FromUserData(data());
   }
 
-  // Setter for the response object for this request.
-  virtual void set_response(std::unique_ptr<OverlayResponse> response) = 0;
-  // The response for this request.  It is constructed with an
-  // OverlayResponseInfo containing user interaction information for the overlay
-  // UI resulting from this request.
-  virtual OverlayResponse* response() const = 0;
-
-  // Setter for the callback.  Provided callbacks are guaranteed to be executed,
-  // either upon dismissal of the request's corresponding overlay UI or upon
-  // cancellation of the request.
-  virtual void set_callback(OverlayCallback callback) = 0;
+  // Returns the request's callback controller, which can be used to communicate
+  // user interaction information back to the reqeuster.
+  virtual OverlayCallbackManager* GetCallbackManager() = 0;
 
  protected:
   OverlayRequest() = default;
diff --git a/ios/chrome/browser/sessions/BUILD.gn b/ios/chrome/browser/sessions/BUILD.gn
index f9943d2..17e3f66 100644
--- a/ios/chrome/browser/sessions/BUILD.gn
+++ b/ios/chrome/browser/sessions/BUILD.gn
@@ -28,12 +28,45 @@
     "//ios/chrome/browser/web_state_list",
     "//ios/public/provider/chrome/browser",
     "//ios/web",
+    "//ios/web/public/security",
+    "//ios/web/public/session",
     "//net",
     "//url",
   ]
   libs = [ "UIKit.framework" ]
 }
 
+source_set("restoration_observer") {
+  sources = [
+    "session_restoration_observer.h",
+  ]
+  deps = [
+    "//base",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
+source_set("restoration_agent") {
+  sources = [
+    "session_restoration_agent.h",
+    "session_restoration_agent.mm",
+  ]
+  deps = [
+    ":restoration_observer",
+    ":serialisation",
+    ":session_service",
+    "//components/favicon/ios",
+    "//ios/chrome/browser:chrome_url_constants",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/web",
+    "//ios/chrome/browser/web_state_list",
+    "//ios/chrome/browser/web_state_list/web_usage_enabler",
+    "//ios/web/public/security",
+    "//ios/web/public/session",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 source_set("session_service") {
   sources = [
     "session_ios_factory.h",
@@ -90,11 +123,14 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
+    "session_restoration_agent_unittest.mm",
     "session_service_ios_unittest.mm",
     "session_window_ios_unittest.mm",
   ]
   deps = [
     ":resources_unit_tests",
+    ":restoration_agent",
+    ":restoration_observer",
     ":serialisation",
     ":session_service",
     ":sessions",
@@ -103,10 +139,15 @@
     "//base/test:test_support",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state:test_support",
+    "//ios/chrome/browser/main",
+    "//ios/chrome/browser/web:web_internal",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/browser/web_state_list:test_support",
+    "//ios/chrome/browser/web_state_list/web_usage_enabler",
+    "//ios/chrome/test:test_support",
     "//ios/web",
     "//ios/web/public/session",
+    "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/ios/chrome/browser/sessions/session_restoration_agent.h b/ios/chrome/browser/sessions/session_restoration_agent.h
new file mode 100644
index 0000000..1f3cc0f
--- /dev/null
+++ b/ios/chrome/browser/sessions/session_restoration_agent.h
@@ -0,0 +1,68 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_AGENT_H_
+#define IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_AGENT_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+
+@class SessionWindowIOS;
+@class SessionIOSFactory;
+class SessionRestorationObserver;
+class WebStateList;
+@class SessionServiceIOS;
+
+namespace ios {
+class ChromeBrowserState;
+}
+
+// This class is responsible for handling requests of session restoration. It
+// can be observed via SessnRestorationObserver which it uses to notify
+// observers of session restoration events.
+class SessionRestorationAgent {
+ public:
+  explicit SessionRestorationAgent(SessionServiceIOS* session_service,
+                                   WebStateList* web_state_list,
+                                   ios::ChromeBrowserState* browser_state);
+
+  ~SessionRestorationAgent();
+
+  // Adds/Removes Observer to session restoration events.
+  void AddObserver(SessionRestorationObserver* observer);
+  void RemoveObserver(SessionRestorationObserver* observer);
+
+  // Restores the |window| (for example, after a crash). If there is only one ,
+  // tab showing the NTP, then this tab should be clobbered, otherwise, the tabs
+  // from the restored sessions should be added at the end of the current list
+  // of tabs. Returns YES if the single NTP tab is closed.
+  bool RestoreSessionWindow(SessionWindowIOS* window);
+
+  // Persists the current list of tabs to disk, either immediately or deferred
+  // based on the value of |immediately|.
+  void SaveSession(const bool immediately);
+
+ private:
+  // Returns true if the current session can be saved.
+  bool CanSaveSession();
+
+  // The service object which handles the actual saving of sessions.
+  SessionServiceIOS* session_service_;
+
+  // The list of web states to be saved.
+  WebStateList* web_state_list_;
+
+  base::ObserverList<SessionRestorationObserver, true> observers_;
+
+  ios::ChromeBrowserState* browser_state_;
+
+  // Session Factory used to create session data for saving.
+  SessionIOSFactory* session_ios_factory_;
+};
+
+#endif  // IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_AGENT_H_
diff --git a/ios/chrome/browser/sessions/session_restoration_agent.mm b/ios/chrome/browser/sessions/session_restoration_agent.mm
new file mode 100644
index 0000000..84a6d40
--- /dev/null
+++ b/ios/chrome/browser/sessions/session_restoration_agent.mm
@@ -0,0 +1,161 @@
+// 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 "ios/chrome/browser/sessions/session_restoration_agent.h"
+
+#include "base/strings/sys_string_conversions.h"
+#include "components/favicon/ios/web_favicon_driver.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#import "ios/chrome/browser/sessions/session_ios_factory.h"
+#include "ios/chrome/browser/sessions/session_restoration_observer.h"
+#import "ios/chrome/browser/sessions/session_service_ios.h"
+#import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/web_state_list/web_state_list_serialization.h"
+#import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h"
+#import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h"
+#include "ios/web/public/navigation/navigation_item.h"
+#import "ios/web/public/navigation/navigation_manager.h"
+#include "ios/web/public/security/certificate_policy_cache.h"
+#import "ios/web/public/session/serializable_user_data_manager.h"
+#include "ios/web/public/session/session_certificate_policy_cache.h"
+#import "ios/web/public/web_state.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+SessionRestorationAgent::SessionRestorationAgent(
+    SessionServiceIOS* session_service,
+    WebStateList* web_state_list,
+    ios::ChromeBrowserState* browser_state)
+    : session_service_(session_service),
+      web_state_list_(web_state_list),
+      browser_state_(browser_state),
+      session_ios_factory_(
+          [[SessionIOSFactory alloc] initWithWebStateList:web_state_list]) {}
+
+SessionRestorationAgent::~SessionRestorationAgent() {
+  // Disconnect the session factory object as it's not granteed that it will be
+  // released before it's referenced by the session service.
+  [session_ios_factory_ disconnect];
+}
+
+void SessionRestorationAgent::AddObserver(
+    SessionRestorationObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void SessionRestorationAgent::RemoveObserver(
+    SessionRestorationObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+bool SessionRestorationAgent::RestoreSessionWindow(SessionWindowIOS* window) {
+  if (!window.sessions.count)
+    return NO;
+
+  for (auto& observer : observers_) {
+    observer.WillStartSessionRestoration();
+  }
+
+  int old_count = web_state_list_->count();
+  DCHECK_GE(old_count, 0);
+
+  web_state_list_->PerformBatchOperation(base::BindOnce(^(
+      WebStateList* web_state_list) {
+    // Don't trigger the initial load for these restored WebStates since the
+    // number of WKWebViews is unbounded and may lead to an OOM crash.
+    WebStateListWebUsageEnabler* webUsageEnabler =
+        WebStateListWebUsageEnablerFactory::GetInstance()->GetForBrowserState(
+            browser_state_);
+    const bool wasTriggersInitialLoadSet =
+        webUsageEnabler->TriggersInitialLoad();
+    webUsageEnabler->SetTriggersInitialLoad(false);
+    web::WebState::CreateParams createParams(browser_state_);
+    DeserializeWebStateList(
+        web_state_list, window,
+        base::BindRepeating(&web::WebState::CreateWithStorageSession,
+                            createParams));
+    webUsageEnabler->SetTriggersInitialLoad(wasTriggersInitialLoadSet);
+  }));
+
+  DCHECK_GT(web_state_list_->count(), old_count);
+  int restored_count = web_state_list_->count() - old_count;
+  DCHECK_EQ(window.sessions.count, static_cast<NSUInteger>(restored_count));
+
+  scoped_refptr<web::CertificatePolicyCache> policy_cache =
+      web::BrowserState::GetCertificatePolicyCache(browser_state_);
+
+  std::vector<web::WebState*> restored_web_states;
+  restored_web_states.reserve(window.sessions.count);
+
+  for (int index = old_count; index < web_state_list_->count(); ++index) {
+    web::WebState* web_state = web_state_list_->GetWebStateAt(index);
+    web::NavigationItem* visible_item =
+        web_state->GetNavigationManager()->GetVisibleItem();
+
+    if (!(visible_item &&
+          visible_item->GetVirtualURL() == kChromeUINewTabURL)) {
+      PagePlaceholderTabHelper::FromWebState(web_state)
+          ->AddPlaceholderForNextNavigation();
+    }
+
+    if (visible_item && visible_item->GetVirtualURL().is_valid()) {
+      favicon::WebFaviconDriver::FromWebState(web_state)->FetchFavicon(
+          visible_item->GetVirtualURL(), /*is_same_document=*/false);
+    }
+
+    // Restore the CertificatePolicyCache (note that webState is invalid after
+    // passing it via move semantic to -initWithWebState:model:).
+    web_state->GetSessionCertificatePolicyCache()->UpdateCertificatePolicyCache(
+        policy_cache);
+
+    restored_web_states.push_back(web_state);
+  }
+
+  // If there was only one tab and it was the new tab page, clobber it.
+  BOOL closed_ntp_tab = NO;
+  if (old_count == 1) {
+    web::WebState* webState = web_state_list_->GetWebStateAt(0);
+    BOOL hasPendingLoad =
+        webState->GetNavigationManager()->GetPendingItem() != nullptr;
+    if (!hasPendingLoad &&
+        webState->GetLastCommittedURL() == kChromeUINewTabURL) {
+      web_state_list_->CloseWebStateAt(0, WebStateList::CLOSE_USER_ACTION);
+
+      closed_ntp_tab = YES;
+      old_count = 0;
+    }
+  }
+  for (auto& observer : observers_) {
+    observer.SessionRestorationFinished(restored_web_states);
+  }
+  return closed_ntp_tab;
+}
+
+void SessionRestorationAgent::SaveSession(bool immediately) {
+  if (!CanSaveSession())
+    return;
+
+  NSString* statePath =
+      base::SysUTF8ToNSString(browser_state_->GetStatePath().AsUTF8Unsafe());
+  [session_service_ saveSession:session_ios_factory_
+                      directory:statePath
+                    immediately:immediately];
+}
+
+bool SessionRestorationAgent::CanSaveSession() {
+  // A session requires an active browser state and web state list.
+  if (!browser_state_ || !web_state_list_)
+    return NO;
+  // Sessions where there's no active tab shouldn't be saved, unless the web
+  // state list is empty. This is a transitional state.
+  if (!web_state_list_->empty() && !web_state_list_->GetActiveWebState())
+    return NO;
+
+  return YES;
+}
diff --git a/ios/chrome/browser/sessions/session_restoration_agent_unittest.mm b/ios/chrome/browser/sessions/session_restoration_agent_unittest.mm
new file mode 100644
index 0000000..8b14957a
--- /dev/null
+++ b/ios/chrome/browser/sessions/session_restoration_agent_unittest.mm
@@ -0,0 +1,254 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <objc/runtime.h>
+
+#include "base/files/file_path.h"
+#include "base/run_loop.h"
+#include "base/strings/sys_string_conversions.h"
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#import "ios/chrome/browser/main/browser_web_state_list_delegate.h"
+#include "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
+#import "ios/chrome/browser/sessions/session_ios.h"
+#import "ios/chrome/browser/sessions/session_restoration_agent.h"
+#include "ios/chrome/browser/sessions/session_restoration_observer.h"
+#import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/sessions/test_session_service.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/web_state_list/web_state_list_delegate.h"
+#import "ios/chrome/browser/web_state_list/web_state_opener.h"
+#import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h"
+#import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h"
+#import "ios/web/public/navigation/navigation_manager.h"
+#include "ios/web/public/navigation/referrer.h"
+#import "ios/web/public/session/crw_session_storage.h"
+#import "ios/web/public/session/serializable_user_data_manager.h"
+#include "ios/web/public/test/web_task_environment.h"
+#include "ios/web/public/thread/web_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+const char kURL1[] = "https://www.some.url.com";
+const char kURL2[] = "https://www.some.url2.com";
+
+class TestRestorationObserver : public SessionRestorationObserver {
+ public:
+  bool restore_started() { return restore_started_; }
+  int restored_web_states_count() { return restored_web_states_count_; }
+
+ private:
+  void WillStartSessionRestoration() override { restore_started_ = true; }
+  void SessionRestorationFinished(
+      const std::vector<web::WebState*>& restored_web_states) override {
+    restored_web_states_count_ = restored_web_states.size();
+  }
+
+  bool restore_started_ = false;
+  int restored_web_states_count_ = -1;
+};
+
+class SessionRestorationAgentTest : public PlatformTest {
+ public:
+  SessionRestorationAgentTest()
+      : web_state_list_delegate_(
+            std::make_unique<BrowserWebStateListDelegate>()),
+        web_state_list_(
+            std::make_unique<WebStateList>(web_state_list_delegate_.get())),
+        test_session_service_([[TestSessionService alloc] init]) {
+    DCHECK_CURRENTLY_ON(web::WebThread::UI);
+
+    TestChromeBrowserState::Builder test_cbs_builder;
+    chrome_browser_state_ = test_cbs_builder.Build();
+
+    // Web usage is disabled during these tests.
+    web_usage_enabler_ =
+        WebStateListWebUsageEnablerFactory::GetInstance()->GetForBrowserState(
+            chrome_browser_state_.get());
+    web_usage_enabler_->SetWebUsageEnabled(false);
+
+    web_usage_enabler_->SetWebStateList(web_state_list_.get());
+    test_session_service_ = [[TestSessionService alloc] init];
+    session_restoration_agent_ = std::make_unique<SessionRestorationAgent>(
+        test_session_service_, web_state_list_.get(),
+        chrome_browser_state_.get());
+  }
+
+  ~SessionRestorationAgentTest() override = default;
+
+  void TearDown() override {
+    web_usage_enabler_->SetWebStateList(nullptr);
+    @autoreleasepool {
+      web_state_list_->CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS);
+    }
+    PlatformTest::TearDown();
+  }
+
+ protected:
+  // Creates a session window with |sessions_count| and mark the
+  // |selected_index| entry as selected.
+  SessionWindowIOS* CreateSessionWindow(int sessions_count,
+                                        int selected_index) {
+    NSMutableArray<CRWSessionStorage*>* sessions = [NSMutableArray array];
+    for (int i = 0; i < sessions_count; i++) {
+      CRWSessionStorage* session_storage = [[CRWSessionStorage alloc] init];
+      session_storage.lastCommittedItemIndex = -1;
+      [sessions addObject:session_storage];
+    }
+    return [[SessionWindowIOS alloc] initWithSessions:sessions
+                                        selectedIndex:selected_index];
+  }
+
+  // Creates a WebState with the given parameters and insert it in the
+  // |web_state_list_|.
+  web::WebState* InsertNewWebState(const GURL& url,
+                                   web::WebState* parent,
+                                   int index,
+                                   bool background) {
+    web::NavigationManager::WebLoadParams load_params(url);
+    load_params.transition_type = ui::PAGE_TRANSITION_TYPED;
+
+    web::WebState::CreateParams create_params(chrome_browser_state_.get());
+    create_params.created_with_opener = false;
+
+    std::unique_ptr<web::WebState> web_state =
+        web::WebState::Create(create_params);
+    web_state->GetNavigationManager()->LoadURLWithParams(load_params);
+
+    int insertion_flags = WebStateList::INSERT_FORCE_INDEX;
+    if (!background)
+      insertion_flags |= WebStateList::INSERT_ACTIVATE;
+    web_state_list_->InsertWebState(index, std::move(web_state),
+                                    insertion_flags, WebStateOpener(parent));
+    return web_state_list_->GetWebStateAt(index);
+  }
+
+  web::WebTaskEnvironment task_environment_;
+  std::unique_ptr<WebStateListDelegate> web_state_list_delegate_;
+  std::unique_ptr<WebStateList> web_state_list_;
+  std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
+  WebStateListWebUsageEnabler* web_usage_enabler_;
+  TestSessionService* test_session_service_;
+  std::unique_ptr<SessionRestorationAgent> session_restoration_agent_;
+};
+
+// Tests that restoring a session works correctly on empty WebStateList.
+TEST_F(SessionRestorationAgentTest, RestoreSessionOnEmptyWebStateList) {
+  SessionWindowIOS* window(
+      CreateSessionWindow(/*sessions_count=*/5, /*selected_index=*/1));
+  session_restoration_agent_->RestoreSessionWindow(window);
+
+  ASSERT_EQ(5, web_state_list_->count());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(1),
+            web_state_list_->GetActiveWebState());
+}
+
+// Tests that restoring a session works correctly on non empty WebStatelist.
+TEST_F(SessionRestorationAgentTest, RestoreSessionWithNonEmptyWebStateList) {
+  web::WebState* web_state = InsertNewWebState(
+      GURL(kURL1), /*parent=*/nullptr, /*index=*/0, /*background=*/false);
+
+  SessionWindowIOS* window(
+      CreateSessionWindow(/*sessions_count=*/3, /*selected_index=*/2));
+  session_restoration_agent_->RestoreSessionWindow(window);
+
+  ASSERT_EQ(4, web_state_list_->count());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(3),
+            web_state_list_->GetActiveWebState());
+  EXPECT_EQ(web_state, web_state_list_->GetWebStateAt(0));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(1));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(2));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(3));
+}
+
+// Tests that saving a non-empty session, then saving an empty session, then
+// restoring, restores zero web states, and not the non-empty session.
+TEST_F(SessionRestorationAgentTest, SaveAndRestoreEmptySession) {
+  InsertNewWebState(GURL(kURL1), /*parent=*/nullptr, /*index=*/0,
+                    /*background=*/false);
+
+  [test_session_service_ setPerformIO:YES];
+  session_restoration_agent_->SaveSession(/*immediately=*/true);
+  [test_session_service_ setPerformIO:NO];
+
+  // Session should be saved, now remove the webstate.
+  web_state_list_->CloseWebStateAt(0, WebStateList::CLOSE_NO_FLAGS);
+  [test_session_service_ setPerformIO:YES];
+  session_restoration_agent_->SaveSession(/*immediately=*/true);
+  [test_session_service_ setPerformIO:NO];
+
+  // Restore, expect that there are no sessions.
+  NSString* state_path = base::SysUTF8ToNSString(
+      chrome_browser_state_->GetStatePath().AsUTF8Unsafe());
+  SessionIOS* session =
+      [test_session_service_ loadSessionFromDirectory:state_path];
+  ASSERT_EQ(1u, session.sessionWindows.count);
+  SessionWindowIOS* session_window = session.sessionWindows[0];
+  session_restoration_agent_->RestoreSessionWindow(session_window);
+
+  EXPECT_EQ(0, web_state_list_->count());
+}
+
+// Tests that saving a session with web states, then clearing the WebStatelist
+// and then restoring the session will restore the web states correctly.
+TEST_F(SessionRestorationAgentTest, SaveAndRestoreSession) {
+  web::WebState* web_state = InsertNewWebState(
+      GURL(kURL1), /*parent=*/nullptr, /*index=*/0, /*background=*/false);
+  InsertNewWebState(GURL(kURL1), web_state, /*index=*/1, /*background=*/false);
+  InsertNewWebState(GURL(kURL2), web_state, /*index=*/0, /*background=*/false);
+
+  ASSERT_EQ(3, web_state_list_->count());
+  web_state_list_->ActivateWebStateAt(1);
+
+  // Force state to flush to disk on the main thread so it can be immediately
+  // tested below.
+  [test_session_service_ setPerformIO:YES];
+  session_restoration_agent_->SaveSession(/*immediately=*/true);
+  [test_session_service_ setPerformIO:NO];
+  // close all the webStates
+  web_state_list_->CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS);
+
+  NSString* state_path = base::SysUTF8ToNSString(
+      chrome_browser_state_->GetStatePath().AsUTF8Unsafe());
+  SessionIOS* session =
+      [test_session_service_ loadSessionFromDirectory:state_path];
+  ASSERT_EQ(1u, session.sessionWindows.count);
+  SessionWindowIOS* session_window = session.sessionWindows[0];
+
+  // Restore from saved session.
+  session_restoration_agent_->RestoreSessionWindow(session_window);
+
+  EXPECT_EQ(3, web_state_list_->count());
+
+  EXPECT_EQ(web_state_list_->GetWebStateAt(1),
+            web_state_list_->GetActiveWebState());
+}
+
+// Tests that SessionRestorationObserver methods are called when sessions is
+// restored.
+TEST_F(SessionRestorationAgentTest, ObserverCalledWithRestore) {
+  InsertNewWebState(GURL(kURL1), /*parent=*/nullptr, /*index=*/0,
+                    /*background=*/false);
+
+  TestRestorationObserver observer;
+  session_restoration_agent_->AddObserver(&observer);
+
+  SessionWindowIOS* window(
+      CreateSessionWindow(/*sessions_count=*/3, /*selected_index=*/2));
+  session_restoration_agent_->RestoreSessionWindow(window);
+  ASSERT_EQ(4, web_state_list_->count());
+
+  EXPECT_TRUE(observer.restore_started());
+  EXPECT_EQ(observer.restored_web_states_count(), 3);
+  session_restoration_agent_->RemoveObserver(&observer);
+}
+
+}  // anonymous namespace
diff --git a/ios/chrome/browser/sessions/session_restoration_observer.h b/ios/chrome/browser/sessions/session_restoration_observer.h
new file mode 100644
index 0000000..55fb50f
--- /dev/null
+++ b/ios/chrome/browser/sessions/session_restoration_observer.h
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_OBSERVER_H_
+#define IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_OBSERVER_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list_types.h"
+
+namespace web {
+class WebState;
+}  // namespace web
+
+// Observer interface for objects interested in Session restoration events.
+class SessionRestorationObserver : public base::CheckedObserver {
+ public:
+  // Invoked before the session restoration starts.
+  virtual void WillStartSessionRestoration() {}
+
+  // Invoked when the session restoration is finished.
+  virtual void SessionRestorationFinished(
+      const std::vector<web::WebState*>& restored_web_states) {}
+
+ protected:
+  SessionRestorationObserver() = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SessionRestorationObserver);
+};
+
+#endif  // IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_OBSERVER_H_
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn
index a93ac3b..f95d5fc 100644
--- a/ios/chrome/browser/tabs/BUILD.gn
+++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -65,6 +65,8 @@
     "//ios/chrome/browser/browser_state_metrics",
     "//ios/chrome/browser/complex_tasks",
     "//ios/chrome/browser/crash_report",
+    "//ios/chrome/browser/crash_report/breadcrumbs",
+    "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags",
     "//ios/chrome/browser/download",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/find_in_page",
@@ -86,6 +88,7 @@
     "//ios/chrome/browser/reading_list",
     "//ios/chrome/browser/search_engines",
     "//ios/chrome/browser/sessions",
+    "//ios/chrome/browser/sessions:restoration_agent",
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/chrome/browser/sessions:session_service",
     "//ios/chrome/browser/snapshots",
@@ -141,6 +144,8 @@
     "//ios/chrome/browser/history:tab_helper",
     "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/main",
+    "//ios/chrome/browser/main",
+    "//ios/chrome/browser/main:test_support",
     "//ios/chrome/browser/ntp",
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/sessions:serialisation",
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm
index fddb047..e053da5 100644
--- a/ios/chrome/browser/tabs/tab_helper_util.mm
+++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -20,6 +20,8 @@
 #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/complex_tasks/ios_task_tab_helper.h"
+#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h"
+#import "ios/chrome/browser/crash_report/breadcrumbs/features.h"
 #import "ios/chrome/browser/download/ar_quick_look_tab_helper.h"
 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
 #import "ios/chrome/browser/find_in_page/find_tab_helper.h"
@@ -105,6 +107,10 @@
     FontSizeTabHelper::CreateForWebState(web_state);
   }
 
+  if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) {
+    BreadcrumbManagerTabHelper::CreateForWebState(web_state);
+  }
+
   ImageFetchTabHelper::CreateForWebState(web_state);
 
   OpenInTabHelper::CreateForWebState(web_state);
diff --git a/ios/chrome/browser/tabs/tab_model.h b/ios/chrome/browser/tabs/tab_model.h
index db4fac5b..331d824a 100644
--- a/ios/chrome/browser/tabs/tab_model.h
+++ b/ios/chrome/browser/tabs/tab_model.h
@@ -26,20 +26,6 @@
 class ChromeBrowserState;
 }
 
-namespace web {
-struct Referrer;
-class WebState;
-}
-
-namespace TabModelConstants {
-
-// Position the tab automatically. This value is used as index parameter in
-// methods that require an index when the caller doesn't have a preference
-// on the position where the tab will be open.
-NSUInteger const kTabPositionAutomatically = NSNotFound;
-
-}  // namespace TabModelConstants
-
 // A model of a tab "strip". Although the UI representation may not be a
 // traditional strip at all, tabs are still accessed via an integral index.
 // The model knows about the currently selected tab in order to maintain
@@ -84,35 +70,6 @@
 
 - (instancetype)init NS_UNAVAILABLE;
 
-// Add/modify tabs.
-
-// Opens a tab at the specified URL. For certain transition types, will consult
-// the order controller and thus may only use |index| as a hint.
-// |parentWebState| may be nil if there is no parent associated with this new
-// tab. |openedByDOM| is YES if the page was opened by DOM. The |index|
-// parameter can be set to TabModelConstants::kTabPositionAutomatically if the
-// caller doesn't have a preference for the position of the tab.
-- (web::WebState*)insertWebStateWithURL:(const GURL&)URL
-                               referrer:(const web::Referrer&)referrer
-                             transition:(ui::PageTransition)transition
-                                 opener:(web::WebState*)parentWebState
-                            openedByDOM:(BOOL)openedByDOM
-                                atIndex:(NSUInteger)index
-                           inBackground:(BOOL)inBackground;
-
-// As above, but using WebLoadParams to specify various optional parameters.
-- (web::WebState*)insertWebStateWithLoadParams:
-                      (const web::NavigationManager::WebLoadParams&)params
-                                        opener:(web::WebState*)parentWebState
-                                   openedByDOM:(BOOL)openedByDOM
-                                       atIndex:(NSUInteger)index
-                                  inBackground:(BOOL)inBackground;
-
-// Opens a new blank tab in response to DOM window opening action. Creates a web
-// state with empty navigation manager.
-- (web::WebState*)insertOpenByDOMWebStateWithOpener:
-    (web::WebState*)parentWebState;
-
 // Closes the tab at the given |index|. |index| must be valid.
 - (void)closeTabAtIndex:(NSUInteger)index;
 
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
index 2c27971..6ea42e09 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -18,7 +18,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/task/post_task.h"
-#include "components/favicon/ios/web_favicon_driver.h"
 #include "components/navigation_metrics/navigation_metrics.h"
 #include "components/profile_metrics/browser_profile_type.h"
 #include "components/sessions/core/serialized_navigation_entry.h"
@@ -35,8 +34,7 @@
 #import "ios/chrome/browser/metrics/tab_usage_recorder.h"
 #import "ios/chrome/browser/prerender/prerender_service_factory.h"
 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
-#import "ios/chrome/browser/sessions/session_ios.h"
-#import "ios/chrome/browser/sessions/session_ios_factory.h"
+#import "ios/chrome/browser/sessions/session_restoration_agent.h"
 #import "ios/chrome/browser/sessions/session_service_ios.h"
 #import "ios/chrome/browser/sessions/session_window_ios.h"
 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
@@ -46,7 +44,6 @@
 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h"
 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
 #import "ios/chrome/browser/tabs/tab_parenting_observer.h"
-#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_metrics_observer.h"
@@ -60,7 +57,6 @@
 #include "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/security/certificate_policy_cache.h"
-#import "ios/web/public/session/serializable_user_data_manager.h"
 #include "ios/web/public/session/session_certificate_policy_cache.h"
 #include "ios/web/public/thread/web_task_traits.h"
 #include "ios/web/public/thread/web_thread.h"
@@ -236,10 +232,9 @@
 
   // Backs up property with the same name.
   std::unique_ptr<TabUsageRecorder> _tabUsageRecorder;
-  // Saves session's state.
-  SessionServiceIOS* _sessionService;
-  // Session Factory used to create session data for saving.
-  SessionIOSFactory* _sessionFactory;
+
+  // Used to handle session restoration.
+  std::unique_ptr<SessionRestorationAgent> _sessionRestorationAgent;
 
   // Used to ensure thread-safety of the certificate policy management code.
   base::CancelableTaskTracker _clearPoliciesTaskTracker;
@@ -297,6 +292,11 @@
 
     _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self);
 
+    // There must be a valid session service defined to consume session windows.
+    DCHECK(service);
+    _sessionRestorationAgent = std::make_unique<SessionRestorationAgent>(
+        service, _webStateList, _browserState);
+
     // Normal browser states are the only ones to get tab restore. Tab sync
     // handles incognito browser states by filtering on profile, so it's
     // important to the backend code to always have a sync window delegate.
@@ -305,10 +305,9 @@
       _tabUsageRecorder = std::make_unique<TabUsageRecorder>(
           _webStateList,
           PrerenderServiceFactory::GetForBrowserState(browserState));
+      _sessionRestorationAgent->AddObserver(_tabUsageRecorder.get());
     }
 
-    _sessionFactory =
-        [[SessionIOSFactory alloc] initWithWebStateList:_webStateList];
     std::unique_ptr<TabModelSyncedWindowDelegate> syncedWindowDelegate =
         std::make_unique<TabModelSyncedWindowDelegate>(_webStateList);
 
@@ -317,10 +316,6 @@
     _syncedWindowDelegate = syncedWindowDelegate.get();
     _webStateListObservers.push_back(std::move(syncedWindowDelegate));
 
-    // There must be a valid session service defined to consume session windows.
-    DCHECK(service);
-    _sessionService = service;
-
     NSMutableArray<id<WebStateListObserving>>* retainedWebStateListObservers =
         [[NSMutableArray alloc] init];
 
@@ -350,6 +345,7 @@
     auto webStateListMetricsObserver =
         std::make_unique<WebStateListMetricsObserver>();
     _webStateListMetricsObserver = webStateListMetricsObserver.get();
+    _sessionRestorationAgent->AddObserver(_webStateListMetricsObserver);
     _webStateListObservers.push_back(std::move(webStateListMetricsObserver));
 
     for (const auto& webStateListObserver : _webStateListObservers)
@@ -375,78 +371,6 @@
   return self;
 }
 
-- (web::WebState*)insertWebStateWithURL:(const GURL&)URL
-                               referrer:(const web::Referrer&)referrer
-                             transition:(ui::PageTransition)transition
-                                 opener:(web::WebState*)parentWebState
-                            openedByDOM:(BOOL)openedByDOM
-                                atIndex:(NSUInteger)index
-                           inBackground:(BOOL)inBackground {
-  web::NavigationManager::WebLoadParams params(URL);
-  params.referrer = referrer;
-  params.transition_type = transition;
-  return [self insertWebStateWithLoadParams:params
-                                     opener:parentWebState
-                                openedByDOM:openedByDOM
-                                    atIndex:index
-                               inBackground:inBackground];
-}
-
-- (web::WebState*)insertOpenByDOMWebStateWithOpener:
-    (web::WebState*)openerWebState {
-  DCHECK(_browserState);
-  web::WebState::CreateParams createParams(_browserState);
-  createParams.created_with_opener = YES;
-  std::unique_ptr<web::WebState> webState = web::WebState::Create(createParams);
-
-  int insertionFlags =
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE;
-  int insertedIndex = _webStateList->InsertWebState(
-      _webStateList->count(), std::move(webState), insertionFlags,
-      WebStateOpener(openerWebState));
-
-  return _webStateList->GetWebStateAt(insertedIndex);
-}
-
-- (web::WebState*)insertWebStateWithLoadParams:
-                      (const web::NavigationManager::WebLoadParams&)loadParams
-                                        opener:(web::WebState*)parentWebState
-                                   openedByDOM:(BOOL)openedByDOM
-                                       atIndex:(NSUInteger)index
-                                  inBackground:(BOOL)inBackground {
-  DCHECK(_browserState);
-  DCHECK(index == TabModelConstants::kTabPositionAutomatically ||
-         index <= self.count);
-
-  int insertionIndex = WebStateList::kInvalidIndex;
-  int insertionFlags = WebStateList::INSERT_NO_FLAGS;
-  if (index != TabModelConstants::kTabPositionAutomatically) {
-    DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
-    insertionIndex = static_cast<int>(index);
-    insertionFlags |= WebStateList::INSERT_FORCE_INDEX;
-  } else if (!ui::PageTransitionCoreTypeIs(loadParams.transition_type,
-                                           ui::PAGE_TRANSITION_LINK)) {
-    insertionIndex = _webStateList->count();
-    insertionFlags |= WebStateList::INSERT_FORCE_INDEX;
-  }
-
-  if (!inBackground) {
-    insertionFlags |= WebStateList::INSERT_ACTIVATE;
-  }
-
-  web::WebState::CreateParams createParams(self.browserState);
-  createParams.created_with_opener = openedByDOM;
-
-  std::unique_ptr<web::WebState> webState = web::WebState::Create(createParams);
-  webState->GetNavigationManager()->LoadURLWithParams(loadParams);
-
-  insertionIndex = _webStateList->InsertWebState(
-      insertionIndex, std::move(webState), insertionFlags,
-      WebStateOpener(parentWebState));
-
-  return _webStateList->GetWebStateAt(insertionIndex);
-}
-
 - (void)closeTabAtIndex:(NSUInteger)index {
   DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
   _webStateList->CloseWebStateAt(static_cast<int>(index),
@@ -473,12 +397,15 @@
 - (void)disconnect {
   if (!_browserState)
     return;
-  // Disconnect the session factory object as it's not granteed that it will be
-  // released before it's referenced by the session service.
-  [_sessionFactory disconnect];
-  _sessionFactory = nil;
+
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   TabModelList::UnregisterTabModelFromChromeBrowserState(_browserState, self);
+
+  _sessionRestorationAgent->RemoveObserver(_webStateListMetricsObserver);
+  if (_tabUsageRecorder)
+    _sessionRestorationAgent->RemoveObserver(_tabUsageRecorder.get());
+
+  _sessionRestorationAgent.reset();
   _browserState = nullptr;
 
   // Clear weak pointer to observers before destroying them.
@@ -509,30 +436,9 @@
 #pragma mark - SessionWindowRestoring(public)
 
 - (void)saveSessionImmediately:(BOOL)immediately {
-  if (![self canSaveCurrentSession])
+  if (!_sessionRestorationAgent)
     return;
-
-  NSString* statePath =
-      base::SysUTF8ToNSString(_browserState->GetStatePath().AsUTF8Unsafe());
-
-  [_sessionService saveSession:_sessionFactory
-                     directory:statePath
-                   immediately:immediately];
-}
-
-#pragma mark - Private methods
-
-// YES if the current session can be saved.
-- (BOOL)canSaveCurrentSession {
-  // A session requires an active browser state and web state list.
-  if (!_browserState || !_webStateList)
-    return NO;
-  // Sessions where there's no active tab shouldn't be saved, unless the web
-  // state list is empty. This is a transitional state.
-  if (!_webStateList->empty() && !_webStateList->GetActiveWebState())
-    return NO;
-
-  return YES;
+  _sessionRestorationAgent->SaveSession(immediately);
 }
 
 - (BOOL)isWebUsageEnabled {
@@ -556,93 +462,7 @@
     _restoringSession = NO;
   }));
 
-  if (!window.sessions.count)
-    return NO;
-  // TODO(crbug.com/1010164): Don't call |WillStartSessionRestoration| directly
-  // from WebStateListMetricsObserver class. Instead use
-  // sessionRestorationObserver.
-  _webStateListMetricsObserver->WillStartSessionRestoration();
-
-  int oldCount = _webStateList->count();
-  DCHECK_GE(oldCount, 0);
-
-  _webStateList->PerformBatchOperation(
-      base::BindOnce(^(WebStateList* web_state_list) {
-        // Don't trigger the initial load for these restored WebStates since the
-        // number of WKWebViews is unbounded and may lead to an OOM crash.
-        WebStateListWebUsageEnabler* webUsageEnabler =
-            WebStateListWebUsageEnablerFactory::GetInstance()
-                ->GetForBrowserState(_browserState);
-        const bool wasTriggersInitialLoadSet =
-            webUsageEnabler->TriggersInitialLoad();
-        webUsageEnabler->SetTriggersInitialLoad(false);
-        web::WebState::CreateParams createParams(_browserState);
-        DeserializeWebStateList(
-            web_state_list, window,
-            base::BindRepeating(&web::WebState::CreateWithStorageSession,
-                                createParams));
-        webUsageEnabler->SetTriggersInitialLoad(wasTriggersInitialLoadSet);
-      }));
-
-  DCHECK_GT(_webStateList->count(), oldCount);
-  int restoredCount = _webStateList->count() - oldCount;
-  DCHECK_EQ(window.sessions.count, static_cast<NSUInteger>(restoredCount));
-
-  scoped_refptr<web::CertificatePolicyCache> policyCache =
-      web::BrowserState::GetCertificatePolicyCache(_browserState);
-
-  std::vector<web::WebState*> restoredWebStates;
-  if (_tabUsageRecorder)
-    restoredWebStates.reserve(window.sessions.count);
-
-  for (int index = oldCount; index < _webStateList->count(); ++index) {
-    web::WebState* webState = _webStateList->GetWebStateAt(index);
-    web::NavigationItem* visible_item =
-        webState->GetNavigationManager()->GetVisibleItem();
-
-    if (!(visible_item &&
-          visible_item->GetVirtualURL() == kChromeUINewTabURL)) {
-      PagePlaceholderTabHelper::FromWebState(webState)
-          ->AddPlaceholderForNextNavigation();
-    }
-
-    if (visible_item && visible_item->GetVirtualURL().is_valid()) {
-      favicon::WebFaviconDriver::FromWebState(webState)->FetchFavicon(
-          visible_item->GetVirtualURL(), /*is_same_document=*/false);
-    }
-
-    // Restore the CertificatePolicyCache (note that webState is invalid after
-    // passing it via move semantic to -initWithWebState:model:).
-    UpdateCertificatePolicyCacheFromWebState(policyCache, webState);
-
-    if (_tabUsageRecorder)
-      restoredWebStates.push_back(webState);
-  }
-
-  // If there was only one tab and it was the new tab page, clobber it.
-  BOOL closedNTPTab = NO;
-  if (oldCount == 1) {
-    web::WebState* webState = _webStateList->GetWebStateAt(0);
-    BOOL hasPendingLoad =
-        webState->GetNavigationManager()->GetPendingItem() != nullptr;
-    if (!hasPendingLoad &&
-        webState->GetLastCommittedURL() == kChromeUINewTabURL) {
-      _webStateList->CloseWebStateAt(0, WebStateList::CLOSE_USER_ACTION);
-
-      closedNTPTab = YES;
-      oldCount = 0;
-    }
-  }
-  if (_tabUsageRecorder) {
-    _tabUsageRecorder->InitialRestoredTabs(_webStateList->GetActiveWebState(),
-                                           restoredWebStates);
-  }
-  // TODO(crbug.com/1010164): Don't call |SessionRestorationFinished| directly
-  // from WebStateListMetricsObserver class. Instead use
-  // SessionRestorationObserver.
-  _webStateListMetricsObserver->SessionRestorationFinished();
-
-  return closedNTPTab;
+  return _sessionRestorationAgent->RestoreSessionWindow(window);
 }
 
 #pragma mark - Notification Handlers
diff --git a/ios/chrome/browser/tabs/tab_model_unittest.mm b/ios/chrome/browser/tabs/tab_model_unittest.mm
index 3386048..65c9361 100644
--- a/ios/chrome/browser/tabs/tab_model_unittest.mm
+++ b/ios/chrome/browser/tabs/tab_model_unittest.mm
@@ -12,6 +12,7 @@
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/main/browser_web_state_list_delegate.h"
+#import "ios/chrome/browser/main/test_browser.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h"
 #include "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
@@ -21,6 +22,7 @@
 #import "ios/chrome/browser/tabs/tab_helper_util.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #import "ios/chrome/browser/web/chrome_web_client.h"
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_delegate.h"
 #import "ios/chrome/browser/web_state_list/web_state_opener.h"
@@ -68,6 +70,8 @@
     TestChromeBrowserState::Builder test_cbs_builder;
     chrome_browser_state_ = test_cbs_builder.Build();
 
+    browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get(),
+                                             web_state_list_.get());
     // Web usage is disabled during these tests.
     web_usage_enabler_ =
         WebStateListWebUsageEnablerFactory::GetInstance()->GetForBrowserState(
@@ -76,6 +80,9 @@
 
     session_window_ = [[SessionWindowIOS alloc] init];
 
+    TabInsertionBrowserAgent::CreateForBrowser(browser_.get());
+    agent_ = TabInsertionBrowserAgent::FromBrowser(browser_.get());
+
     // Create tab model with just a dummy session service so the async state
     // saving doesn't trigger unless actually wanted.
     SetTabModel(CreateTabModel([[TestSessionService alloc] init], nil));
@@ -98,7 +105,7 @@
     }
 
     tab_model_ = tab_model;
-    web_usage_enabler_->SetWebStateList(tab_model_.webStateList);
+    web_usage_enabler_->SetWebStateList(web_state_list_.get());
   }
 
   TabModel* CreateTabModel(SessionServiceIOS* session_service,
@@ -112,6 +119,19 @@
     return tab_model;
   }
 
+  const web::NavigationManager::WebLoadParams Params(GURL url) {
+    return Params(url, ui::PAGE_TRANSITION_TYPED);
+  }
+
+  const web::NavigationManager::WebLoadParams Params(
+      GURL url,
+      ui::PageTransition transition) {
+    web::NavigationManager::WebLoadParams loadParams(url);
+    loadParams.referrer = web::Referrer();
+    loadParams.transition_type = transition;
+    return loadParams;
+  }
+
  protected:
   // Creates a session window with entries named "restored window 1",
   // "restored window 2" and "restored window 3" and the second entry
@@ -130,250 +150,124 @@
   IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_;
   web::ScopedTestingWebClient web_client_;
   std::unique_ptr<WebStateListDelegate> web_state_list_delegate_;
+
   std::unique_ptr<WebStateList> web_state_list_;
+  std::unique_ptr<Browser> browser_;
   SessionWindowIOS* session_window_;
   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
+  TabInsertionBrowserAgent* agent_;
   WebStateListWebUsageEnabler* web_usage_enabler_;
   TabModel* tab_model_;
 };
 
 TEST_F(TabModelTest, IsEmpty) {
-  EXPECT_EQ([tab_model_ count], 0U);
+  EXPECT_EQ(web_state_list_->count(), 0);
   EXPECT_TRUE([tab_model_ isEmpty]);
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:0
-                       inBackground:NO];
-  ASSERT_EQ(1U, [tab_model_ count]);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/0,
+                         /*in_background=*/false);
+  ASSERT_EQ(1, web_state_list_->count());
   EXPECT_FALSE([tab_model_ isEmpty]);
 }
 
-TEST_F(TabModelTest, InsertUrlSingle) {
-  web::WebState* web_state =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
-  ASSERT_EQ(1U, [tab_model_ count]);
-  EXPECT_EQ(web_state, tab_model_.webStateList->GetWebStateAt(0));
-}
-
-TEST_F(TabModelTest, BrowserStateDestroyedMultiple) {
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:0
-                       inBackground:NO];
-  [tab_model_ disconnect];
-  [tab_model_ disconnect];
-}
-
-TEST_F(TabModelTest, InsertUrlMultiple) {
-  web::WebState* web_state0 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
-  web::WebState* web_state1 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
-  web::WebState* web_state2 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:1
-                           inBackground:NO];
-
-  ASSERT_EQ(3U, [tab_model_ count]);
-  EXPECT_EQ(web_state1, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state2, tab_model_.webStateList->GetWebStateAt(1));
-  EXPECT_EQ(web_state0, tab_model_.webStateList->GetWebStateAt(2));
-}
-
-TEST_F(TabModelTest, AppendUrlSingle) {
-  web::WebState* web_state =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  ASSERT_EQ(1U, [tab_model_ count]);
-  EXPECT_EQ(web_state, tab_model_.webStateList->GetWebStateAt(0));
-}
-
-TEST_F(TabModelTest, AppendUrlMultiple) {
-  web::WebState* web_state0 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  web::WebState* web_state1 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  web::WebState* web_state2 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-
-  ASSERT_EQ(3U, [tab_model_ count]);
-  EXPECT_EQ(web_state0, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state1, tab_model_.webStateList->GetWebStateAt(1));
-  EXPECT_EQ(web_state2, tab_model_.webStateList->GetWebStateAt(2));
-}
-
 TEST_F(TabModelTest, CloseTabAtIndexBeginning) {
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
   web::WebState* web_state1 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
   web::WebState* web_state2 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
   [tab_model_ closeTabAtIndex:0];
 
-  ASSERT_EQ(2U, [tab_model_ count]);
-  EXPECT_EQ(web_state1, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state2, tab_model_.webStateList->GetWebStateAt(1));
+  ASSERT_EQ(2, web_state_list_->count());
+  EXPECT_EQ(web_state1, web_state_list_->GetWebStateAt(0));
+  EXPECT_EQ(web_state2, web_state_list_->GetWebStateAt(1));
 }
 
 TEST_F(TabModelTest, CloseTabAtIndexMiddle) {
   web::WebState* web_state0 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
   web::WebState* web_state2 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
 
   [tab_model_ closeTabAtIndex:1];
 
-  ASSERT_EQ(2U, [tab_model_ count]);
-  EXPECT_EQ(web_state0, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state2, tab_model_.webStateList->GetWebStateAt(1));
+  ASSERT_EQ(2, web_state_list_->count());
+  EXPECT_EQ(web_state0, web_state_list_->GetWebStateAt(0));
+  EXPECT_EQ(web_state2, web_state_list_->GetWebStateAt(1));
 }
 
 TEST_F(TabModelTest, CloseTabAtIndexLast) {
   web::WebState* web_state0 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
   web::WebState* web_state1 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
 
   [tab_model_ closeTabAtIndex:2];
 
-  ASSERT_EQ(2U, [tab_model_ count]);
-  EXPECT_EQ(web_state0, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state1, tab_model_.webStateList->GetWebStateAt(1));
+  ASSERT_EQ(2, web_state_list_->count());
+  EXPECT_EQ(web_state0, web_state_list_->GetWebStateAt(0));
+  EXPECT_EQ(web_state1, web_state_list_->GetWebStateAt(1));
 }
 
 TEST_F(TabModelTest, CloseTabAtIndexOnlyOne) {
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
 
   [tab_model_ closeTabAtIndex:0];
-
-  EXPECT_EQ(0U, [tab_model_ count]);
+  EXPECT_EQ(0, web_state_list_->count());
 }
 
 // TODO(crbug.com/888674): migrate this to EG test so it can be tested with
 // WKBasedNavigationManager.
 TEST_F(TabModelTest, DISABLED_RestoreSessionOnNTPTest) {
-  web::WebState* web_state =
-      [tab_model_ insertWebStateWithURL:GURL(kChromeUINewTabURL)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
+  web::WebState* web_state = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                    /*parent=*/nil,
+                                                    /*opened_by_dom=*/false,
+                                                    /*index=*/0,
+                                                    /*in_background=*/false);
   web::WebStateImpl* web_state_impl =
       static_cast<web::WebStateImpl*>(web_state);
 
@@ -385,66 +279,57 @@
   SessionWindowIOS* window(CreateSessionWindow());
   [tab_model_ restoreSessionWindow:window forInitialRestore:NO];
 
-  ASSERT_EQ(3U, [tab_model_ count]);
-  EXPECT_EQ(tab_model_.webStateList->GetWebStateAt(1),
-            tab_model_.webStateList->GetActiveWebState());
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(1));
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(2));
+  ASSERT_EQ(3, web_state_list_->count());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(1),
+            web_state_list_->GetActiveWebState());
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(0));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(1));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(2));
 }
 
 // TODO(crbug.com/888674): migrate this to EG test so it can be tested with
 // WKBasedNavigationManager.
 TEST_F(TabModelTest, DISABLED_RestoreSessionOn2NtpTest) {
-  web::WebState* web_state0 =
-      [tab_model_ insertWebStateWithURL:GURL(kChromeUINewTabURL)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
+  web::WebState* web_state0 = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                     /*parent=*/nil,
+                                                     /*opened_by_dom=*/false,
+                                                     /*index=*/0,
+                                                     /*in_background=*/false);
   web::WebStateImpl* web_state_impl =
       static_cast<web::WebStateImpl*>(web_state0);
   web_state_impl->GetNavigationManagerImpl().CommitPendingItem();
-  web::WebState* web_state1 =
-      [tab_model_ insertWebStateWithURL:GURL(kChromeUINewTabURL)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:1
-                           inBackground:NO];
+  web::WebState* web_state1 = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                     /*parent=*/nil,
+                                                     /*opened_by_dom=*/false,
+                                                     /*index=*/0,
+                                                     /*in_background=*/false);
   web_state_impl = static_cast<web::WebStateImpl*>(web_state1);
   web_state_impl->GetNavigationManagerImpl().CommitPendingItem();
 
   SessionWindowIOS* window(CreateSessionWindow());
   [tab_model_ restoreSessionWindow:window forInitialRestore:NO];
 
-  ASSERT_EQ(5U, [tab_model_ count]);
-  EXPECT_EQ(tab_model_.webStateList->GetWebStateAt(3),
-            tab_model_.webStateList->GetActiveWebState());
-  EXPECT_EQ(web_state0, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_EQ(web_state1, tab_model_.webStateList->GetWebStateAt(1));
-  EXPECT_NE(web_state0, tab_model_.webStateList->GetWebStateAt(2));
-  EXPECT_NE(web_state0, tab_model_.webStateList->GetWebStateAt(3));
-  EXPECT_NE(web_state0, tab_model_.webStateList->GetWebStateAt(4));
-  EXPECT_NE(web_state1, tab_model_.webStateList->GetWebStateAt(2));
-  EXPECT_NE(web_state1, tab_model_.webStateList->GetWebStateAt(3));
-  EXPECT_NE(web_state1, tab_model_.webStateList->GetWebStateAt(4));
+  ASSERT_EQ(5, web_state_list_->count());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(3),
+            web_state_list_->GetActiveWebState());
+  EXPECT_EQ(web_state0, web_state_list_->GetWebStateAt(0));
+  EXPECT_EQ(web_state1, web_state_list_->GetWebStateAt(1));
+  EXPECT_NE(web_state0, web_state_list_->GetWebStateAt(2));
+  EXPECT_NE(web_state0, web_state_list_->GetWebStateAt(3));
+  EXPECT_NE(web_state0, web_state_list_->GetWebStateAt(4));
+  EXPECT_NE(web_state1, web_state_list_->GetWebStateAt(2));
+  EXPECT_NE(web_state1, web_state_list_->GetWebStateAt(3));
+  EXPECT_NE(web_state1, web_state_list_->GetWebStateAt(4));
 }
 
 // TODO(crbug.com/888674): migrate this to EG test so it can be tested with
 // WKBasedNavigationManager.
 TEST_F(TabModelTest, DISABLED_RestoreSessionOnAnyTest) {
-  web::WebState* web_state =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:0
-                           inBackground:NO];
+  web::WebState* web_state = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                    /*parent=*/nil,
+                                                    /*opened_by_dom=*/false,
+                                                    /*index=*/0,
+                                                    /*in_background=*/false);
   web::WebStateImpl* web_state_impl =
       static_cast<web::WebStateImpl*>(web_state);
   web_state_impl->GetNavigationManagerImpl().CommitPendingItem();
@@ -452,156 +337,60 @@
   SessionWindowIOS* window(CreateSessionWindow());
   [tab_model_ restoreSessionWindow:window forInitialRestore:NO];
 
-  ASSERT_EQ(4U, [tab_model_ count]);
-  EXPECT_EQ(tab_model_.webStateList->GetWebStateAt(2),
-            tab_model_.webStateList->GetActiveWebState());
-  EXPECT_EQ(web_state, tab_model_.webStateList->GetWebStateAt(0));
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(1));
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(2));
-  EXPECT_NE(web_state, tab_model_.webStateList->GetWebStateAt(3));
+  ASSERT_EQ(4, web_state_list_->count());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(2),
+            web_state_list_->GetActiveWebState());
+  EXPECT_EQ(web_state, web_state_list_->GetWebStateAt(0));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(1));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(2));
+  EXPECT_NE(web_state, web_state_list_->GetWebStateAt(3));
 }
 
 TEST_F(TabModelTest, CloseAllTabs) {
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL2)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL2)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
   [tab_model_ closeAllTabs];
 
-  EXPECT_EQ(0U, [tab_model_ count]);
+  EXPECT_EQ(0, web_state_list_->count());
 }
 
 TEST_F(TabModelTest, CloseAllTabsWithNoTabs) {
   [tab_model_ closeAllTabs];
 
-  EXPECT_EQ(0U, [tab_model_ count]);
+  EXPECT_EQ(0, web_state_list_->count());
 }
 
 TEST_F(TabModelTest, InsertWithSessionController) {
-  EXPECT_EQ([tab_model_ count], 0U);
+  EXPECT_EQ(web_state_list_->count(), 0);
   EXPECT_TRUE([tab_model_ isEmpty]);
 
   web::WebState* new_web_state =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/web_state_list_->count(),
+                             /*in_background=*/false);
 
-  EXPECT_EQ([tab_model_ count], 1U);
-  EXPECT_EQ(new_web_state, tab_model_.webStateList->GetWebStateAt(0));
-  tab_model_.webStateList->ActivateWebStateAt(0);
-  web::WebState* current_web_state =
-      tab_model_.webStateList->GetActiveWebState();
+  EXPECT_EQ(web_state_list_->count(), 1);
+  EXPECT_EQ(new_web_state, web_state_list_->GetWebStateAt(0));
+  web_state_list_->ActivateWebStateAt(0);
+  web::WebState* current_web_state = web_state_list_->GetActiveWebState();
   EXPECT_TRUE(current_web_state);
 }
 
-TEST_F(TabModelTest, AddWithOrderController) {
-  // Create a few tabs with the controller at the front.
-  web::WebState* parent =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-
-  // Add a new tab, it should be added behind the parent.
-  web::WebState* child = [tab_model_
-      insertWebStateWithURL:GURL(kURL1)
-                   referrer:web::Referrer()
-                 transition:ui::PAGE_TRANSITION_LINK
-                     opener:parent
-                openedByDOM:NO
-                    atIndex:TabModelConstants::kTabPositionAutomatically
-               inBackground:NO];
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(parent), 0);
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(child), 1);
-
-  // Add another new tab without a parent, should go at the end.
-  web::WebState* web_state = [tab_model_
-      insertWebStateWithURL:GURL(kURL1)
-                   referrer:web::Referrer()
-                 transition:ui::PAGE_TRANSITION_LINK
-                     opener:nil
-                openedByDOM:NO
-                    atIndex:TabModelConstants::kTabPositionAutomatically
-               inBackground:NO];
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(web_state),
-            static_cast<int>([tab_model_ count]) - 1);
-
-  // Same for a tab that's not opened via a LINK transition.
-  web::WebState* web_state2 =
-      [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                               referrer:web::Referrer()
-                             transition:ui::PAGE_TRANSITION_TYPED
-                                 opener:nil
-                            openedByDOM:NO
-                                atIndex:[tab_model_ count]
-                           inBackground:NO];
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(web_state2),
-            static_cast<int>([tab_model_ count]) - 1);
-
-  // Add a tab in the background. It should appear behind the opening tab.
-  web::WebState* web_state3 = [tab_model_
-      insertWebStateWithURL:GURL(kURL1)
-                   referrer:web::Referrer()
-                 transition:ui::PAGE_TRANSITION_LINK
-                     opener:web_state
-                openedByDOM:NO
-                    atIndex:TabModelConstants::kTabPositionAutomatically
-               inBackground:NO];
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(web_state3),
-            tab_model_.webStateList->GetIndexOfWebState(web_state) + 1);
-
-  // Add another background tab behind the one we just opened.
-  web::WebState* web_state4 = [tab_model_
-      insertWebStateWithURL:GURL(kURL1)
-                   referrer:web::Referrer()
-                 transition:ui::PAGE_TRANSITION_LINK
-                     opener:web_state3
-                openedByDOM:NO
-                    atIndex:TabModelConstants::kTabPositionAutomatically
-               inBackground:NO];
-  EXPECT_EQ(tab_model_.webStateList->GetIndexOfWebState(web_state4),
-            tab_model_.webStateList->GetIndexOfWebState(web_state3) + 1);
-}
-
 // Test that saving a non-empty session, then saving an empty session, then
 // restoring, restores zero tabs, and not the non-empty session.
 TEST_F(TabModelTest, RestorePersistedSessionAfterEmpty) {
@@ -610,13 +399,11 @@
   TestSessionService* test_session_service = [[TestSessionService alloc] init];
   SetTabModel(CreateTabModel(test_session_service, nil));
 
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:0
-                       inBackground:NO];
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/0,
+                         /*in_background=*/false);
   [test_session_service setPerformIO:YES];
   [tab_model_ saveSessionImmediately:YES];
   [test_session_service setPerformIO:NO];
@@ -636,7 +423,7 @@
   SessionWindowIOS* session_window = session.sessionWindows[0];
   [tab_model_ restoreSessionWindow:session_window forInitialRestore:NO];
 
-  EXPECT_EQ(0U, [tab_model_ count]);
+  EXPECT_EQ(0, web_state_list_->count());
 }
 
 TEST_F(TabModelTest, DISABLED_PersistSelectionChange) {
@@ -645,30 +432,25 @@
   TestSessionService* test_session_service = [[TestSessionService alloc] init];
   SetTabModel(CreateTabModel(test_session_service, nil));
 
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:nil
-                        openedByDOM:NO
-                            atIndex:tab_model_.webStateList->count()
-                       inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:tab_model_.webStateList->GetWebStateAt(0)
-                        openedByDOM:NO
-                            atIndex:[tab_model_ count]
-                       inBackground:NO];
-  [tab_model_ insertWebStateWithURL:GURL(kURL1)
-                           referrer:web::Referrer()
-                         transition:ui::PAGE_TRANSITION_TYPED
-                             opener:tab_model_.webStateList->GetWebStateAt(0)
-                        openedByDOM:NO
-                            atIndex:0
-                       inBackground:NO];
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
 
-  ASSERT_EQ(3U, [tab_model_ count]);
-  tab_model_.webStateList->ActivateWebStateAt(1);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/web_state_list_->GetWebStateAt(0),
+                         /*opened_by_dom=*/false,
+                         /*index=*/web_state_list_->count(),
+                         /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/web_state_list_->GetWebStateAt(0),
+                         /*opened_by_dom=*/false,
+                         /*index=*/0,
+                         /*in_background=*/false);
+
+  ASSERT_EQ(3, web_state_list_->count());
+  web_state_list_->ActivateWebStateAt(1);
   // Force state to flush to disk on the main thread so it can be immediately
   // tested below.
   [test_session_service setPerformIO:YES];
@@ -685,10 +467,10 @@
   // Create tab model from saved session.
   SetTabModel(CreateTabModel(test_session_service, session_window));
 
-  ASSERT_EQ(3u, [tab_model_ count]);
+  ASSERT_EQ(3, web_state_list_->count());
 
-  EXPECT_EQ(tab_model_.webStateList->GetWebStateAt(1),
-            tab_model_.webStateList->GetActiveWebState());
+  EXPECT_EQ(web_state_list_->GetWebStateAt(1),
+            web_state_list_->GetActiveWebState());
 }
 
 }  // anonymous namespace
diff --git a/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.mm b/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.mm
index 68eface..1c0bbd1c 100644
--- a/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.mm
+++ b/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.mm
@@ -11,6 +11,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/app_launcher/app_launcher_tab_helper.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
@@ -128,7 +129,7 @@
     std::unique_ptr<OverlayRequest> request =
         OverlayRequest::CreateWithConfig<AppLauncherAlertOverlayRequestConfig>(
             /* is_repeated_request= */ false);
-    request->set_callback(
+    request->GetCallbackManager()->AddCompletionCallback(
         base::BindOnce(&AppLauncherOverlayCallback, completion));
     OverlayRequestQueue::FromWebState(webState,
                                       OverlayModality::kWebContentArea)
@@ -195,7 +196,7 @@
     std::unique_ptr<OverlayRequest> request =
         OverlayRequest::CreateWithConfig<AppLauncherAlertOverlayRequestConfig>(
             /* is_repeated_request= */ true);
-    request->set_callback(
+    request->GetCallbackManager()->AddCompletionCallback(
         base::BindOnce(&AppLauncherOverlayCallback, completion));
     OverlayRequestQueue::FromWebState(tabHelper->web_state(),
                                       OverlayModality::kWebContentArea)
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
index 96345aa..183524a3 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -103,7 +103,7 @@
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    base::OnceClosure callback) override;
   bool HasCreditCardScanFeature() override;
-  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ScanCreditCard(CreditCardScanCallback callback) override;
   void ShowAutofillPopup(
       const gfx::RectF& element_bounds,
       base::i18n::TextDirection text_direction,
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
index 25ec273b..30295352 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -330,8 +330,7 @@
   return false;
 }
 
-void ChromeAutofillClientIOS::ScanCreditCard(
-    const CreditCardScanCallback& callback) {
+void ChromeAutofillClientIOS::ScanCreditCard(CreditCardScanCallback callback) {
   NOTREACHED();
 }
 
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 52540ce4..97bea73 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -245,11 +245,13 @@
   sources = [
     "bookmarks_accessibility_egtest.mm",
     "bookmarks_promo_egtest.mm",
+    "bookmarks_search_egtest.mm",
   ]
   deps = [
     ":bookmarks_ui",
     ":eg_test_support+eg2",
     "//base/test:test_support",
+    "//components/strings",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h
index d340970..40622ad 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h
@@ -36,6 +36,12 @@
 // GREYAssert is induced if test bookmarks can not be loaded.
 - (void)setupStandardBookmarks;
 
+#pragma mark - Common Helpers
+
+// Verifies that there is |count| children on the bookmark folder with |name|.
+// GREYAssert is induced if the folder doesn't exist or the count doesn't match.
+- (void)verifyChildCount:(int)count inFolderWithName:(NSString*)name;
+
 #pragma mark - Promo
 
 // Checks that the promo has already been seen or not. GREYAssert is induced if
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.mm b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.mm
index 13cf33c5..168e7c96 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.mm
@@ -62,6 +62,14 @@
                                 fourthURL:spec4]);
 }
 
+#pragma mark - Common Helpers
+
+- (void)verifyChildCount:(int)count inFolderWithName:(NSString*)name {
+  EG_TEST_HELPER_ASSERT_NO_ERROR([BookmarkEarlGreyAppInterface
+      verifyChildCount:count
+      inFolderWithName:name]);
+}
+
 #pragma mark - Promo
 
 - (void)verifyPromoAlreadySeen:(BOOL)seen {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.h b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.h
index f6823fa1..f5cec92 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.h
@@ -30,6 +30,9 @@
 // Sets that the promo has already been seen |times| number of times.
 + (void)setPromoAlreadySeenNumberOfTimes:(int)times;
 
+// Verifies that there is |count| children on the bookmark folder with |name|.
++ (NSError*)verifyChildCount:(size_t)count inFolderWithName:(NSString*)name;
+
 // Returns the number of times a Promo has been seen.
 + (int)numberOfTimesPromoAlreadySeen;
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.mm b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.mm
index ab637c2..7e3776b 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_app_interface.mm
@@ -17,6 +17,7 @@
 #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h"
 #import "ios/testing/nserror_util.h"
 #import "ios/web/public/test/http_server/http_server.h"
+#include "ui/base/models/tree_node_iterator.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -101,6 +102,37 @@
   prefs->SetBoolean(prefs::kIosBookmarkPromoAlreadySeen, seen);
 }
 
++ (NSError*)verifyChildCount:(size_t)count inFolderWithName:(NSString*)name {
+  base::string16 name16(base::SysNSStringToUTF16(name));
+  bookmarks::BookmarkModel* bookmarkModel =
+      ios::BookmarkModelFactory::GetForBrowserState(
+          chrome_test_util::GetOriginalBrowserState());
+
+  ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
+      bookmarkModel->root_node());
+
+  const bookmarks::BookmarkNode* folder = nullptr;
+  while (iterator.has_next()) {
+    const bookmarks::BookmarkNode* bookmark = iterator.Next();
+    if (bookmark->is_folder() && bookmark->GetTitle() == name16) {
+      folder = bookmark;
+      break;
+    }
+  }
+  if (!folder)
+    return testing::NSErrorWithLocalizedDescription(
+        [NSString stringWithFormat:@"No folder named %@", name]);
+
+  if (folder->children().size() != count)
+    return testing::NSErrorWithLocalizedDescription(
+        [NSString stringWithFormat:
+                      @"Unexpected number of children in folder '%@': %" PRIuS
+                       " instead of %" PRIuS,
+                      name, folder->children().size(), count]);
+
+  return nil;
+}
+
 + (void)setPromoAlreadySeenNumberOfTimes:(int)times {
   PrefService* prefs = chrome_test_util::GetOriginalBrowserState()->GetPrefs();
   prefs->SetInteger(prefs::kIosBookmarkSigninPromoDisplayedCount, times);
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm
index 55ec0fe..f4a502b 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.mm
@@ -201,7 +201,10 @@
 
 - (void)renameBookmarkFolderWithFolderTitle:(NSString*)folderTitle {
   NSString* titleIdentifier = @"Title_textField";
-  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(titleIdentifier)]
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(titleIdentifier),
+                                          grey_kindOfClassName(@"UITextField"),
+                                          nil)]
       performAction:grey_replaceText(folderTitle)];
 }
 
@@ -452,7 +455,10 @@
       assertWithMatcher:grey_notNil()];
 
   // Edit textfield.
-  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(textFieldId)]
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(textFieldId),
+                                          grey_kindOfClassName(@"UITextField"),
+                                          nil)]
       performAction:grey_replaceText(newName)];
 
   // Dismiss editor.
@@ -481,7 +487,10 @@
       assertWithMatcher:grey_notNil()];
 
   // Edit textfield.
-  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(textFieldId)]
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(textFieldId),
+                                          grey_kindOfClassName(@"UITextField"),
+                                          nil)]
       performAction:grey_replaceText(newName)];
 
   // Dismiss editor.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm
index d4ccd532..70e07ca 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmarks_search_egtest.mm
@@ -5,13 +5,11 @@
 #import <UIKit/UIKit.h>
 #import <XCTest/XCTest.h>
 
-#include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.h"
-#import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_utils.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
@@ -50,14 +48,14 @@
 - (void)tearDown {
   [super tearDown];
   [ChromeEarlGrey clearBookmarks];
-  [BookmarkEarlGreyUtils clearBookmarksPositionCache];
+  [BookmarkEarlGrey clearBookmarksPositionCache];
 }
 
 #pragma mark - BookmarksSearchTestCase Tests
 
 // Tests that the search bar is shown on root.
 - (void)testSearchBarShownOnRoot {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
 
   // Verify the search bar is shown.
@@ -68,7 +66,7 @@
 
 // Tests that the search bar is shown on mobile list.
 - (void)testSearchBarShownOnMobileBookmarks {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -80,7 +78,7 @@
 
 // Tests the search.
 - (void)testSearchResults {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -142,7 +140,7 @@
 
 // Tests that you get 'No Results' when no matching bookmarks are found.
 - (void)testSearchWithNoResults {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -165,7 +163,7 @@
 
 // Tests that scrim is shown while search box is enabled with no queries.
 - (void)testSearchScrimShownWhenSearchBoxEnabled {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -207,7 +205,7 @@
 // Tests that tapping scrim while search box is enabled dismisses the search
 // controller.
 - (void)testSearchTapOnScrimCancelsSearchController {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -239,7 +237,7 @@
 // Tests that long press on scrim while search box is enabled dismisses the
 // search controller.
 - (void)testSearchLongPressOnScrimCancelsSearchController {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -275,7 +273,7 @@
 
 // Tests cancelling search restores the node's bookmarks.
 - (void)testSearchCancelRestoresNodeBookmarks {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -311,7 +309,7 @@
 
 // Tests that the navigation bar isn't shown when search is focused and empty.
 - (void)testSearchHidesNavigationBar {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -337,7 +335,7 @@
 // Tests that you can long press and edit a bookmark and see edits when going
 // back to search.
 - (void)testSearchLongPressEditOnURL {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -373,7 +371,7 @@
 // Tests that you can long press and edit a bookmark folder and see edits
 // when going back to search.
 - (void)testSearchLongPressEditOnFolder {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -429,7 +427,7 @@
     EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad on iOS11.");
   }
 
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -457,7 +455,7 @@
     EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad on iOS11.");
   }
 
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -476,7 +474,7 @@
 
 // Tests that you can't search while in edit mode.
 - (void)testDisablesSearchOnEditMode {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -504,7 +502,7 @@
 
 // Tests that new Folder is disabled when search results are shown.
 - (void)testSearchDisablesNewFolderButtonOnNavigationBar {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -527,7 +525,7 @@
 // Tests that a single edit is possible when searching and selecting a single
 // URL in edit mode.
 - (void)testSearchEditModeEditOnSingleURL {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -570,7 +568,7 @@
 
 // Tests that multiple deletes on search results works.
 - (void)testSearchEditModeDeleteOnMultipleURL {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -617,7 +615,7 @@
 
 // Tests that multiple moves on search results works.
 - (void)testMoveFunctionalityOnMultipleUrlSelection {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
@@ -673,7 +671,7 @@
   [[EarlGrey selectElementWithMatcher:CancelButton()] performAction:grey_tap()];
 
   // Verify Folder 1 has three bookmark nodes.
-  [BookmarkEarlGreyUtils assertChildCount:3 ofFolderWithName:@"Folder 1"];
+  [BookmarkEarlGrey verifyChildCount:3 inFolderWithName:@"Folder 1"];
 
   // Drill down to where "Second URL" and "First URL" have been moved and assert
   // it's presence.
@@ -688,7 +686,7 @@
 
 // Tests that a search and single edit is possible when searching over root.
 - (void)testSearchEditPossibleOnRoot {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
 
   // Search and hide keyboard.
@@ -737,8 +735,14 @@
 }
 
 // Tests that you can search folders.
-- (void)testSearchFolders {
-  [BookmarkEarlGreyUtils setupStandardBookmarks];
+// TODO(crbug.com/1034183): Enable for EG2 once NavigateBackButtonTo() is fixed.
+#if defined(CHROME_EARL_GREY_2)
+#define MAYBE_testSearchFolders DISABLED_testSearchFolders
+#else
+#define MAYBE_testSearchFolders testSearchFolders
+#endif
+- (void)MAYBE_testSearchFolders {
+  [BookmarkEarlGrey setupStandardBookmarks];
   [BookmarkEarlGreyUI openBookmarks];
   [BookmarkEarlGreyUI openMobileBookmarks];
 
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 86326dc..aae101d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -167,6 +167,7 @@
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
 #import "ios/chrome/browser/web/web_state_delegate_tab_helper.h"
 #import "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h"
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h"
@@ -2295,6 +2296,7 @@
     }
     NSArray<GuideName*>* guideNames = @[
       kContentAreaGuide,
+      kPrimaryToolbarGuide,
       kBadgeOverflowMenuGuide,
       kOmniboxGuide,
       kOmniboxLeadingImageGuide,
@@ -2593,7 +2595,6 @@
   __weak __typeof(self) weakSelf = self;
   [self.toolbarAccessoryPresenter
       addToolbarAccessoryView:findBarView
-             usingToolbarView:_primaryToolbarCoordinator.viewController.view
                      animated:animate
                    completion:^() {
                      __strong __typeof(self) strongSelf = weakSelf;
@@ -2601,6 +2602,7 @@
                        [strongSelf.findBarController selectAllText];
                      }
                    }];
+
   [self updateFindBar:YES shouldFocus:shouldFocus];
 }
 
@@ -3049,10 +3051,9 @@
   // Requested web state should not be blocked from opening.
   SnapshotTabHelper::FromWebState(webState)->UpdateSnapshotWithCallback(nil);
 
-  web::WebState* childWebState =
-      [[self tabModel] insertOpenByDOMWebStateWithOpener:webState];
-
-  return childWebState;
+  TabInsertionBrowserAgent* insertionAgent =
+      TabInsertionBrowserAgent::FromBrowser(self.browser);
+  return insertionAgent->InsertWebStateOpenedByDOM(webState);
 }
 
 - (void)closeWebState:(web::WebState*)webState {
@@ -3075,31 +3076,23 @@
   loadParams.transition_type = params.transition;
   loadParams.is_renderer_initiated = params.is_renderer_initiated;
   loadParams.virtual_url = params.virtual_url;
+  TabInsertionBrowserAgent* insertionAgent =
+      TabInsertionBrowserAgent::FromBrowser(self.browser);
   switch (params.disposition) {
     case WindowOpenDisposition::NEW_FOREGROUND_TAB:
     case WindowOpenDisposition::NEW_BACKGROUND_TAB: {
-      return [[self tabModel]
-          insertWebStateWithLoadParams:loadParams
-                                opener:webState
-                           openedByDOM:NO
-                               atIndex:TabModelConstants::
-                                           kTabPositionAutomatically
-                          inBackground:
-                              (params.disposition ==
-                               WindowOpenDisposition::NEW_BACKGROUND_TAB)];
+      return insertionAgent->InsertWebState(
+          loadParams, webState, false, TabInsertion::kPositionAutomatically,
+          (params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB));
     }
     case WindowOpenDisposition::CURRENT_TAB: {
       webState->GetNavigationManager()->LoadURLWithParams(loadParams);
       return webState;
     }
     case WindowOpenDisposition::NEW_POPUP: {
-      return [[self tabModel]
-          insertWebStateWithLoadParams:loadParams
-                                opener:webState
-                           openedByDOM:YES
-                               atIndex:TabModelConstants::
-                                           kTabPositionAutomatically
-                          inBackground:NO];
+      return insertionAgent->InsertWebState(
+          loadParams, webState, true, TabInsertion::kPositionAutomatically,
+          false);
     }
     default:
       NOTIMPLEMENTED();
@@ -4098,15 +4091,13 @@
     GURL URL(std::string("data:text/plain;charset=utf-8;base64,") + base64HTML);
     web::Referrer referrer(webState->GetLastCommittedURL(),
                            web::ReferrerPolicyDefault);
-
-    [[weakSelf tabModel]
-        insertWebStateWithURL:URL
-                     referrer:referrer
-                   transition:ui::PAGE_TRANSITION_LINK
-                       opener:webState
-                  openedByDOM:YES
-                      atIndex:TabModelConstants::kTabPositionAutomatically
-                 inBackground:NO];
+    web::NavigationManager::WebLoadParams loadParams(URL);
+    loadParams.referrer = referrer;
+    loadParams.transition_type = ui::PAGE_TRANSITION_LINK;
+    TabInsertionBrowserAgent* insertionAgent =
+        TabInsertionBrowserAgent::FromBrowser(self.browser);
+    insertionAgent->InsertWebState(loadParams, webState, true,
+                                   TabInsertion::kPositionAutomatically, false);
   };
   [self.currentWebState->GetJSInjectionReceiver()
       executeJavaScript:script
@@ -4761,14 +4752,12 @@
 - (void)captivePortalDetectorTabHelper:
             (CaptivePortalDetectorTabHelper*)tabHelper
                  connectWithLandingURL:(const GURL&)landingURL {
-  [self.tabModel
-      insertWebStateWithLoadParams:web_navigation_util::CreateWebLoadParams(
-                                       landingURL, ui::PAGE_TRANSITION_TYPED,
-                                       nullptr)
-                            opener:nil
-                       openedByDOM:NO
-                           atIndex:self.tabModel.webStateList->count()
-                      inBackground:NO];
+  TabInsertionBrowserAgent* insertionAgent =
+      TabInsertionBrowserAgent::FromBrowser(self.browser);
+  insertionAgent->InsertWebState(
+      web_navigation_util::CreateWebLoadParams(
+          landingURL, ui::PAGE_TRANSITION_TYPED, nullptr),
+      nil, false, self.browser->GetWebStateList()->count(), false);
 }
 
 #pragma mark - PageInfoPresentation
diff --git a/ios/chrome/browser/ui/dialogs/overlay_java_script_dialog_presenter.mm b/ios/chrome/browser/ui/dialogs/overlay_java_script_dialog_presenter.mm
index 1ab74be..1b5d9242 100644
--- a/ios/chrome/browser/ui/dialogs/overlay_java_script_dialog_presenter.mm
+++ b/ios/chrome/browser/ui/dialogs/overlay_java_script_dialog_presenter.mm
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
 #import "base/strings/sys_string_conversions.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
@@ -68,7 +69,7 @@
           base::SysNSStringToUTF8(default_prompt_text));
       break;
   }
-  request->set_callback(base::BindOnce(
+  request->GetCallbackManager()->AddCompletionCallback(base::BindOnce(
       &OverlayJavaScriptDialogPresenter::HandleJavaScriptDialogResponse,
       weak_factory_.GetWeakPtr(), std::move(callback), source, dialog_type));
   OverlayRequestQueue::FromWebState(web_state, OverlayModality::kWebContentArea)
diff --git a/ios/chrome/browser/ui/overlays/BUILD.gn b/ios/chrome/browser/ui/overlays/BUILD.gn
index 1212487..917382f3 100644
--- a/ios/chrome/browser/ui/overlays/BUILD.gn
+++ b/ios/chrome/browser/ui/overlays/BUILD.gn
@@ -53,9 +53,12 @@
 
 source_set("coordinators") {
   sources = [
+    "overlay_request_coordinator+subclassing.h",
     "overlay_request_coordinator.h",
     "overlay_request_coordinator.mm",
     "overlay_request_coordinator_delegate.h",
+    "overlay_request_mediator.h",
+    "overlay_request_mediator.mm",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/BUILD.gn b/ios/chrome/browser/ui/overlays/common/alerts/BUILD.gn
index 0f9f74f2..e12928f7 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/BUILD.gn
+++ b/ios/chrome/browser/ui/overlays/common/alerts/BUILD.gn
@@ -4,10 +4,10 @@
 
 source_set("alerts") {
   sources = [
-    "alert_overlay_coordinator+subclassing.h",
+    "alert_overlay_coordinator+alert_mediator_creation.h",
     "alert_overlay_coordinator.h",
     "alert_overlay_coordinator.mm",
-    "alert_overlay_mediator+subclassing.h",
+    "alert_overlay_mediator+alert_consumer_support.h",
     "alert_overlay_mediator.h",
     "alert_overlay_mediator.mm",
   ]
@@ -33,6 +33,8 @@
 
   deps = [
     ":alerts",
+    "//ios/chrome/browser/overlays",
+    "//ios/chrome/browser/overlays/test",
     "//ios/chrome/browser/ui/alert_view",
     "//ios/chrome/browser/ui/alert_view/test",
     "//ios/chrome/browser/ui/elements",
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h
similarity index 80%
rename from ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h
rename to ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h
index 22dfc7f..9b7e453 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_SUBCLASSING_H_
-#define IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_SUBCLASSING_H_
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_ALERT_MEDIATOR_CREATION_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_ALERT_MEDIATOR_CREATION_H_
 
 #import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.h"
 
@@ -12,7 +12,7 @@
 
 // Category that allows subclasses to update UI using the OverlayRequest
 // configuration.
-@interface AlertOverlayCoordinator (Subclassing)
+@interface AlertOverlayCoordinator (AlertMediatorCreation)
 
 // Subclasses must override this selector to create a mediator that will
 // configure the alert using the OverlayRequest's config.
@@ -20,4 +20,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_SUBCLASSING_H_
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_COORDINATOR_ALERT_MEDIATOR_CREATION_H_
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.mm
index 57d8fb4..489e682 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.mm
@@ -5,9 +5,11 @@
 #import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.h"
 
 #include "base/logging.h"
+#include "base/mac/foundation_util.h"
 #import "ios/chrome/browser/ui/alert_view/alert_view_controller.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h"
+#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h"
 #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h"
 #import "ios/chrome/browser/ui/presenters/contained_presenter_delegate.h"
 #import "ios/chrome/browser/ui/presenters/non_modal_view_controller_presenter.h"
@@ -17,26 +19,26 @@
 #endif
 
 @interface AlertOverlayCoordinator () <AlertOverlayMediatorDataSource,
-                                       AlertOverlayMediatorDelegate,
                                        ContainedPresenterDelegate>
-@property(nonatomic, getter=isStarted) BOOL started;
 @property(nonatomic) AlertViewController* alertViewController;
+@property(nonatomic) AlertOverlayMediator* alertMediator;
 @property(nonatomic) NonModalViewControllerPresenter* presenter;
-@property(nonatomic) AlertOverlayMediator* mediator;
 @end
 
 @implementation AlertOverlayCoordinator
 
 #pragma mark - Accessors
 
-- (void)setMediator:(AlertOverlayMediator*)mediator {
-  if (_mediator == mediator)
+- (void)setAlertMediator:(AlertOverlayMediator*)alertMediator {
+  if ([self.alertMediator isEqual:alertMediator])
     return;
-  _mediator.delegate = nil;
-  _mediator.dataSource = nil;
-  _mediator = mediator;
-  _mediator.delegate = self;
-  _mediator.dataSource = self;
+  self.alertMediator.dataSource = nil;
+  self.mediator = alertMediator;
+  self.alertMediator.dataSource = self;
+}
+
+- (AlertOverlayMediator*)alertMediator {
+  return base::mac::ObjCCastStrict<AlertOverlayMediator>(self.mediator);
 }
 
 #pragma mark - AlertOverlayMediatorDataSource
@@ -48,12 +50,6 @@
   return index < textFieldResults.count ? textFieldResults[index] : nil;
 }
 
-#pragma mark - AlertOverlayMediatorDelegate
-
-- (void)stopDialogForMediator:(AlertOverlayMediator*)mediator {
-  [self stopAnimated:YES];
-}
-
 #pragma mark - ContainedPresenterDelegate
 
 - (void)containedPresenterDidPresent:(id<ContainedPresenter>)presenter {
@@ -89,8 +85,8 @@
       UIModalPresentationOverCurrentContext;
   self.alertViewController.modalTransitionStyle =
       UIModalTransitionStyleCrossDissolve;
-  self.mediator = [self newMediator];
-  self.mediator.consumer = self.alertViewController;
+  self.alertMediator = [self newMediator];
+  self.alertMediator.consumer = self.alertViewController;
   self.presenter = [[NonModalViewControllerPresenter alloc] init];
   self.presenter.delegate = self;
   self.presenter.baseViewController = self.baseViewController;
@@ -109,7 +105,7 @@
 
 @end
 
-@implementation AlertOverlayCoordinator (Subclassing)
+@implementation AlertOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   NOTREACHED() << "Subclasses implement.";
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h
similarity index 88%
rename from ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h
rename to ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h
index 726fb12..8e0fcc7 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_SUBCLASSING_H_
-#define IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_SUBCLASSING_H_
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_ALERT_CONSUMER_SUPPORT_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_ALERT_CONSUMER_SUPPORT_H_
 
 #import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h"
 
@@ -12,7 +12,7 @@
 
 // Category that exposes the values to pass to the consumer.  Subclasses must
 // implement these functions using the data from their request configurations.
-@interface AlertOverlayMediator (Subclassing)
+@interface AlertOverlayMediator (AlertConsumerSupport)
 
 // The title to supply to the AlertConsumer.  Default value is nil.
 @property(nonatomic, readonly) NSString* alertTitle;
@@ -34,4 +34,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_SUBCLASSING_H_
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_ALERT_CONSUMER_SUPPORT_H_
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h
index 9fbd9b3e..3afc6d5 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h
@@ -5,35 +5,24 @@
 #ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_H_
 #define IOS_CHROME_BROWSER_UI_OVERLAYS_COMMON_ALERTS_ALERT_OVERLAY_MEDIATOR_H_
 
-#import <Foundation/Foundation.h>
+#import "ios/chrome/browser/ui/overlays/overlay_request_mediator.h"
 
 @protocol AlertConsumer;
 @protocol AlertOverlayMediatorDataSource;
 @protocol AlertOverlayMediatorDelegate;
 
 // Mediator superclass for configuring AlertConsumers.
-@interface AlertOverlayMediator : NSObject
+@interface AlertOverlayMediator : OverlayRequestMediator
 
 // The consumer to be updated by this mediator.  Setting to a new value updates
 // the new consumer.
 @property(nonatomic, weak) id<AlertConsumer> consumer;
 
-// The mediator's delegate.
-@property(nonatomic, weak) id<AlertOverlayMediatorDelegate> delegate;
-
 // The mediator's data source.
 @property(nonatomic, weak) id<AlertOverlayMediatorDataSource> dataSource;
 
 @end
 
-// Protocol used by the actions set up by the JavaScriptDialogOverlayMediator.
-@protocol AlertOverlayMediatorDelegate <NSObject>
-
-// Called by |mediator| to dismiss the alert UI when an action is tapped.
-- (void)stopDialogForMediator:(AlertOverlayMediator*)mediator;
-
-@end
-
 // Protocol used to provide text field information to the actions set up by the
 // JavaScriptDialogOverlayMediator.
 @protocol AlertOverlayMediatorDataSource <NSObject>
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.mm
index 143625d..7e06caa 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.mm
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/alert_view/alert_consumer.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -34,7 +34,7 @@
 
 @end
 
-@implementation AlertOverlayMediator (Subclassing)
+@implementation AlertOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertTitle {
   // Subclasses implement.
diff --git a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator_unittest.mm
index edfb7644..594b965f 100644
--- a/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator_unittest.mm
@@ -4,10 +4,12 @@
 
 #import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h"
 
+#include "ios/chrome/browser/overlays/public/overlay_request.h"
+#include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h"
 #import "ios/chrome/browser/ui/alert_view/alert_action.h"
 #import "ios/chrome/browser/ui/alert_view/test/fake_alert_consumer.h"
 #import "ios/chrome/browser/ui/elements/text_field_configuration.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 #import "ios/chrome/browser/ui/overlays/common/alerts/test/alert_overlay_mediator_test.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -33,7 +35,10 @@
 // Tests that the AlertOverlayMediator's subclassing properties are correctly
 // applied to the consumer.
 TEST_F(AlertOverlayMediatorTest, SetUpConsumer) {
-  FakeAlertOverlayMediator* mediator = [[FakeAlertOverlayMediator alloc] init];
+  std::unique_ptr<OverlayRequest> request =
+      OverlayRequest::CreateWithConfig<FakeOverlayUserData>(nullptr);
+  FakeAlertOverlayMediator* mediator =
+      [[FakeAlertOverlayMediator alloc] initWithRequest:request.get()];
   mediator.alertTitle = @"Title";
   mediator.alertMessage = @"Message";
   mediator.alertTextFieldConfigurations =
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h b/ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h
new file mode 100644
index 0000000..3d96ca7
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_SUBCLASSING_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_SUBCLASSING_H_
+
+#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h"
+
+@class OverlayRequestMediator;
+
+// Interface for concrete subclasses of OverlayRequestCoordinator.
+@interface OverlayRequestCoordinator (Subclassing)
+
+// Whether the coordinator has been started.
+@property(nonatomic, assign, getter=isStarted) BOOL started;
+
+// The mediator used to configure the overlay UI.
+@property(nonatomic, strong) OverlayRequestMediator* mediator;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_SUBCLASSING_H_
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm
index 87a0d89..7d5c1777 100644
--- a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm
@@ -6,11 +6,19 @@
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h"
+#import "ios/chrome/browser/ui/overlays/overlay_request_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
+@interface OverlayRequestCoordinator () <OverlayRequestMediatorDelegate> {
+  // Subclassing properties.
+  BOOL _started;
+  OverlayRequestMediator* _mediator;
+}
+@end
+
 @implementation OverlayRequestCoordinator
 
 - (void)dealloc {
@@ -65,4 +73,32 @@
   [self stopAnimated:YES];
 }
 
+#pragma mark - OverlayRequestMediatorDelegate
+
+- (void)stopOverlayForMediator:(OverlayRequestMediator*)mediator {
+  [self stopAnimated:YES];
+}
+
+@end
+
+@implementation OverlayRequestCoordinator (Subclassing)
+
+- (void)setStarted:(BOOL)started {
+  _started = started;
+}
+
+- (BOOL)isStarted {
+  return _started;
+}
+
+- (void)setMediator:(OverlayRequestMediator*)mediator {
+  _mediator.delegate = nil;
+  _mediator = mediator;
+  _mediator.delegate = self;
+}
+
+- (OverlayRequestMediator*)mediator {
+  return _mediator;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_mediator.h b/ios/chrome/browser/ui/overlays/overlay_request_mediator.h
new file mode 100644
index 0000000..3433149
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/overlay_request_mediator.h
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_MEDIATOR_H_
+
+#import <Foundation/Foundation.h>
+
+class OverlayRequest;
+@protocol OverlayRequestMediatorDelegate;
+
+// Mediator used to configure overlay UI consumers using an OverlayRequest.
+// Subclasses should use the request passed on initialization to set up overlay
+// UI via consumer protocols specific to that config type.
+@interface OverlayRequestMediator : NSObject
+
+// Initializer for a mediator that sets ups its consumer with |request|'s
+// config.
+- (instancetype)initWithRequest:(OverlayRequest*)request
+    NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+// The request passed on initialization.
+@property(nonatomic, readonly) OverlayRequest* request;
+
+// The delegate.
+@property(nonatomic, weak) id<OverlayRequestMediatorDelegate> delegate;
+
+@end
+
+// Delegate for the mediator used to stop the overlay when user interaction
+// should trigger dismissal.
+@protocol OverlayRequestMediatorDelegate <NSObject>
+
+// Stops the overlay UI.
+- (void)stopOverlayForMediator:(OverlayRequestMediator*)mediator;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_mediator.mm b/ios/chrome/browser/ui/overlays/overlay_request_mediator.mm
new file mode 100644
index 0000000..bcea75b
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/overlay_request_mediator.mm
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/overlays/overlay_request_mediator.h"
+
+#include "base/logging.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation OverlayRequestMediator
+
+- (instancetype)initWithRequest:(OverlayRequest*)request {
+  if (self = [super init]) {
+    _request = request;
+    DCHECK(_request);
+  }
+  return self;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm
index 40f9539f..d33d2bb 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm
@@ -6,7 +6,7 @@
 
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #include "ios/chrome/browser/overlays/public/web_content_area/app_launcher_alert_overlay.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -21,9 +21,7 @@
 
 @end
 
-@implementation AppLauncherAlertOverlayCoordinator (Subclassing)
-
-#pragma mark - AlertOverlayCoordinator
+@implementation AppLauncherAlertOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   return [[AppLauncherAlertOverlayMediator alloc] initWithRequest:self.request];
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.mm
index ee4fbf0e..de55618 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.mm
@@ -6,11 +6,12 @@
 
 #include "base/logging.h"
 #include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #include "ios/chrome/browser/overlays/public/overlay_response.h"
 #include "ios/chrome/browser/overlays/public/web_content_area/app_launcher_alert_overlay.h"
 #import "ios/chrome/browser/ui/alert_view/alert_action.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -19,7 +20,7 @@
 #endif
 
 @interface AppLauncherAlertOverlayMediator ()
-@property(nonatomic, readonly) OverlayRequest* request;
+// The config from the request passed on initialization.
 @property(nonatomic, readonly) AppLauncherAlertOverlayRequestConfig* config;
 
 // Sets the OverlayResponse. |allowAppLaunch| indicates whether the alert's
@@ -30,11 +31,9 @@
 @implementation AppLauncherAlertOverlayMediator
 
 - (instancetype)initWithRequest:(OverlayRequest*)request {
-  if (self = [super init]) {
-    _request = request;
-    DCHECK(_request);
+  if (self = [super initWithRequest:request]) {
     // Verify that the request is configured for app launcher alerts.
-    DCHECK(_request->GetConfig<AppLauncherAlertOverlayRequestConfig>());
+    DCHECK(request->GetConfig<AppLauncherAlertOverlayRequestConfig>());
   }
   return self;
 }
@@ -48,14 +47,14 @@
 #pragma mark - Response helpers
 
 - (void)updateResponseAllowingAppLaunch:(BOOL)allowAppLaunch {
-  self.request->set_response(
+  self.request->GetCallbackManager()->SetCompletionResponse(
       OverlayResponse::CreateWithInfo<AppLauncherAlertOverlayResponseInfo>(
           allowAppLaunch));
 }
 
 @end
 
-@implementation AppLauncherAlertOverlayMediator (Subclassing)
+@implementation AppLauncherAlertOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertMessage {
   return self.config->is_repeated_request()
@@ -77,7 +76,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf updateResponseAllowingAppLaunch:YES];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
     [AlertAction actionWithTitle:rejectActionTitle
                            style:UIAlertActionStyleCancel
@@ -85,7 +84,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf updateResponseAllowingAppLaunch:NO];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
   ];
 }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm
index 11b3f094..02671dc 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm
@@ -7,7 +7,7 @@
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #include "ios/chrome/browser/overlays/public/web_content_area/http_auth_overlay.h"
 #import "ios/chrome/browser/ui/alert_view/alert_view_controller.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -27,7 +27,7 @@
 
 @end
 
-@implementation HTTPAuthDialogOverlayCoordinator (Subclassing)
+@implementation HTTPAuthDialogOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   return [[HTTPAuthDialogOverlayMediator alloc] initWithRequest:self.request];
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h
index a75dbf18..be41f0cc 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h
@@ -13,13 +13,6 @@
 // Mediator object that uses a HTTPAuthOverlayRequestConfig to set up the UI for
 // an HTTP authentication dialog.
 @interface HTTPAuthDialogOverlayMediator : AlertOverlayMediator
-
-// Designated initializer for a mediator that uses |request|'s configuration to
-// set up an AlertConsumer.
-- (instancetype)initWithRequest:(OverlayRequest*)request
-    NS_DESIGNATED_INITIALIZER;
-- (instancetype)init NS_UNAVAILABLE;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.mm
index e651510..146e003 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.mm
@@ -7,13 +7,14 @@
 #include "base/logging.h"
 #import "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #include "ios/chrome/browser/overlays/public/overlay_request.h"
 #include "ios/chrome/browser/overlays/public/overlay_response.h"
 #include "ios/chrome/browser/overlays/public/web_content_area/http_auth_overlay.h"
 #import "ios/chrome/browser/ui/alert_view/alert_action.h"
 #import "ios/chrome/browser/ui/alert_view/alert_consumer.h"
 #import "ios/chrome/browser/ui/elements/text_field_configuration.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -22,7 +23,7 @@
 #endif
 
 @interface HTTPAuthDialogOverlayMediator ()
-@property(nonatomic, readonly) OverlayRequest* request;
+// The config from the request passed on initialization.
 @property(nonatomic, readonly) HTTPAuthOverlayRequestConfig* config;
 
 // Sets the OverlayResponse using the user input from the prompt UI.
@@ -33,11 +34,9 @@
 @implementation HTTPAuthDialogOverlayMediator
 
 - (instancetype)initWithRequest:(OverlayRequest*)request {
-  if (self = [super init]) {
-    _request = request;
-    DCHECK(_request);
+  if (self = [super initWithRequest:request]) {
     // Verify that the request is configured for HTTP authentication dialogs.
-    DCHECK(_request->GetConfig<HTTPAuthOverlayRequestConfig>());
+    DCHECK(request->GetConfig<HTTPAuthOverlayRequestConfig>());
   }
   return self;
 }
@@ -62,12 +61,13 @@
     response = OverlayResponse::CreateWithInfo<HTTPAuthOverlayResponseInfo>(
         user, password);
   }
-  self.request->set_response(std::move(response));
+  self.request->GetCallbackManager()->SetCompletionResponse(
+      std::move(response));
 }
 
 @end
 
-@implementation HTTPAuthDialogOverlayMediator (Subclassing)
+@implementation HTTPAuthDialogOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertTitle {
   return l10n_util::GetNSStringWithFixup(IDS_LOGIN_DIALOG_TITLE);
@@ -107,7 +107,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf updateResponseCancelled:NO];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
     [AlertAction actionWithTitle:l10n_util::GetNSString(IDS_CANCEL)
                            style:UIAlertActionStyleCancel
@@ -115,7 +115,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf updateResponseCancelled:YES];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
   ];
 }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator.mm
index 3092d40f..2fb1e18a 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator.mm
@@ -6,7 +6,7 @@
 
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_alert_overlay.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -23,7 +23,7 @@
 
 @end
 
-@implementation JavaScriptAlertOverlayCoordinator (Subclassing)
+@implementation JavaScriptAlertOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   return [[JavaScriptAlertOverlayMediator alloc] initWithRequest:self.request];
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.h b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.h
index df73fb22b..4e90532 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.h
@@ -12,12 +12,6 @@
 // Mediator object that uses a JavaScriptAlertOverlayRequestConfig to set up the
 // UI for a JavaScript alert overlay.
 @interface JavaScriptAlertOverlayMediator : AlertOverlayMediator
-
-// Initializer for a mediator that configures its consumer using |request|.
-- (instancetype)initWithRequest:(OverlayRequest*)request
-    NS_DESIGNATED_INITIALIZER;
-- (instancetype)init NS_UNAVAILABLE;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_JAVA_SCRIPT_DIALOGS_JAVA_SCRIPT_ALERT_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.mm
index 5159f13a..2f3b9b9 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_mediator.mm
@@ -11,7 +11,7 @@
 #import "ios/chrome/browser/ui/alert_view/alert_action.h"
 #import "ios/chrome/browser/ui/alert_view/alert_consumer.h"
 #import "ios/chrome/browser/ui/dialogs/dialog_constants.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_overlay_mediator_util.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -22,18 +22,16 @@
 #endif
 
 @interface JavaScriptAlertOverlayMediator ()
-@property(nonatomic, readonly) OverlayRequest* request;
+// The congig from the request passed on initialization.
 @property(nonatomic, readonly) JavaScriptAlertOverlayRequestConfig* config;
 @end
 
 @implementation JavaScriptAlertOverlayMediator
 
 - (instancetype)initWithRequest:(OverlayRequest*)request {
-  if (self = [super init]) {
-    _request = request;
-    DCHECK(_request);
+  if (self = [super initWithRequest:request]) {
     // Verify that the request is configured for JavaScript alerts.
-    DCHECK(_request->GetConfig<JavaScriptAlertOverlayRequestConfig>());
+    DCHECK(request->GetConfig<JavaScriptAlertOverlayRequestConfig>());
   }
   return self;
 }
@@ -46,7 +44,7 @@
 
 @end
 
-@implementation JavaScriptAlertOverlayMediator (Subclassing)
+@implementation JavaScriptAlertOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertTitle {
   return GetJavaScriptDialogTitle(self.config->source(),
@@ -64,7 +62,7 @@
       actionWithTitle:l10n_util::GetNSString(IDS_OK)
                 style:UIAlertActionStyleDefault
               handler:^(AlertAction* action) {
-                [weakSelf.delegate stopDialogForMediator:weakSelf];
+                [weakSelf.delegate stopOverlayForMediator:weakSelf];
               }] ] mutableCopy];
   AlertAction* blockingAction =
       GetBlockingAlertAction(self, self.config->source());
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm
index 1759c0e..d3e57eb 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm
@@ -6,7 +6,7 @@
 
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_confirmation_overlay.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -23,7 +23,7 @@
 
 @end
 
-@implementation JavaScriptConfirmationOverlayCoordinator (Subclassing)
+@implementation JavaScriptConfirmationOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   return [[JavaScriptConfirmationOverlayMediator alloc]
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h
index 7d7eb42..df34d93 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h
@@ -12,12 +12,6 @@
 // Mediator object that uses a JavaScriptConfirmationOverlayRequestConfig to set
 // up the UI for a JavaScript confirmation overlay.
 @interface JavaScriptConfirmationOverlayMediator : AlertOverlayMediator
-
-// Initializer for a mediator that configures its consumer using |request|.
-- (instancetype)initWithRequest:(OverlayRequest*)request
-    NS_DESIGNATED_INITIALIZER;
-- (instancetype)init NS_UNAVAILABLE;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_JAVA_SCRIPT_DIALOGS_JAVA_SCRIPT_CONFIRMATION_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.mm
index f375a26a..53979fa 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h"
 
 #include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_confirmation_overlay.h"
@@ -20,7 +21,7 @@
 #endif
 
 @interface JavaScriptConfirmationOverlayMediator ()
-@property(nonatomic, readonly) OverlayRequest* request;
+// The config from the request passed on initialization.
 @property(nonatomic, readonly)
     JavaScriptConfirmationOverlayRequestConfig* config;
 
@@ -31,11 +32,9 @@
 @implementation JavaScriptConfirmationOverlayMediator
 
 - (instancetype)initWithRequest:(OverlayRequest*)request {
-  if (self = [super init]) {
-    _request = request;
-    DCHECK(_request);
+  if (self = [super initWithRequest:request]) {
     // Verify that the request is configured for JavaScript confirmations.
-    DCHECK(_request->GetConfig<JavaScriptConfirmationOverlayRequestConfig>());
+    DCHECK(request->GetConfig<JavaScriptConfirmationOverlayRequestConfig>());
   }
   return self;
 }
@@ -50,14 +49,14 @@
 
 // Sets the OverlayResponse using the user's selection from the confirmation UI.
 - (void)setConfirmationResponse:(BOOL)dialogConfirmed {
-  self.request->set_response(
+  self.request->GetCallbackManager()->SetCompletionResponse(
       OverlayResponse::CreateWithInfo<
           JavaScriptConfirmationOverlayResponseInfo>(dialogConfirmed));
 }
 
 @end
 
-@implementation JavaScriptConfirmationOverlayMediator (Subclassing)
+@implementation JavaScriptConfirmationOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertTitle {
   return GetJavaScriptDialogTitle(self.config->source(),
@@ -78,7 +77,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf setConfirmationResponse:YES];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
     [AlertAction actionWithTitle:l10n_util::GetNSString(IDS_CANCEL)
                            style:UIAlertActionStyleCancel
@@ -86,7 +85,7 @@
                            __typeof__(self) strongSelf = weakSelf;
                            [strongSelf setConfirmationResponse:NO];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
   ] mutableCopy];
   AlertAction* blockingAction =
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator_unittest.mm
index d71a50d..23a218e8 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator_unittest.mm
@@ -7,6 +7,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/elide_url.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_confirmation_overlay.h"
@@ -45,7 +46,7 @@
   }
   const GURL& url() const { return url_; }
   const std::string& message() const { return message_; }
-  const OverlayRequest* request() const { return request_.get(); }
+  OverlayRequest* request() const { return request_.get(); }
 
  private:
   web::TestWebState web_state_;
@@ -109,12 +110,13 @@
 TEST_F(JavaScriptConfirmationOverlayMediatorTest, ConfirmResponse) {
   CreateMediator();
   ASSERT_EQ(2U, consumer().actions.count);
-  ASSERT_FALSE(!!request()->response());
+  ASSERT_FALSE(!!request()->GetCallbackManager()->GetCompletionResponse());
 
   // Execute the confirm action and verify the response.
   AlertAction* confirm_action = consumer().actions[0];
   confirm_action.handler(confirm_action);
-  OverlayResponse* confirm_response = request()->response();
+  OverlayResponse* confirm_response =
+      request()->GetCallbackManager()->GetCompletionResponse();
   ASSERT_TRUE(!!confirm_response);
   JavaScriptConfirmationOverlayResponseInfo* confirm_response_info =
       confirm_response->GetInfo<JavaScriptConfirmationOverlayResponseInfo>();
@@ -126,12 +128,13 @@
 TEST_F(JavaScriptConfirmationOverlayMediatorTest, CancelResponse) {
   CreateMediator();
   ASSERT_EQ(2U, consumer().actions.count);
-  ASSERT_FALSE(!!request()->response());
+  ASSERT_FALSE(!!request()->GetCallbackManager()->GetCompletionResponse());
 
   // Execute the cancel action and verify the response.
   AlertAction* cancel_action = consumer().actions[1];
   cancel_action.handler(cancel_action);
-  OverlayResponse* cancel_response = request()->response();
+  OverlayResponse* cancel_response =
+      request()->GetCallbackManager()->GetCompletionResponse();
   ASSERT_TRUE(!!cancel_response);
   JavaScriptConfirmationOverlayResponseInfo* cancel_response_info =
       cancel_response->GetInfo<JavaScriptConfirmationOverlayResponseInfo>();
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.mm
index a2eed9b..ee26a31f 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.mm
@@ -47,6 +47,6 @@
                     GetBlockingState(source);
                 if (blocking_state)
                   blocking_state->JavaScriptDialogBlockingOptionSelected();
-                [weakMediator.delegate stopDialogForMediator:weakMediator];
+                [weakMediator.delegate stopOverlayForMediator:weakMediator];
               }];
 }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator.mm
index 3b984806..8e7b889 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator.mm
@@ -6,7 +6,7 @@
 
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_prompt_overlay.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+alert_mediator_creation.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -23,7 +23,7 @@
 
 @end
 
-@implementation JavaScriptPromptOverlayCoordinator (Subclassing)
+@implementation JavaScriptPromptOverlayCoordinator (AlertMediatorCreation)
 
 - (AlertOverlayMediator*)newMediator {
   return [[JavaScriptPromptOverlayMediator alloc] initWithRequest:self.request];
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.h b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.h
index 11d82b62..cda2abd 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.h
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.h
@@ -12,12 +12,6 @@
 // Mediator object that uses a JavaScriptPromptOverlayRequestConfig to set
 // up the UI for a JavaScript prompt overlay.
 @interface JavaScriptPromptOverlayMediator : AlertOverlayMediator
-
-// Initializer for a mediator that configures its consumer using |request|.
-- (instancetype)initWithRequest:(OverlayRequest*)request
-    NS_DESIGNATED_INITIALIZER;
-- (instancetype)init NS_UNAVAILABLE;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_JAVA_SCRIPT_DIALOGS_JAVA_SCRIPT_PROMPT_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm
index 52bf8660..03bbdd9 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm
@@ -6,6 +6,7 @@
 
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_prompt_overlay.h"
@@ -13,7 +14,7 @@
 #import "ios/chrome/browser/ui/alert_view/alert_view_controller.h"
 #import "ios/chrome/browser/ui/dialogs/dialog_constants.h"
 #import "ios/chrome/browser/ui/elements/text_field_configuration.h"
-#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
+#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+alert_consumer_support.h"
 #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.h"
 #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_overlay_mediator_util.h"
@@ -25,7 +26,7 @@
 #endif
 
 @interface JavaScriptPromptOverlayMediator ()
-@property(nonatomic, readonly) OverlayRequest* request;
+// The config from the request passed on initialization.
 @property(nonatomic, readonly) JavaScriptPromptOverlayRequestConfig* config;
 
 // Sets the OverlayResponse using the user input |textInput| from the prompt UI.
@@ -35,11 +36,9 @@
 @implementation JavaScriptPromptOverlayMediator
 
 - (instancetype)initWithRequest:(OverlayRequest*)request {
-  if (self = [super init]) {
-    _request = request;
-    DCHECK(_request);
+  if (self = [super initWithRequest:request]) {
     // Verify that the request is configured for JavaScript prompts.
-    DCHECK(_request->GetConfig<JavaScriptPromptOverlayRequestConfig>());
+    DCHECK(request->GetConfig<JavaScriptPromptOverlayRequestConfig>());
   }
   return self;
 }
@@ -53,14 +52,14 @@
 #pragma mark - Response helpers
 
 - (void)setPromptResponse:(NSString*)textInput {
-  self.request->set_response(
+  self.request->GetCallbackManager()->SetCompletionResponse(
       OverlayResponse::CreateWithInfo<JavaScriptPromptOverlayResponseInfo>(
           base::SysNSStringToUTF8(textInput)));
 }
 
 @end
 
-@implementation JavaScriptPromptOverlayMediator (Subclassing)
+@implementation JavaScriptPromptOverlayMediator (AlertConsumerSupport)
 
 - (NSString*)alertTitle {
   return GetJavaScriptDialogTitle(self.config->source(),
@@ -94,12 +93,12 @@
                                           textFieldIndex:0];
                            [strongSelf setPromptResponse:input ? input : @""];
                            [strongSelf.delegate
-                               stopDialogForMediator:strongSelf];
+                               stopOverlayForMediator:strongSelf];
                          }],
     [AlertAction actionWithTitle:l10n_util::GetNSString(IDS_CANCEL)
                            style:UIAlertActionStyleCancel
                          handler:^(AlertAction* action) {
-                           [weakSelf.delegate stopDialogForMediator:weakSelf];
+                           [weakSelf.delegate stopOverlayForMediator:weakSelf];
                          }],
   ];
   AlertAction* blockingAction =
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator_unittest.mm
index 054a511..e034295 100644
--- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator_unittest.mm
@@ -7,6 +7,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/elide_url.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_response.h"
 #import "ios/chrome/browser/overlays/public/web_content_area/java_script_prompt_overlay.h"
@@ -76,7 +77,7 @@
   const std::string& default_prompt_value() const {
     return default_prompt_value_;
   }
-  const OverlayRequest* request() const { return request_.get(); }
+  OverlayRequest* request() const { return request_.get(); }
   FakePromptOverlayMediatorDataSource* data_source() { return data_source_; }
 
  private:
@@ -157,12 +158,13 @@
   data_source().promptInput = kFakeUserInput;
   CreateMediator();
   ASSERT_EQ(2U, consumer().actions.count);
-  ASSERT_FALSE(!!request()->response());
+  ASSERT_FALSE(!!request()->GetCallbackManager()->GetCompletionResponse());
 
   // Execute the confirm action and verify the response.
   AlertAction* confirm_action = consumer().actions[0];
   confirm_action.handler(confirm_action);
-  OverlayResponse* confirm_response = request()->response();
+  OverlayResponse* confirm_response =
+      request()->GetCallbackManager()->GetCompletionResponse();
   ASSERT_TRUE(!!confirm_response);
   JavaScriptPromptOverlayResponseInfo* confirm_response_info =
       confirm_response->GetInfo<JavaScriptPromptOverlayResponseInfo>();
@@ -177,12 +179,13 @@
   data_source().promptInput = nil;
   CreateMediator();
   ASSERT_EQ(2U, consumer().actions.count);
-  ASSERT_FALSE(!!request()->response());
+  ASSERT_FALSE(!!request()->GetCallbackManager()->GetCompletionResponse());
 
   // Execute the confirm action and verify the response.
   AlertAction* confirm_action = consumer().actions[0];
   confirm_action.handler(confirm_action);
-  OverlayResponse* confirm_response = request()->response();
+  OverlayResponse* confirm_response =
+      request()->GetCallbackManager()->GetCompletionResponse();
   ASSERT_TRUE(!!confirm_response);
   JavaScriptPromptOverlayResponseInfo* confirm_response_info =
       confirm_response->GetInfo<JavaScriptPromptOverlayResponseInfo>();
@@ -196,12 +199,13 @@
   data_source().promptInput = kFakeUserInput;
   CreateMediator();
   ASSERT_EQ(2U, consumer().actions.count);
-  ASSERT_FALSE(!!request()->response());
+  ASSERT_FALSE(!!request()->GetCallbackManager()->GetCompletionResponse());
 
   // Execute the cancel action and verify that there is no response for
   // cancelled prompts.
   AlertAction* cancel_action = consumer().actions[1];
   cancel_action.handler(cancel_action);
-  OverlayResponse* cancel_response = request()->response();
+  OverlayResponse* cancel_response =
+      request()->GetCallbackManager()->GetCompletionResponse();
   EXPECT_FALSE(!!cancel_response);
 }
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn
index 2c1d8299..dc6b2c6c 100644
--- a/ios/chrome/browser/ui/settings/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -8,8 +8,6 @@
     "account_sign_in_item.mm",
     "byo_textfield_item.h",
     "byo_textfield_item.mm",
-    "clear_browsing_data_constants.h",
-    "clear_browsing_data_constants.mm",
     "clear_browsing_data_item.h",
     "clear_browsing_data_item.mm",
     "copied_to_chrome_item.h",
@@ -60,12 +58,21 @@
   ]
 
   public_deps = [
+    ":clear_browsing_data_constants",
     "//ios/chrome/browser/ui/settings/cells/legacy",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+source_set("clear_browsing_data_constants") {
+  sources = [
+    "clear_browsing_data_constants.h",
+    "clear_browsing_data_constants.mm",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 source_set("public") {
   sources = [
     "settings_cells_constants.h",
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
index 0d16492..ebee360 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
@@ -123,6 +123,7 @@
 }
 
 source_set("eg_tests") {
+  defines = [ "CHROME_EARL_GREY_1" ]
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
@@ -130,11 +131,32 @@
   ]
   deps = [
     "//base/test:test_support",
-    "//components/strings",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/browsing_data:feature_flags",
-    "//ios/chrome/browser/ui/settings/cells",
+    "//ios/chrome/browser/ui/settings/cells:clear_browsing_data_constants",
     "//ios/chrome/test/earl_grey:test_support",
+    "//ios/testing/earl_grey:earl_grey_support",
     "//ui/base",
   ]
 }
+
+source_set("eg2_tests") {
+  defines = [ "CHROME_EARL_GREY_2" ]
+  configs += [
+    "//build/config/compiler:enable_arc",
+    "//build/config/ios:xctest_config",
+  ]
+  testonly = true
+  sources = [
+    "clear_browsing_data_egtest.mm",
+  ]
+  deps = [
+    "//base/test:test_support",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser/ui/settings/cells:clear_browsing_data_constants",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+    "//ios/third_party/earl_grey2:test_lib",
+    "//ui/base",
+  ]
+  libs = [ "UIKit.framework" ]
+}
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller_unittest.mm
index 5918edc..58f5c0f 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller_unittest.mm
@@ -214,7 +214,7 @@
 TEST_F(ClearBrowsingDataCollectionViewControllerTest,
        TestItemsSignedInSyncActiveHistoryOff) {
   test_sync_service_->SetDisableReasons(
-      syncer::SyncService::DISABLE_REASON_NONE);
+      syncer::SyncService::DisableReasonSet());
   test_sync_service_->SetTransportState(
       syncer::SyncService::TransportState::ACTIVE);
   test_sync_service_->SetFirstSetupComplete(true);
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm
index 610053d..59397bb 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_egtest.mm
@@ -2,19 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <EarlGrey/EarlGrey.h>
 #import <XCTest/XCTest.h>
 
 #include "base/ios/ios_util.h"
-#include "base/test/scoped_feature_list.h"
-#include "components/strings/grit/components_strings.h"
-#include "ios/chrome/browser/browsing_data/browsing_data_features.h"
 #include "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h"
 #include "ios/chrome/grit/ios_strings.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"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -28,9 +25,7 @@
 @interface ClearBrowsingDataSettingsTestCase : ChromeTestCase
 @end
 
-@implementation ClearBrowsingDataSettingsTestCase {
-  base::test::ScopedFeatureList _featureList;
-}
+@implementation ClearBrowsingDataSettingsTestCase
 
 - (void)openClearBrowsingDataDialog {
   [ChromeEarlGreyUI openSettingsMenu];
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
index 0dbc9e7..36bc700 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -552,13 +552,12 @@
 }
 
 - (BOOL)isSyncDisabledByAdministrator {
-  return (self.syncService->GetDisableReasons() &
-          syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) != 0;
+  return self.syncService->GetDisableReasons().Has(
+      syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
 }
 
 - (BOOL)isSyncDisabled {
-  return self.syncService->GetDisableReasons() !=
-         syncer::SyncService::DISABLE_REASON_NONE;
+  return !self.syncService->GetDisableReasons().Empty();
 }
 
 - (BOOL)isSyncCanBeAvailable {
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
index 73a0c4190..151a41d 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
@@ -161,8 +161,7 @@
 #pragma mark - SyncObserverModelBridge
 
 - (void)onSyncStateChanged {
-  if (self.syncService->GetDisableReasons() !=
-      syncer::SyncService::DISABLE_REASON_NONE) {
+  if (!self.syncService->GetDisableReasons().Empty()) {
     [self closeManageSyncSettings];
   }
 }
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
index 9579e5f..4721d2f 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -289,7 +289,9 @@
     self.encryptionItem.image =
         [UIImage imageNamed:kGoogleServicesSyncErrorImage];
     self.encryptionItem.detailText =
-        GetNSString(IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_ENCRYPTION_FIX_NOW);
+        GetNSString(self.syncSetupService->IsEncryptEverythingEnabled()
+                        ? IDS_IOS_SYNC_ERROR_DESCRIPTION
+                        : IDS_IOS_SYNC_PASSWORDS_ERROR_DESCRIPTION);
   } else {
     needsUpdate = needsUpdate || self.encryptionItem.image != nil;
     self.encryptionItem.image = nil;
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index 6a0280de..8cb94655 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -999,8 +999,8 @@
     googleServicesItem.detailText = nil;
     googleServicesItem.image =
         [UIImage imageNamed:kSyncAndGoogleServicesImageName];
-  } else if (syncService->GetDisableReasons() &
-             syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) {
+  } else if (syncService->GetDisableReasons().Has(
+                 syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)) {
     googleServicesItem.detailText = l10n_util::GetNSString(
         IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS);
     googleServicesItem.image =
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn
index 014a2e6..68b867d 100644
--- a/ios/chrome/browser/ui/tab_grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -26,6 +26,7 @@
     "//components/sessions",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/main",
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/chrome/browser/snapshots",
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
index 7acf214..52059d3e 100644
--- a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
+++ b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
@@ -5,10 +5,14 @@
 #import "ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.h"
 
 #include "base/logging.h"
+#import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h"
 #import "ios/chrome/browser/ui/tab_grid/view_controller_swapping.h"
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
+
 #import "ios/web/public/navigation/navigation_manager.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -42,24 +46,18 @@
   return self.tabGridViewController;
 }
 
-- (void)dismissWithNewTabAnimationToModel:(TabModel*)targetModel
-                        withUrlLoadParams:(const UrlLoadParams&)urlLoadParams
-                                  atIndex:(NSUInteger)position {
-  NSUInteger tabIndex = position;
-  if (position > targetModel.count)
-    tabIndex = targetModel.count;
+- (void)dismissWithNewTabAnimationToBrowser:(Browser*)browser
+                          withUrlLoadParams:(const UrlLoadParams&)urlLoadParams
+                                    atIndex:(int)position {
+  int tabIndex = std::min(position, browser->GetWebStateList()->count());
 
-  // Create the new tab.
-  [targetModel insertWebStateWithLoadParams:urlLoadParams.web_params
-                                     opener:nil
-                                openedByDOM:NO
-                                    atIndex:tabIndex
-                               inBackground:NO];
+  TabInsertionBrowserAgent::FromBrowser(browser)->InsertWebState(
+      urlLoadParams.web_params, nil, false, tabIndex, false);
 
   // Tell the delegate to display the tab.
   DCHECK(self.delegate);
   [self.delegate tabSwitcher:self
-      shouldFinishWithActiveModel:targetModel
+      shouldFinishWithActiveModel:browser->GetTabModel()
                      focusOmnibox:NO];
 }
 
diff --git a/ios/chrome/browser/ui/tab_grid/tab_switcher.h b/ios/chrome/browser/ui/tab_grid/tab_switcher.h
index 22b19f4..f7628dac 100644
--- a/ios/chrome/browser/ui/tab_grid/tab_switcher.h
+++ b/ios/chrome/browser/ui/tab_grid/tab_switcher.h
@@ -11,6 +11,7 @@
 #include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
+class Browser;
 @protocol OmniboxFocuser;
 @class TabModel;
 @protocol TabSwitcher;
@@ -66,9 +67,9 @@
 //   |-tabSwitcher:shouldFinishWithActiveModel:|
 //   |-tabSwitcherDismissTransitionDidEnd:|
 // to inform the delegate when this animation begins and ends.
-- (void)dismissWithNewTabAnimationToModel:(TabModel*)targetModel
-                        withUrlLoadParams:(const UrlLoadParams&)urlLoadParams
-                                  atIndex:(NSUInteger)position;
+- (void)dismissWithNewTabAnimationToBrowser:(Browser*)browser
+                          withUrlLoadParams:(const UrlLoadParams&)urlLoadParams
+                                    atIndex:(int)position;
 
 // Updates the OTR (Off The Record) tab model. Should only be called when both
 // the current OTR tab model and the new OTR tab model are either nil or contain
diff --git a/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h b/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h
index b0d2b45..204cd640 100644
--- a/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h
+++ b/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h
@@ -23,12 +23,10 @@
 // The main presented view.
 @property(nonatomic, strong, readonly) UIView* backgroundView;
 
-// Adds the provided |toolbarAccessoryView| as an accessory using the
-// |toolbarView| for positioning. Calls the provided |completion| after adding
-// the view. There can only be one toolbar view presented at a time. If there is
-// a view already presented, this is a no-op.
+// Adds the provided |toolbarAccessoryView| as an accessory. Calls the provided
+// |completion| after adding the view. There can only be one toolbar view
+// presented at a time. If there is a view already presented, this is a no-op.
 - (void)addToolbarAccessoryView:(UIView*)toolbarAccessoryView
-               usingToolbarView:(UIView*)toolbarView
                        animated:(BOOL)animated
                      completion:(void (^)())completion;
 
diff --git a/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.mm b/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.mm
index 225e9ee..4400922 100644
--- a/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.mm
+++ b/ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.mm
@@ -9,6 +9,7 @@
 #import "ios/chrome/browser/ui/image_util/image_util.h"
 #import "ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_constants.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h"
+#import "ios/chrome/browser/ui/util/layout_guide_names.h"
 #import "ios/chrome/browser/ui/util/named_guide.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/colors/dynamic_color_util.h"
@@ -62,7 +63,6 @@
 }
 
 - (void)addToolbarAccessoryView:(UIView*)toolbarAccessoryView
-               usingToolbarView:(UIView*)toolbarView
                        animated:(BOOL)animated
                      completion:(void (^)())completion {
   if (self.backgroundView) {
@@ -72,12 +72,10 @@
 
   if (ShouldShowCompactToolbar()) {
     [self showIPhoneToolbarAccessoryView:toolbarAccessoryView
-                        usingToolbarView:toolbarView
                                 animated:animated
                               completion:completion];
   } else {
     [self showIPadToolbarAccessoryView:toolbarAccessoryView
-                      usingToolbarView:toolbarView
                               animated:animated
                             completion:completion];
   }
@@ -128,7 +126,6 @@
 // Animates accessory to iPad positioning: A small view in the top right, just
 // below the toolbar.
 - (void)showIPadToolbarAccessoryView:(UIView*)toolbarAccessoryView
-                    usingToolbarView:(UIView*)toolbarView
                             animated:(BOOL)animated
                           completion:(void (^)())completion {
   DCHECK(IsIPadIdiom());
@@ -156,10 +153,14 @@
   NSLayoutConstraint* animationConstraint = [self.backgroundView.leadingAnchor
       constraintEqualToAnchor:self.baseViewController.view.trailingAnchor];
 
+  UILayoutGuide* toolbarLayoutGuide =
+      [NamedGuide guideWithName:kPrimaryToolbarGuide
+                           view:self.baseViewController.view];
+
   [NSLayoutConstraint activateConstraints:@[
     // Anchors accessory below the |toolbarView|.
     [self.backgroundView.topAnchor
-        constraintEqualToAnchor:toolbarView.bottomAnchor],
+        constraintEqualToAnchor:toolbarLayoutGuide.bottomAnchor],
     animationConstraint,
     widthConstraint,
     [self.backgroundView.widthAnchor
@@ -200,7 +201,6 @@
 
 // Animates accessory to iPhone positioning: covering the whole toolbar.
 - (void)showIPhoneToolbarAccessoryView:(UIView*)toolbarAccessoryView
-                      usingToolbarView:(UIView*)toolbarView
                               animated:(BOOL)animated
                             completion:(nullable void (^)())completion {
   self.backgroundView =
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
index 6e7cdb8b..1d1497b 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
@@ -176,6 +176,18 @@
       ToolbarExpandedHeight(self.traitCollection.preferredContentSizeCategory));
 }
 
+- (void)willMoveToWindow:(UIWindow*)newWindow {
+  [super willMoveToWindow:newWindow];
+  [NamedGuide guideWithName:kPrimaryToolbarGuide view:self].constrainedView =
+      nil;
+}
+
+- (void)didMoveToWindow {
+  [super didMoveToWindow];
+  [NamedGuide guideWithName:kPrimaryToolbarGuide view:self].constrainedView =
+      self;
+}
+
 #pragma mark - Setup
 
 // Sets up the toolbar background.
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc
index 369afa1..900feecd 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.cc
+++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -29,7 +29,7 @@
                                       base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kEmbedderBlockRestoreUrl{"EmbedderBlockRestoreUrl",
-                                             base::FEATURE_ENABLED_BY_DEFAULT};
+                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kDisableAnimationOnLowBattery{
     "DisableAnimationOnLowBattery", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.h b/ios/chrome/browser/ui/util/layout_guide_names.h
index 7a70e7a..d3422d5 100644
--- a/ios/chrome/browser/ui/util/layout_guide_names.h
+++ b/ios/chrome/browser/ui/util/layout_guide_names.h
@@ -15,6 +15,10 @@
 
 // A guide that is constrained to match the frame of the tab's content area.
 extern GuideName* const kContentAreaGuide;
+// A guide that is constrained to match the frame of the primary toolbar. This
+// follows the frame of the primary toolbar even when that frame shrinks due to
+// fullscreen. It does not include the tab strip on iPad.
+extern GuideName* const kPrimaryToolbarGuide;
 // A guide that is constrained to match the frame of the secondary toolbar.
 extern GuideName* const kSecondaryToolbarGuide;
 // A guide that is constrained to match the frame the secondary toolbar would
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.mm b/ios/chrome/browser/ui/util/layout_guide_names.mm
index 7974262c..0a7bb75 100644
--- a/ios/chrome/browser/ui/util/layout_guide_names.mm
+++ b/ios/chrome/browser/ui/util/layout_guide_names.mm
@@ -9,6 +9,7 @@
 #endif
 
 GuideName* const kContentAreaGuide = @"ContentAreaGuide";
+GuideName* const kPrimaryToolbarGuide = @"kPrimaryToolbarGuide";
 GuideName* const kSecondaryToolbarGuide = @"kSecondaryToolbarGuide";
 GuideName* const kSecondaryToolbarNoFullscreenGuide =
     @"kSecondaryToolbarNoFullscreenGuide";
diff --git a/ios/chrome/browser/url_loading/url_loading_service.mm b/ios/chrome/browser/url_loading/url_loading_service.mm
index 1cd9704..d58e2aac 100644
--- a/ios/chrome/browser/url_loading/url_loading_service.mm
+++ b/ios/chrome/browser/url_loading/url_loading_service.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/browser/url_loading/url_loading_service_factory.h"
 #import "ios/chrome/browser/url_loading/url_loading_util.h"
 #import "ios/chrome/browser/web/load_timing_tab_helper.h"
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #include "net/base/url_util.h"
 
@@ -283,21 +284,17 @@
   // lead to be calling it twice, and calling 'did' below once.
   notifier_->NewTabWillLoadUrl(params.web_params.url, params.user_initiated);
 
-  TabModel* tab_model = browser_->GetTabModel();
-
   web::WebState* adjacent_web_state = nil;
   if (params.append_to == kCurrentTab)
-    adjacent_web_state = tab_model.webStateList->GetActiveWebState();
+    adjacent_web_state = browser_->GetWebStateList()->GetActiveWebState();
 
   UrlLoadParams saved_params = params;
   auto openTab = ^{
-    [tab_model insertWebStateWithLoadParams:saved_params.web_params
-                                     opener:adjacent_web_state
-                                openedByDOM:NO
-                                    atIndex:TabModelConstants::
-                                                kTabPositionAutomatically
-                               inBackground:saved_params.in_background()];
-
+    TabInsertionBrowserAgent* insertionAgent =
+        TabInsertionBrowserAgent::FromBrowser(browser_);
+    insertionAgent->InsertWebState(saved_params.web_params, adjacent_web_state,
+                                   false, TabInsertion::kPositionAutomatically,
+                                   saved_params.in_background());
     notifier_->NewTabDidLoadUrl(saved_params.web_params.url,
                                 saved_params.user_initiated);
   };
diff --git a/ios/chrome/browser/url_loading/url_loading_service_unittest.mm b/ios/chrome/browser/url_loading/url_loading_service_unittest.mm
index 15e31de..7ebc2e1c 100644
--- a/ios/chrome/browser/url_loading/url_loading_service_unittest.mm
+++ b/ios/chrome/browser/url_loading/url_loading_service_unittest.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
 #import "ios/chrome/browser/url_loading/url_loading_service_factory.h"
 #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
 #include "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_opener.h"
 #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h"
@@ -65,13 +66,13 @@
                       (const web::NavigationManager::WebLoadParams&)loadParams
                                         opener:(web::WebState*)parentWebState
                                    openedByDOM:(BOOL)openedByDOM
-                                       atIndex:(NSUInteger)index
+                                       atIndex:(int)index
                                   inBackground:(BOOL)inBackground {
   int insertionIndex = WebStateList::kInvalidIndex;
   int insertionFlags = WebStateList::INSERT_NO_FLAGS;
-  if (index != TabModelConstants::kTabPositionAutomatically) {
-    DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
-    insertionIndex = static_cast<int>(index);
+  if (index != TabInsertion::kPositionAutomatically) {
+    DCHECK_LE(index, INT_MAX);
+    insertionIndex = index;
     insertionFlags |= WebStateList::INSERT_FORCE_INDEX;
   } else if (!ui::PageTransitionCoreTypeIs(loadParams.transition_type,
                                            ui::PAGE_TRANSITION_LINK)) {
@@ -138,6 +139,7 @@
     id tabModel = CreateTestTabModel(chrome_browser_state_.get());
     tab_model_ = tabModel;
     browser_ = new TestBrowser(chrome_browser_state_.get(), tabModel);
+    TabInsertionBrowserAgent::CreateForBrowser(browser_);
     service_ = UrlLoadingServiceFactory::GetForBrowserState(
         chrome_browser_state_.get());
     service_->SetDelegate(url_loading_delegate_);
@@ -150,6 +152,7 @@
     id otrTabModel = CreateTestTabModel(otr_browser_state);
     otr_tab_model_ = otrTabModel;
     otr_browser_ = new TestBrowser(otr_browser_state, otrTabModel);
+    TabInsertionBrowserAgent::CreateForBrowser(otr_browser_);
     otr_service_ =
         UrlLoadingServiceFactory::GetForBrowserState(otr_browser_state);
     otr_service_->SetDelegate(url_loading_delegate_);
diff --git a/ios/chrome/browser/web/web_state_delegate_tab_helper.mm b/ios/chrome/browser/web/web_state_delegate_tab_helper.mm
index 7e142a3..86d1230 100644
--- a/ios/chrome/browser/web/web_state_delegate_tab_helper.mm
+++ b/ios/chrome/browser/web/web_state_delegate_tab_helper.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/web/web_state_delegate_tab_helper.h"
 
 #import "base/strings/sys_string_conversions.h"
+#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
 #include "ios/chrome/browser/overlays/public/overlay_modality.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
@@ -44,7 +45,7 @@
   std::unique_ptr<OverlayRequest> request =
       OverlayRequest::CreateWithConfig<HTTPAuthOverlayRequestConfig>(
           message, default_username);
-  request->set_callback(
+  request->GetCallbackManager()->AddCompletionCallback(
       base::BindOnce(&WebStateDelegateTabHelper::OnHTTPAuthOverlayFinished,
                      weak_factory_.GetWeakPtr(), callback));
   OverlayRequestQueue::FromWebState(source, OverlayModality::kWebContentArea)
diff --git a/ios/chrome/browser/web_state_list/BUILD.gn b/ios/chrome/browser/web_state_list/BUILD.gn
index 92a391b..d4c66b1 100644
--- a/ios/chrome/browser/web_state_list/BUILD.gn
+++ b/ios/chrome/browser/web_state_list/BUILD.gn
@@ -8,6 +8,8 @@
     "active_web_state_observation_forwarder.mm",
     "all_web_state_observation_forwarder.h",
     "all_web_state_observation_forwarder.mm",
+    "tab_insertion_browser_agent.h",
+    "tab_insertion_browser_agent.mm",
     "web_state_list.h",
     "web_state_list.mm",
     "web_state_list_delegate.h",
@@ -30,6 +32,9 @@
     "//base",
     "//components/favicon/core",
     "//components/favicon/ios",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/main:public",
+    "//ios/chrome/browser/sessions:restoration_observer",
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/web",
     "//ios/web/public/session",
@@ -56,6 +61,7 @@
   sources = [
     "active_web_state_observation_forwarder_unittest.mm",
     "all_web_state_observation_forwarder_unittest.mm",
+    "tab_insertion_browser_agent_unittest.mm",
     "web_state_list_favicon_driver_observer_unittest.mm",
     "web_state_list_order_controller_unittest.mm",
     "web_state_list_serialization_unittest.mm",
@@ -67,7 +73,10 @@
     ":web_state_list",
     "//base",
     "//components/favicon/ios",
+    "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/browser_state:test_support",
+    "//ios/chrome/browser/main",
+    "//ios/chrome/browser/main:test_support",
     "//ios/chrome/browser/sessions:serialisation",
     "//ios/chrome/browser/web",
     "//ios/web",
diff --git a/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h
new file mode 100644
index 0000000..011f723
--- /dev/null
+++ b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_WEB_STATE_LIST_TAB_INSERTION_BROWSER_AGENT_H_
+#define IOS_CHROME_BROWSER_WEB_STATE_LIST_TAB_INSERTION_BROWSER_AGENT_H_
+
+#import <Foundation/Foundation.h>
+
+#include "ios/chrome/browser/main/browser_user_data.h"
+#import "ios/web/public/navigation/navigation_manager.h"
+
+namespace ios {
+class ChromeBrowserState;
+}
+namespace web {
+class WebState;
+}
+class WebStateList;
+
+namespace TabInsertion {
+
+// Position the tab automatically. This value is used as index parameter in
+// methods that require an index when the caller doesn't have a preference
+// on the position where the tab will be open.
+int const kPositionAutomatically = -1;
+
+}  // namespace TabInsertion
+
+class TabInsertionBrowserAgent
+    : public BrowserUserData<TabInsertionBrowserAgent> {
+ public:
+  ~TabInsertionBrowserAgent() override;
+
+  web::WebState* InsertWebState(
+      const web::NavigationManager::WebLoadParams& params,
+      web::WebState* parent,
+      bool opened_by_dom,
+      int index,
+      bool in_background);
+
+  web::WebState* InsertWebStateOpenedByDOM(web::WebState* parent);
+
+ private:
+  explicit TabInsertionBrowserAgent(Browser* browser);
+  friend class BrowserUserData<TabInsertionBrowserAgent>;
+  BROWSER_USER_DATA_KEY_DECL();
+
+  ios::ChromeBrowserState* browser_state_;
+  WebStateList* web_state_list_;
+};
+
+#endif  // IOS_CHROME_BROWSER_WEB_STATE_LIST_TAB_INSERTION_BROWSER_AGENT_H_
diff --git a/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.mm b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.mm
new file mode 100644
index 0000000..ae01d566
--- /dev/null
+++ b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent.mm
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/web_state_list/web_state_opener.h"
+#import "ios/web/public/web_state.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+BROWSER_USER_DATA_KEY_IMPL(TabInsertionBrowserAgent)
+
+TabInsertionBrowserAgent::TabInsertionBrowserAgent(Browser* browser)
+    : browser_state_(browser->GetBrowserState()),
+      web_state_list_(browser->GetWebStateList()) {}
+
+TabInsertionBrowserAgent::~TabInsertionBrowserAgent() {}
+
+web::WebState* TabInsertionBrowserAgent::InsertWebState(
+    const web::NavigationManager::WebLoadParams& params,
+    web::WebState* parent,
+    bool opened_by_dom,
+    int index,
+    bool in_background) {
+  DCHECK(index == TabInsertion::kPositionAutomatically ||
+         (index >= 0 && index <= web_state_list_->count()));
+
+  int insertion_index = WebStateList::kInvalidIndex;
+  int insertion_flags = WebStateList::INSERT_NO_FLAGS;
+  if (index != TabInsertion::kPositionAutomatically) {
+    DCHECK_LE(index, INT_MAX);
+    insertion_index = static_cast<int>(index);
+    insertion_flags |= WebStateList::INSERT_FORCE_INDEX;
+  } else if (!ui::PageTransitionCoreTypeIs(params.transition_type,
+                                           ui::PAGE_TRANSITION_LINK)) {
+    insertion_index = web_state_list_->count();
+    insertion_flags |= WebStateList::INSERT_FORCE_INDEX;
+  }
+
+  if (!in_background) {
+    insertion_flags |= WebStateList::INSERT_ACTIVATE;
+  }
+
+  web::WebState::CreateParams create_params(browser_state_);
+  create_params.created_with_opener = opened_by_dom;
+
+  std::unique_ptr<web::WebState> web_state =
+      web::WebState::Create(create_params);
+  web_state->GetNavigationManager()->LoadURLWithParams(params);
+
+  int inserted_index =
+      web_state_list_->InsertWebState(insertion_index, std::move(web_state),
+                                      insertion_flags, WebStateOpener(parent));
+
+  return web_state_list_->GetWebStateAt(inserted_index);
+}
+
+web::WebState* TabInsertionBrowserAgent::InsertWebStateOpenedByDOM(
+    web::WebState* parent) {
+  web::WebState::CreateParams createParams(browser_state_);
+  createParams.created_with_opener = YES;
+  std::unique_ptr<web::WebState> web_state =
+      web::WebState::Create(createParams);
+  int insertionFlags =
+      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE;
+  int insertedIndex = web_state_list_->InsertWebState(
+      web_state_list_->count(), std::move(web_state), insertionFlags,
+      WebStateOpener(parent));
+
+  return web_state_list_->GetWebStateAt(insertedIndex);
+}
diff --git a/ios/chrome/browser/web_state_list/tab_insertion_browser_agent_unittest.mm b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent_unittest.mm
new file mode 100644
index 0000000..41a6ad4
--- /dev/null
+++ b/ios/chrome/browser/web_state_list/tab_insertion_browser_agent_unittest.mm
@@ -0,0 +1,191 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h"
+
+#import "ios/chrome/browser/main/browser.h"
+#import "ios/chrome/browser/main/test_browser.h"
+#import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/web/public/navigation/navigation_manager.h"
+#include "ios/web/public/navigation/referrer.h"
+#include "ios/web/public/test/web_task_environment.h"
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+const char kURL1[] = "https://www.some.url.com";
+
+class TabInsertionBrowserAgentTest : public PlatformTest {
+ public:
+  TabInsertionBrowserAgentTest() : browser_(std::make_unique<TestBrowser>()) {
+    TabInsertionBrowserAgent::CreateForBrowser(browser_.get());
+    agent_ = TabInsertionBrowserAgent::FromBrowser(browser_.get());
+  }
+
+  const web::NavigationManager::WebLoadParams Params(GURL url) {
+    return Params(url, ui::PAGE_TRANSITION_TYPED);
+  }
+
+  const web::NavigationManager::WebLoadParams Params(
+      GURL url,
+      ui::PageTransition transition) {
+    web::NavigationManager::WebLoadParams loadParams(url);
+    loadParams.referrer = web::Referrer();
+    loadParams.transition_type = transition;
+    return loadParams;
+  }
+
+ protected:
+  web::WebTaskEnvironment task_environment_;
+  std::unique_ptr<Browser> browser_;
+  TabInsertionBrowserAgent* agent_;
+};
+
+}  // namespace
+
+TEST_F(TabInsertionBrowserAgentTest, InsertUrlSingle) {
+  web::WebState* web_state = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                    /*parent=*/nil,
+                                                    /*opened_by_dom=*/false,
+                                                    /*index=*/0,
+                                                    /*in_background=*/false);
+  ASSERT_EQ(1, browser_->GetWebStateList()->count());
+  EXPECT_EQ(web_state, browser_->GetWebStateList()->GetWebStateAt(0));
+}
+
+TEST_F(TabInsertionBrowserAgentTest, InsertUrlMultiple) {
+  web::WebState* web_state0 = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                     /*parent=*/nil,
+                                                     /*opened_by_dom=*/false,
+                                                     /*index=*/0,
+                                                     /*in_background=*/false);
+  web::WebState* web_state1 = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                     /*parent=*/nil,
+                                                     /*opened_by_dom=*/false,
+                                                     /*index=*/0,
+                                                     /*in_background=*/false);
+
+  web::WebState* web_state2 = agent_->InsertWebState(Params(GURL(kURL1)),
+                                                     /*parent=*/nil,
+                                                     /*opened_by_dom=*/false,
+                                                     /*index=*/1,
+                                                     /*in_background=*/false);
+
+  ASSERT_EQ(3, browser_->GetWebStateList()->count());
+  EXPECT_EQ(web_state1, browser_->GetWebStateList()->GetWebStateAt(0));
+  EXPECT_EQ(web_state2, browser_->GetWebStateList()->GetWebStateAt(1));
+  EXPECT_EQ(web_state0, browser_->GetWebStateList()->GetWebStateAt(2));
+}
+
+TEST_F(TabInsertionBrowserAgentTest, AppendUrlSingle) {
+  web::WebState* web_state =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+
+  ASSERT_EQ(1, browser_->GetWebStateList()->count());
+  EXPECT_EQ(web_state, browser_->GetWebStateList()->GetWebStateAt(0));
+}
+
+TEST_F(TabInsertionBrowserAgentTest, AppendUrlMultiple) {
+  web::WebState* web_state0 =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+  web::WebState* web_state1 =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+  web::WebState* web_state2 =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+
+  ASSERT_EQ(3, browser_->GetWebStateList()->count());
+  EXPECT_EQ(web_state0, browser_->GetWebStateList()->GetWebStateAt(0));
+  EXPECT_EQ(web_state1, browser_->GetWebStateList()->GetWebStateAt(1));
+  EXPECT_EQ(web_state2, browser_->GetWebStateList()->GetWebStateAt(2));
+}
+
+TEST_F(TabInsertionBrowserAgentTest, AddWithOrderController) {
+  // Create a few tabs with the controller at the front.
+  web::WebState* parent =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/browser_->GetWebStateList()->count(),
+                         /*in_background=*/false);
+  agent_->InsertWebState(Params(GURL(kURL1)),
+                         /*parent=*/nil,
+                         /*opened_by_dom=*/false,
+                         /*index=*/browser_->GetWebStateList()->count(),
+                         /*in_background=*/false);
+
+  // Add a new tab, it should be added behind the parent.
+  web::WebState* child =
+      agent_->InsertWebState(Params(GURL(kURL1), ui::PAGE_TRANSITION_LINK),
+                             /*parent=*/parent,
+                             /*opened_by_dom=*/false,
+                             /*index=*/TabInsertion::kPositionAutomatically,
+                             /*in_background=*/false);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(parent), 0);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(child), 1);
+
+  // Add another new tab without a parent, should go at the end.
+  web::WebState* web_state =
+      agent_->InsertWebState(Params(GURL(kURL1), ui::PAGE_TRANSITION_LINK),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/TabInsertion::kPositionAutomatically,
+                             /*in_background=*/false);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(web_state),
+            browser_->GetWebStateList()->count() - 1);
+
+  // Same for a tab that's not opened via a LINK transition.
+  web::WebState* web_state2 =
+      agent_->InsertWebState(Params(GURL(kURL1)),
+                             /*parent=*/nil,
+                             /*opened_by_dom=*/false,
+                             /*index=*/browser_->GetWebStateList()->count(),
+                             /*in_background=*/false);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(web_state2),
+            browser_->GetWebStateList()->count() - 1);
+
+  // Add a tab in the background. It should appear behind the opening tab.
+  web::WebState* web_state3 =
+      agent_->InsertWebState(Params(GURL(kURL1), ui::PAGE_TRANSITION_LINK),
+                             /*parent=*/web_state,
+                             /*opened_by_dom=*/false,
+                             /*index=*/TabInsertion::kPositionAutomatically,
+                             /*in_background=*/false);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(web_state3),
+            browser_->GetWebStateList()->GetIndexOfWebState(web_state) + 1);
+
+  // Add another background tab behind the one we just opened.
+  web::WebState* web_state4 =
+      agent_->InsertWebState(Params(GURL(kURL1), ui::PAGE_TRANSITION_LINK),
+                             /*parent=*/web_state3,
+                             /*opened_by_dom=*/false,
+                             /*index=*/TabInsertion::kPositionAutomatically,
+                             /*in_background=*/false);
+  EXPECT_EQ(browser_->GetWebStateList()->GetIndexOfWebState(web_state4),
+            browser_->GetWebStateList()->GetIndexOfWebState(web_state3) + 1);
+}
diff --git a/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.h b/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.h
index 3cda7c0..912dc6d 100644
--- a/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.h
+++ b/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.h
@@ -6,20 +6,17 @@
 #define IOS_CHROME_BROWSER_WEB_STATE_LIST_WEB_STATE_LIST_METRICS_OBSERVER_H_
 
 #include "base/macros.h"
+#include "ios/chrome/browser/sessions/session_restoration_observer.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer.h"
 
-class WebStateListMetricsObserver : public WebStateListObserver {
+class WebStateListMetricsObserver : public WebStateListObserver,
+                                    public SessionRestorationObserver {
  public:
   WebStateListMetricsObserver();
   ~WebStateListMetricsObserver() override;
 
   void RecordSessionMetrics();
 
-  // TODO(crbug.com/1010164): Don't define these methods here. Instead implement
-  // SessionRestorationObserver methods.
-  void WillStartSessionRestoration();
-  void SessionRestorationFinished();
-
   // WebStateListObserver implementation.
   void WebStateInsertedAt(WebStateList* web_state_list,
                           web::WebState* web_state,
@@ -44,6 +41,11 @@
   // Reset metrics counters.
   void ResetSessionMetrics();
 
+  // SessionRestorationObserver implementation.
+  void WillStartSessionRestoration() override;
+  void SessionRestorationFinished(
+      const std::vector<web::WebState*>& restored_web_states) override;
+
   DISALLOW_COPY_AND_ASSIGN(WebStateListMetricsObserver);
 };
 
diff --git a/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.mm b/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.mm
index 9ed4c248..f4017c9f 100644
--- a/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.mm
+++ b/ios/chrome/browser/web_state_list/web_state_list_metrics_observer.mm
@@ -32,7 +32,8 @@
   metric_collection_paused_ = true;
 }
 
-void WebStateListMetricsObserver::SessionRestorationFinished() {
+void WebStateListMetricsObserver::SessionRestorationFinished(
+    const std::vector<web::WebState*>& restored_web_states) {
   metric_collection_paused_ = false;
 }
 
diff --git a/ios/chrome/test/app/tab_test_util.mm b/ios/chrome/test/app/tab_test_util.mm
index c6abe8e4..fc565cd 100644
--- a/ios/chrome/test/app/tab_test_util.mm
+++ b/ios/chrome/test/app/tab_test_util.mm
@@ -59,13 +59,13 @@
       return;
     }
       // The TabGrid is currently presented.
-    TabModel* tabModel =
-        GetMainController().interfaceProvider.mainInterface.tabModel;
+    Browser* browser =
+        GetMainController().interfaceProvider.mainInterface.browser;
     UrlLoadParams params = UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL));
     [GetMainController().tabSwitcher
-        dismissWithNewTabAnimationToModel:tabModel
-                        withUrlLoadParams:params
-                                  atIndex:NSNotFound];
+        dismissWithNewTabAnimationToBrowser:browser
+                          withUrlLoadParams:params
+                                    atIndex:INT_MAX];
   }
 }
 
@@ -79,13 +79,13 @@
       return;
     }
       // The TabGrid is currently presented.
-    TabModel* tabModel =
-        GetMainController().interfaceProvider.incognitoInterface.tabModel;
+    Browser* browser =
+        GetMainController().interfaceProvider.incognitoInterface.browser;
     UrlLoadParams params = UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL));
     [GetMainController().tabSwitcher
-        dismissWithNewTabAnimationToModel:tabModel
-                        withUrlLoadParams:params
-                                  atIndex:NSNotFound];
+        dismissWithNewTabAnimationToBrowser:browser
+                          withUrlLoadParams:params
+                                    atIndex:INT_MAX];
   }
 }
 
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index b29b5e4..8b0f9ce 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -72,6 +72,7 @@
   deps = [
     "//ios/chrome/browser/ui/settings:eg2_tests",
     "//ios/chrome/browser/ui/settings/autofill:eg2_tests",
+    "//ios/chrome/browser/ui/settings/clear_browsing_data:eg2_tests",
     "//ios/chrome/browser/ui/settings/password:eg2_tests",
   ]
 }
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn
index a6f4c52..3281199 100644
--- a/ios/third_party/material_components_ios/BUILD.gn
+++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -59,8 +59,6 @@
   "src/components/BottomAppBar/src/MaterialBottomAppBar.h",
   "src/components/BottomAppBar/src/private/MDCBottomAppBarAttributes.h",
   "src/components/BottomAppBar/src/private/MDCBottomAppBarLayer.h",
-  "src/components/BottomNavigation/src/ColorThemer/MDCBottomNavigationBarColorThemer.h",
-  "src/components/BottomNavigation/src/ColorThemer/MaterialBottomNavigation+ColorThemer.h",
   "src/components/BottomNavigation/src/MDCBottomNavigationBar.h",
   "src/components/BottomNavigation/src/MDCBottomNavigationBarController.h",
   "src/components/BottomNavigation/src/MaterialBottomNavigation.h",
@@ -123,16 +121,9 @@
   "src/components/Buttons/src/TypographyThemer/MDCButtonTypographyThemer.h",
   "src/components/Buttons/src/TypographyThemer/MaterialButtons+TypographyThemer.h",
   "src/components/Buttons/src/private/MDCButton+Subclassing.h",
-  "src/components/Cards/src/CardThemer/MDCCardScheme.h",
-  "src/components/Cards/src/CardThemer/MDCCardThemer.h",
-  "src/components/Cards/src/CardThemer/MaterialCards+CardThemer.h",
-  "src/components/Cards/src/ColorThemer/MDCCardsColorThemer.h",
-  "src/components/Cards/src/ColorThemer/MaterialCards+ColorThemer.h",
   "src/components/Cards/src/MDCCard.h",
   "src/components/Cards/src/MDCCardCollectionCell.h",
   "src/components/Cards/src/MaterialCards.h",
-  "src/components/Cards/src/ShapeThemer/MDCCardsShapeThemer.h",
-  "src/components/Cards/src/ShapeThemer/MaterialCards+ShapeThemer.h",
   "src/components/Cards/src/Theming/MDCCard+MaterialTheming.h",
   "src/components/Cards/src/Theming/MDCCardCollectionCell+MaterialTheming.h",
   "src/components/Cards/src/Theming/MaterialCards+Theming.h",
@@ -195,8 +186,6 @@
   "src/components/FeatureHighlight/src/ColorThemer/MaterialFeatureHighlight+ColorThemer.h",
   "src/components/FeatureHighlight/src/FeatureHighlightAccessibilityMutator/MDCFeatureHighlightAccessibilityMutator.h",
   "src/components/FeatureHighlight/src/FeatureHighlightAccessibilityMutator/MaterialFeatureHighlight+FeatureHighlightAccessibilityMutator.h",
-  "src/components/FeatureHighlight/src/FontThemer/MDCFeatureHighlightFontThemer.h",
-  "src/components/FeatureHighlight/src/FontThemer/MaterialFeatureHighlight+FontThemer.h",
   "src/components/FeatureHighlight/src/MDCFeatureHighlightView.h",
   "src/components/FeatureHighlight/src/MDCFeatureHighlightViewController.h",
   "src/components/FeatureHighlight/src/MaterialFeatureHighlight.h",
@@ -225,8 +214,6 @@
   "src/components/HeaderStackView/src/ColorThemer/MaterialHeaderStackView+ColorThemer.h",
   "src/components/HeaderStackView/src/MDCHeaderStackView.h",
   "src/components/HeaderStackView/src/MaterialHeaderStackView.h",
-  "src/components/Ink/src/ColorThemer/MDCInkColorThemer.h",
-  "src/components/Ink/src/ColorThemer/MaterialInk+ColorThemer.h",
   "src/components/Ink/src/MDCInkGestureRecognizer.h",
   "src/components/Ink/src/MDCInkTouchController.h",
   "src/components/Ink/src/MDCInkView.h",
@@ -238,9 +225,6 @@
   "src/components/LibraryInfo/src/MaterialLibraryInfo.h",
   "src/components/List/src/ColorThemer/MDCListColorThemer.h",
   "src/components/List/src/ColorThemer/MaterialList+ColorThemer.h",
-  "src/components/List/src/ListThemer/MDCListScheme.h",
-  "src/components/List/src/ListThemer/MDCListThemer.h",
-  "src/components/List/src/ListThemer/MaterialList+ListThemer.h",
   "src/components/List/src/MDCBaseCell.h",
   "src/components/List/src/MDCSelfSizingStereoCell.h",
   "src/components/List/src/MaterialList.h",
@@ -269,8 +253,6 @@
   "src/components/NavigationDrawer/src/private/MDCBottomDrawerShadowedView.h",
   "src/components/OverlayWindow/src/MDCOverlayWindow.h",
   "src/components/OverlayWindow/src/MaterialOverlayWindow.h",
-  "src/components/PageControl/src/ColorThemer/MDCPageControlColorThemer.h",
-  "src/components/PageControl/src/ColorThemer/MaterialPageControl+ColorThemer.h",
   "src/components/PageControl/src/MDCPageControl.h",
   "src/components/PageControl/src/MaterialPageControl.h",
   "src/components/PageControl/src/private/MDCPageControlIndicator.h",
@@ -281,8 +263,6 @@
   "src/components/Palettes/src/MaterialPalettes.h",
   "src/components/Palettes/src/private/MDCPaletteExpansions.h",
   "src/components/Palettes/src/private/MDCPaletteNames.h",
-  "src/components/ProgressView/src/ColorThemer/MDCProgressViewColorThemer.h",
-  "src/components/ProgressView/src/ColorThemer/MaterialProgressView+ColorThemer.h",
   "src/components/ProgressView/src/MDCProgressView.h",
   "src/components/ProgressView/src/MaterialProgressView.h",
   "src/components/ProgressView/src/Theming/MDCProgressView+MaterialTheming.h",
@@ -320,8 +300,6 @@
   "src/components/Slider/src/MaterialSlider.h",
   "src/components/Slider/src/private/MDCSlider+Private.h",
   "src/components/Slider/src/private/MDCSlider_Subclassable.h",
-  "src/components/Snackbar/src/ColorThemer/MDCSnackbarColorThemer.h",
-  "src/components/Snackbar/src/ColorThemer/MaterialSnackbar+ColorThemer.h",
   "src/components/Snackbar/src/FontThemer/MDCSnackbarFontThemer.h",
   "src/components/Snackbar/src/FontThemer/MaterialSnackbar+FontThemer.h",
   "src/components/Snackbar/src/MDCSnackbarAlignment.h",
@@ -339,8 +317,6 @@
   "src/components/Snackbar/src/private/MaterialSnackbarStrings_table.h",
   "src/components/Tabs/src/ColorThemer/MDCTabBarColorThemer.h",
   "src/components/Tabs/src/ColorThemer/MaterialTabs+ColorThemer.h",
-  "src/components/Tabs/src/FontThemer/MDCTabBarFontThemer.h",
-  "src/components/Tabs/src/FontThemer/MaterialTabs+FontThemer.h",
   "src/components/Tabs/src/MDCTabBar.h",
   "src/components/Tabs/src/MDCTabBarAlignment.h",
   "src/components/Tabs/src/MDCTabBarDisplayDelegate.h",
@@ -409,8 +385,6 @@
   "src/components/TextFields/src/ColorThemer/MDCFilledTextFieldColorThemer.h",
   "src/components/TextFields/src/ColorThemer/MDCOutlinedTextFieldColorThemer.h",
   "src/components/TextFields/src/ColorThemer/MaterialTextFields+ColorThemer.h",
-  "src/components/TextFields/src/FontThemer/MDCTextFieldFontThemer.h",
-  "src/components/TextFields/src/FontThemer/MaterialTextFields+FontThemer.h",
   "src/components/TextFields/src/MDCIntrinsicHeightTextView.h",
   "src/components/TextFields/src/MDCMultilineTextField.h",
   "src/components/TextFields/src/MDCMultilineTextInputDelegate.h",
@@ -831,9 +805,6 @@
     "src/components/BottomAppBar/src/private/MDCBottomAppBarAttributes.h",
     "src/components/BottomAppBar/src/private/MDCBottomAppBarLayer.h",
     "src/components/BottomAppBar/src/private/MDCBottomAppBarLayer.m",
-    "src/components/BottomNavigation/src/ColorThemer/MDCBottomNavigationBarColorThemer.h",
-    "src/components/BottomNavigation/src/ColorThemer/MDCBottomNavigationBarColorThemer.m",
-    "src/components/BottomNavigation/src/ColorThemer/MaterialBottomNavigation+ColorThemer.h",
     "src/components/BottomNavigation/src/MDCBottomNavigationBar.h",
     "src/components/BottomNavigation/src/MDCBottomNavigationBar.m",
     "src/components/BottomNavigation/src/MDCBottomNavigationBarController.h",
@@ -937,22 +908,11 @@
     "src/components/Buttons/src/TypographyThemer/MDCButtonTypographyThemer.m",
     "src/components/Buttons/src/TypographyThemer/MaterialButtons+TypographyThemer.h",
     "src/components/Buttons/src/private/MDCButton+Subclassing.h",
-    "src/components/Cards/src/CardThemer/MDCCardScheme.h",
-    "src/components/Cards/src/CardThemer/MDCCardScheme.m",
-    "src/components/Cards/src/CardThemer/MDCCardThemer.h",
-    "src/components/Cards/src/CardThemer/MDCCardThemer.m",
-    "src/components/Cards/src/CardThemer/MaterialCards+CardThemer.h",
-    "src/components/Cards/src/ColorThemer/MDCCardsColorThemer.h",
-    "src/components/Cards/src/ColorThemer/MDCCardsColorThemer.m",
-    "src/components/Cards/src/ColorThemer/MaterialCards+ColorThemer.h",
     "src/components/Cards/src/MDCCard.h",
     "src/components/Cards/src/MDCCard.m",
     "src/components/Cards/src/MDCCardCollectionCell.h",
     "src/components/Cards/src/MDCCardCollectionCell.m",
     "src/components/Cards/src/MaterialCards.h",
-    "src/components/Cards/src/ShapeThemer/MDCCardsShapeThemer.h",
-    "src/components/Cards/src/ShapeThemer/MDCCardsShapeThemer.m",
-    "src/components/Cards/src/ShapeThemer/MaterialCards+ShapeThemer.h",
     "src/components/Cards/src/Theming/MDCCard+MaterialTheming.h",
     "src/components/Cards/src/Theming/MDCCard+MaterialTheming.m",
     "src/components/Cards/src/Theming/MDCCardCollectionCell+MaterialTheming.h",
@@ -1051,9 +1011,6 @@
     "src/components/FeatureHighlight/src/FeatureHighlightAccessibilityMutator/MDCFeatureHighlightAccessibilityMutator.h",
     "src/components/FeatureHighlight/src/FeatureHighlightAccessibilityMutator/MDCFeatureHighlightAccessibilityMutator.m",
     "src/components/FeatureHighlight/src/FeatureHighlightAccessibilityMutator/MaterialFeatureHighlight+FeatureHighlightAccessibilityMutator.h",
-    "src/components/FeatureHighlight/src/FontThemer/MDCFeatureHighlightFontThemer.h",
-    "src/components/FeatureHighlight/src/FontThemer/MDCFeatureHighlightFontThemer.m",
-    "src/components/FeatureHighlight/src/FontThemer/MaterialFeatureHighlight+FontThemer.h",
     "src/components/FeatureHighlight/src/MDCFeatureHighlightView.h",
     "src/components/FeatureHighlight/src/MDCFeatureHighlightViewController.h",
     "src/components/FeatureHighlight/src/MDCFeatureHighlightViewController.m",
@@ -1097,9 +1054,6 @@
     "src/components/HeaderStackView/src/MDCHeaderStackView.h",
     "src/components/HeaderStackView/src/MDCHeaderStackView.m",
     "src/components/HeaderStackView/src/MaterialHeaderStackView.h",
-    "src/components/Ink/src/ColorThemer/MDCInkColorThemer.h",
-    "src/components/Ink/src/ColorThemer/MDCInkColorThemer.m",
-    "src/components/Ink/src/ColorThemer/MaterialInk+ColorThemer.h",
     "src/components/Ink/src/MDCInkGestureRecognizer.h",
     "src/components/Ink/src/MDCInkGestureRecognizer.m",
     "src/components/Ink/src/MDCInkTouchController.h",
@@ -1118,11 +1072,6 @@
     "src/components/List/src/ColorThemer/MDCListColorThemer.h",
     "src/components/List/src/ColorThemer/MDCListColorThemer.m",
     "src/components/List/src/ColorThemer/MaterialList+ColorThemer.h",
-    "src/components/List/src/ListThemer/MDCListScheme.h",
-    "src/components/List/src/ListThemer/MDCListScheme.m",
-    "src/components/List/src/ListThemer/MDCListThemer.h",
-    "src/components/List/src/ListThemer/MDCListThemer.m",
-    "src/components/List/src/ListThemer/MaterialList+ListThemer.h",
     "src/components/List/src/MDCBaseCell.h",
     "src/components/List/src/MDCBaseCell.m",
     "src/components/List/src/MDCSelfSizingStereoCell.h",
@@ -1167,9 +1116,6 @@
     "src/components/OverlayWindow/src/MDCOverlayWindow.h",
     "src/components/OverlayWindow/src/MDCOverlayWindow.m",
     "src/components/OverlayWindow/src/MaterialOverlayWindow.h",
-    "src/components/PageControl/src/ColorThemer/MDCPageControlColorThemer.h",
-    "src/components/PageControl/src/ColorThemer/MDCPageControlColorThemer.m",
-    "src/components/PageControl/src/ColorThemer/MaterialPageControl+ColorThemer.h",
     "src/components/PageControl/src/MDCPageControl.h",
     "src/components/PageControl/src/MDCPageControl.m",
     "src/components/PageControl/src/MaterialPageControl.h",
@@ -1186,9 +1132,6 @@
     "src/components/Palettes/src/private/MDCPaletteExpansions.m",
     "src/components/Palettes/src/private/MDCPaletteNames.h",
     "src/components/Palettes/src/private/MDCPaletteNames.m",
-    "src/components/ProgressView/src/ColorThemer/MDCProgressViewColorThemer.h",
-    "src/components/ProgressView/src/ColorThemer/MDCProgressViewColorThemer.m",
-    "src/components/ProgressView/src/ColorThemer/MaterialProgressView+ColorThemer.h",
     "src/components/ProgressView/src/MDCProgressView.h",
     "src/components/ProgressView/src/MDCProgressView.m",
     "src/components/ProgressView/src/MaterialProgressView.h",
@@ -1251,9 +1194,6 @@
     "src/components/Slider/src/MaterialSlider.h",
     "src/components/Slider/src/private/MDCSlider+Private.h",
     "src/components/Slider/src/private/MDCSlider_Subclassable.h",
-    "src/components/Snackbar/src/ColorThemer/MDCSnackbarColorThemer.h",
-    "src/components/Snackbar/src/ColorThemer/MDCSnackbarColorThemer.m",
-    "src/components/Snackbar/src/ColorThemer/MaterialSnackbar+ColorThemer.h",
     "src/components/Snackbar/src/FontThemer/MDCSnackbarFontThemer.h",
     "src/components/Snackbar/src/FontThemer/MDCSnackbarFontThemer.m",
     "src/components/Snackbar/src/FontThemer/MaterialSnackbar+FontThemer.h",
@@ -1278,9 +1218,6 @@
     "src/components/Tabs/src/ColorThemer/MDCTabBarColorThemer.h",
     "src/components/Tabs/src/ColorThemer/MDCTabBarColorThemer.m",
     "src/components/Tabs/src/ColorThemer/MaterialTabs+ColorThemer.h",
-    "src/components/Tabs/src/FontThemer/MDCTabBarFontThemer.h",
-    "src/components/Tabs/src/FontThemer/MDCTabBarFontThemer.m",
-    "src/components/Tabs/src/FontThemer/MaterialTabs+FontThemer.h",
     "src/components/Tabs/src/MDCTabBar.h",
     "src/components/Tabs/src/MDCTabBar.m",
     "src/components/Tabs/src/MDCTabBarAlignment.h",
@@ -1387,9 +1324,6 @@
     "src/components/TextFields/src/ColorThemer/MDCOutlinedTextFieldColorThemer.h",
     "src/components/TextFields/src/ColorThemer/MDCOutlinedTextFieldColorThemer.m",
     "src/components/TextFields/src/ColorThemer/MaterialTextFields+ColorThemer.h",
-    "src/components/TextFields/src/FontThemer/MDCTextFieldFontThemer.h",
-    "src/components/TextFields/src/FontThemer/MDCTextFieldFontThemer.m",
-    "src/components/TextFields/src/FontThemer/MaterialTextFields+FontThemer.h",
     "src/components/TextFields/src/MDCIntrinsicHeightTextView.h",
     "src/components/TextFields/src/MDCIntrinsicHeightTextView.m",
     "src/components/TextFields/src/MDCMultilineTextField.h",
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
index f3b50ad..8c97e32 100644
--- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
+++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
@@ -94,7 +94,7 @@
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    base::OnceClosure callback) override;
   bool HasCreditCardScanFeature() override;
-  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ScanCreditCard(CreditCardScanCallback callback) override;
   void ShowAutofillPopup(
       const gfx::RectF& element_bounds,
       base::i18n::TextDirection text_direction,
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
index 8c5c5c6..c902e581 100644
--- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
+++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -215,8 +215,7 @@
   return false;
 }
 
-void WebViewAutofillClientIOS::ScanCreditCard(
-    const CreditCardScanCallback& callback) {
+void WebViewAutofillClientIOS::ScanCreditCard(CreditCardScanCallback callback) {
   NOTREACHED();
 }
 
diff --git a/media/base/mac/video_frame_mac_unittests.cc b/media/base/mac/video_frame_mac_unittests.cc
index 86ecdf5..f0b6de5 100644
--- a/media/base/mac/video_frame_mac_unittests.cc
+++ b/media/base/mac/video_frame_mac_unittests.cc
@@ -96,7 +96,7 @@
   auto wrapper_frame = VideoFrame::WrapVideoFrame(
       frame, frame->format(), frame->visible_rect(), frame->natural_size());
   wrapper_frame->AddDestructionObserver(
-      base::Bind(&Increment, &instances_destroyed));
+      base::BindOnce(&Increment, &instances_destroyed));
   ASSERT_TRUE(wrapper_frame.get());
 
   auto pb = WrapVideoFrameInCVPixelBuffer(*wrapper_frame);
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 9b679e9..7cf867d 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -59,7 +59,7 @@
                void(BufferingState, BufferingStateChangeReason));
   MOCK_METHOD0(OnDurationChange, void());
   MOCK_METHOD2(OnAddTextTrack,
-               void(const TextTrackConfig&, const AddTextTrackDoneCB&));
+               void(const TextTrackConfig&, AddTextTrackDoneCB));
   MOCK_METHOD1(OnWaiting, void(WaitingReason));
   MOCK_METHOD1(OnAudioConfigChange, void(const AudioDecoderConfig&));
   MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index b09ac029..a7089ff 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -58,7 +58,7 @@
     // Executed whenever a text track is added.
     // The client is expected to create a TextTrack and call |done_cb|.
     virtual void OnAddTextTrack(const TextTrackConfig& config,
-                                const AddTextTrackDoneCB& done_cb) = 0;
+                                AddTextTrackDoneCB done_cb) = 0;
 
     // Executed whenever the pipeline is waiting because of |reason|.
     virtual void OnWaiting(WaitingReason reason) = 0;
diff --git a/media/base/text_renderer.cc b/media/base/text_renderer.cc
index fa57294..ef0d293b 100644
--- a/media/base/text_renderer.cc
+++ b/media/base/text_renderer.cc
@@ -34,7 +34,7 @@
     std::move(pause_cb_).Run();
 }
 
-void TextRenderer::Initialize(const base::Closure& ended_cb) {
+void TextRenderer::Initialize(const base::RepeatingClosure& ended_cb) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(ended_cb);
   DCHECK_EQ(kUninitialized, state_)  << "state_ " << state_;
@@ -103,12 +103,11 @@
   DCHECK(pending_eos_set_.find(text_stream) ==
          pending_eos_set_.end());
 
-  AddTextTrackDoneCB done_cb =
-      BindToCurrentLoop(base::Bind(&TextRenderer::OnAddTextTrackDone,
-                                   weak_factory_.GetWeakPtr(),
-                                   text_stream));
+  AddTextTrackDoneCB done_cb = BindToCurrentLoop(
+      base::BindOnce(&TextRenderer::OnAddTextTrackDone,
+                     weak_factory_.GetWeakPtr(), text_stream));
 
-  add_text_track_cb_.Run(config, done_cb);
+  add_text_track_cb_.Run(config, std::move(done_cb));
 }
 
 void TextRenderer::RemoveTextStream(DemuxerStream* text_stream) {
diff --git a/media/base/text_renderer.h b/media/base/text_renderer.h
index e8348bd..10281794 100644
--- a/media/base/text_renderer.h
+++ b/media/base/text_renderer.h
@@ -45,7 +45,7 @@
 
   // |ended_cb| is executed when all of the text tracks have reached
   // end of stream, following a play request.
-  void Initialize(const base::Closure& ended_cb);
+  void Initialize(const base::RepeatingClosure& ended_cb);
 
   // Starts text track cue decoding and rendering.
   void StartPlaying();
@@ -106,7 +106,7 @@
   const AddTextTrackCB add_text_track_cb_;
 
   // Callbacks provided during Initialize().
-  base::Closure ended_cb_;
+  base::RepeatingClosure ended_cb_;
 
   // Callback provided to Pause().
   base::Closure pause_cb_;
diff --git a/media/base/text_renderer_unittest.cc b/media/base/text_renderer_unittest.cc
index a9fa487..d45eecd 100644
--- a/media/base/text_renderer_unittest.cc
+++ b/media/base/text_renderer_unittest.cc
@@ -58,7 +58,7 @@
         task_environment_.GetMainThreadTaskRunner(),
         base::Bind(&TextRendererTest::OnAddTextTrack, base::Unretained(this))));
     text_renderer_->Initialize(
-        base::Bind(&TextRendererTest::OnEnd, base::Unretained(this)));
+        base::BindRepeating(&TextRendererTest::OnEnd, base::Unretained(this)));
   }
 
   void Destroy() {
@@ -87,7 +87,7 @@
   }
 
   void OnAddTextTrack(const TextTrackConfig& config,
-                      const AddTextTrackDoneCB& done_cb) {
+                      AddTextTrackDoneCB done_cb) {
     base::Closure destroy_cb =
         base::Bind(&TextRendererTest::OnDestroyTextTrack,
                    base::Unretained(this), text_tracks_.size());
@@ -96,7 +96,7 @@
     // text renderer deallocates them.
     text_tracks_.push_back(new FakeTextTrack(destroy_cb, config));
     std::unique_ptr<TextTrack> text_track(text_tracks_.back());
-    done_cb.Run(std::move(text_track));
+    std::move(done_cb).Run(std::move(text_track));
   }
 
   void RemoveTextTrack(unsigned idx) {
diff --git a/media/base/text_track.h b/media/base/text_track.h
index f7ee5ee..4d594a0 100644
--- a/media/base/text_track.h
+++ b/media/base/text_track.h
@@ -25,10 +25,11 @@
                             const std::string& settings) = 0;
 };
 
-using AddTextTrackDoneCB = base::Callback<void(std::unique_ptr<TextTrack>)>;
+using AddTextTrackDoneCB = base::OnceCallback<void(std::unique_ptr<TextTrack>)>;
 
-using AddTextTrackCB = base::Callback<void(const TextTrackConfig& config,
-                                           const AddTextTrackDoneCB& done_cb)>;
+using AddTextTrackCB =
+    base::RepeatingCallback<void(const TextTrackConfig& config,
+                                 AddTextTrackDoneCB done_cb)>;
 
 }  // namespace media
 
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc
index 5fd96c9..b39c625b 100644
--- a/media/blink/resource_multibuffer_data_provider.cc
+++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -85,6 +85,9 @@
   request.SetRequestContext(is_client_audio_element_
                                 ? blink::mojom::RequestContextType::AUDIO
                                 : blink::mojom::RequestContextType::VIDEO);
+  request.SetRequestDestination(
+      is_client_audio_element_ ? network::mojom::RequestDestination::kAudio
+                               : network::mojom::RequestDestination::kVideo);
   request.SetHttpHeaderField(
       WebString::FromUTF8(net::HttpRequestHeaders::kRange),
       WebString::FromUTF8(
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 9d72af0..b9124a72 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -2133,7 +2133,7 @@
 }
 
 void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config,
-                                        const AddTextTrackDoneCB& done_cb) {
+                                        AddTextTrackDoneCB done_cb) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   const WebInbandTextTrackImpl::Kind web_kind =
@@ -2149,7 +2149,7 @@
   std::unique_ptr<TextTrack> text_track(new TextTrackImpl(
       main_task_runner_, client_, std::move(web_inband_text_track)));
 
-  done_cb.Run(std::move(text_track));
+  std::move(done_cb).Run(std::move(text_track));
 }
 
 void WebMediaPlayerImpl::OnWaiting(WaitingReason reason) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index 8972649..7b82f3b0 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -341,7 +341,7 @@
                               BufferingStateChangeReason reason) override;
   void OnDurationChange() override;
   void OnAddTextTrack(const TextTrackConfig& config,
-                      const AddTextTrackDoneCB& done_cb) override;
+                      AddTextTrackDoneCB done_cb) override;
   void OnWaiting(WaitingReason reason) override;
   void OnAudioConfigChange(const AudioDecoderConfig& config) override;
   void OnVideoConfigChange(const VideoDecoderConfig& config) override;
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
index c30e0fa0..e7f90a1 100644
--- a/media/capture/BUILD.gn
+++ b/media/capture/BUILD.gn
@@ -410,7 +410,7 @@
     configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
   }
 
-  if (is_linux) {
+  if (is_chromeos) {
     deps += [ "//media/gpu/test:local_gpu_memory_buffer_manager" ]
   }
 
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
index 393cfdd6..593682b1 100644
--- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
+++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
@@ -1381,10 +1381,11 @@
 
         boolean isInfrared = false;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-            final int infoColor = cameraCharacteristics.get(
+            final Integer infoColor = cameraCharacteristics.get(
                     CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
-            isInfrared =
-                    (infoColor == CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR);
+            isInfrared = infoColor != null
+                    && infoColor.equals(
+                            CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR);
         }
         return "camera2 " + id + ", facing "
                 + ((facing == CameraCharacteristics.LENS_FACING_FRONT) ? "front" : "back")
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc
index 09d32beea..2bb62d90 100644
--- a/media/capture/video/win/video_capture_device_factory_win.cc
+++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -98,7 +98,9 @@
     // HP HD Camera. See https://crbug.com/1011888.
     "04ca:7095",
     // RBG/IR camera for Windows Hello Face Auth. See https://crbug.com/984864.
-    "13d3:5257"};
+    "13d3:5257",
+    // Acer Aspire f5-573g. See https://crbug.com/1034644.
+    "0bda:57f2"};
 
 const std::pair<VideoCaptureApi, std::vector<std::pair<GUID, GUID>>>
     kMfAttributes[] = {{VideoCaptureApi::WIN_MEDIA_FOUNDATION,
diff --git a/media/filters/pipeline_controller_unittest.cc b/media/filters/pipeline_controller_unittest.cc
index d30b0fa..b18e36e9 100644
--- a/media/filters/pipeline_controller_unittest.cc
+++ b/media/filters/pipeline_controller_unittest.cc
@@ -141,7 +141,7 @@
                               BufferingStateChangeReason reason) override {}
   void OnDurationChange() override {}
   void OnAddTextTrack(const TextTrackConfig& config,
-                      const AddTextTrackDoneCB& done_cb) override {}
+                      AddTextTrackDoneCB done_cb) override {}
   void OnWaiting(WaitingReason reason) override {}
   void OnVideoNaturalSizeChange(const gfx::Size& size) override {}
   void OnAudioConfigChange(const AudioDecoderConfig& config) override {}
diff --git a/media/gpu/chromeos/BUILD.gn b/media/gpu/chromeos/BUILD.gn
index e7faacf..c4e922e 100644
--- a/media/gpu/chromeos/BUILD.gn
+++ b/media/gpu/chromeos/BUILD.gn
@@ -51,6 +51,8 @@
     "gpu_buffer_layout.h",
     "image_processor.cc",
     "image_processor.h",
+    "image_processor_backend.cc",
+    "image_processor_backend.h",
     "image_processor_factory.h",
     "image_processor_with_pool.cc",
     "image_processor_with_pool.h",
diff --git a/media/gpu/chromeos/image_processor.cc b/media/gpu/chromeos/image_processor.cc
index b54ec4d..e24ce499 100644
--- a/media/gpu/chromeos/image_processor.cc
+++ b/media/gpu/chromeos/image_processor.cc
@@ -4,11 +4,14 @@
 
 #include "media/gpu/chromeos/image_processor.h"
 
+#include <memory>
 #include <ostream>
 #include <sstream>
 
-#include "base/strings/stringprintf.h"
-#include "media/base/video_frame.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
+#include "base/task/task_traits.h"
 #include "media/base/video_types.h"
 #include "media/gpu/macros.h"
 
@@ -22,20 +25,6 @@
   return ostream;
 }
 
-template <class T>
-std::string VectorToString(const std::vector<T>& vec) {
-  std::ostringstream result;
-  std::string delim;
-  result << "[";
-  for (const T& v : vec) {
-    result << delim << v;
-    if (delim.size() == 0)
-      delim = ", ";
-  }
-  result << "]";
-  return result.str();
-}
-
 // Verify if the format of |frame| matches |config|.
 bool CheckVideoFrameFormat(const ImageProcessor::PortConfig& config,
                            const VideoFrame& frame) {
@@ -65,75 +54,192 @@
 
 }  // namespace
 
-ImageProcessor::PortConfig::PortConfig(const PortConfig&) = default;
+ImageProcessor::ClientCallback::ClientCallback(FrameReadyCB ready_cb)
+    : ready_cb(std::move(ready_cb)) {}
+ImageProcessor::ClientCallback::ClientCallback(
+    LegacyFrameReadyCB legacy_ready_cb)
+    : legacy_ready_cb(std::move(legacy_ready_cb)) {}
+ImageProcessor::ClientCallback::ClientCallback(ClientCallback&&) = default;
+ImageProcessor::ClientCallback::~ClientCallback() = default;
 
-ImageProcessor::PortConfig::PortConfig(
-    Fourcc fourcc,
-    const gfx::Size& size,
-    const std::vector<ColorPlaneLayout>& planes,
-    const gfx::Size& visible_size,
-    const std::vector<VideoFrame::StorageType>& preferred_storage_types)
-    : fourcc(fourcc),
-      size(size),
-      planes(planes),
-      visible_size(visible_size),
-      preferred_storage_types(preferred_storage_types) {}
+// static
+std::unique_ptr<ImageProcessor> ImageProcessor::Create(
+    CreateBackendCB create_backend_cb,
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    const std::vector<OutputMode>& preferred_output_modes,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> client_task_runner) {
+  scoped_refptr<base::SequencedTaskRunner> backend_task_runner =
+      base::CreateSequencedTaskRunner({base::ThreadPool()});
+  auto wrapped_error_cb = base::BindRepeating(
+      base::IgnoreResult(&base::SequencedTaskRunner::PostTask),
+      client_task_runner, FROM_HERE, std::move(error_cb));
+  std::unique_ptr<ImageProcessorBackend> backend =
+      create_backend_cb.Run(input_config, output_config, preferred_output_modes,
+                            std::move(wrapped_error_cb), backend_task_runner);
+  if (!backend)
+    return nullptr;
 
-ImageProcessor::PortConfig::~PortConfig() = default;
-
-std::string ImageProcessor::PortConfig::ToString() const {
-  return base::StringPrintf(
-      "PortConfig(format:%s, size:%s, planes: %s, visible_size:%s, "
-      "storage_types:%s)",
-      fourcc.ToString().c_str(), size.ToString().c_str(),
-      VectorToString(planes).c_str(), visible_size.ToString().c_str(),
-      VectorToString(preferred_storage_types).c_str());
+  return base::WrapUnique(new ImageProcessor(std::move(backend),
+                                             std::move(client_task_runner),
+                                             std::move(backend_task_runner)));
 }
 
 ImageProcessor::ImageProcessor(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
-    OutputMode output_mode,
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner)
-    : input_config_(input_config),
-      output_config_(output_config),
-      output_mode_(output_mode),
-      client_task_runner_(std::move(client_task_runner)) {
+    std::unique_ptr<ImageProcessorBackend> backend,
+    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
+    : backend_(std::move(backend)),
+      client_task_runner_(std::move(client_task_runner)),
+      backend_task_runner_(std::move(backend_task_runner)) {
+  DVLOGF(2);
   DETACH_FROM_SEQUENCE(client_sequence_checker_);
+
+  weak_this_ = weak_this_factory_.GetWeakPtr();
 }
 
-ImageProcessor::~ImageProcessor() = default;
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
-bool ImageProcessor::Process(scoped_refptr<VideoFrame> frame,
-                             LegacyFrameReadyCB cb) {
+ImageProcessor::~ImageProcessor() {
+  DVLOGF(3);
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-  DCHECK_EQ(output_mode(), OutputMode::ALLOCATE);
 
-  return ProcessInternal(std::move(frame), std::move(cb));
-}
+  weak_this_factory_.InvalidateWeakPtrs();
 
-bool ImageProcessor::ProcessInternal(scoped_refptr<VideoFrame> frame,
-                                     LegacyFrameReadyCB cb) {
-  NOTIMPLEMENTED();
-  return false;
+  // Delete |backend_| on |backend_task_runner_|.
+  backend_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          base::DoNothing::Once<std::unique_ptr<ImageProcessorBackend>>(),
+          std::move(backend_)));
 }
-#endif
 
 bool ImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
                              scoped_refptr<VideoFrame> output_frame,
                              FrameReadyCB cb) {
+  DVLOGF(4);
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
   DCHECK_EQ(output_mode(), OutputMode::IMPORT);
   DCHECK(input_frame);
   DCHECK(output_frame);
 
-  if (!CheckVideoFrameFormat(input_config_, *input_frame) ||
-      !CheckVideoFrameFormat(output_config_, *output_frame))
+  if (!CheckVideoFrameFormat(input_config(), *input_frame) ||
+      !CheckVideoFrameFormat(output_config(), *output_frame))
     return false;
 
-  return ProcessInternal(std::move(input_frame), std::move(output_frame),
-                         std::move(cb));
+  int cb_index = StoreCallback(std::move(cb));
+  auto ready_cb = base::BindOnce(&ImageProcessor::OnProcessDoneThunk,
+                                 client_task_runner_, weak_this_, cb_index);
+  backend_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&ImageProcessorBackend::Process,
+                     base::Unretained(backend_.get()), std::move(input_frame),
+                     std::move(output_frame), std::move(ready_cb)));
+  return true;
+}
+
+// static
+void ImageProcessor::OnProcessDoneThunk(
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
+    base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+    int cb_index,
+    scoped_refptr<VideoFrame> frame) {
+  DVLOGF(4);
+  DCHECK(weak_this);
+
+  task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&ImageProcessor::OnProcessDone, *weak_this,
+                                cb_index, std::move(frame)));
+}
+
+void ImageProcessor::OnProcessDone(int cb_index,
+                                   scoped_refptr<VideoFrame> frame) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+
+  auto it = pending_cbs_.find(cb_index);
+  // Skip if the callback is dropped by Reset().
+  if (it == pending_cbs_.end())
+    return;
+
+  DCHECK(it->second.ready_cb);
+  FrameReadyCB cb = std::move(it->second.ready_cb);
+  pending_cbs_.erase(it);
+
+  std::move(cb).Run(std::move(frame));
+}
+
+bool ImageProcessor::Process(scoped_refptr<VideoFrame> frame,
+                             LegacyFrameReadyCB cb) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_EQ(output_mode(), OutputMode::ALLOCATE);
+
+  int cb_index = StoreCallback(std::move(cb));
+  auto ready_cb = base::BindOnce(&ImageProcessor::OnProcessLegacyDoneThunk,
+                                 client_task_runner_, weak_this_, cb_index);
+  backend_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&ImageProcessorBackend::ProcessLegacy,
+                                base::Unretained(backend_.get()),
+                                std::move(frame), std::move(ready_cb)));
+  return true;
+}
+
+// static
+void ImageProcessor::OnProcessLegacyDoneThunk(
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
+    base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+    int cb_index,
+    size_t buffer_id,
+    scoped_refptr<VideoFrame> frame) {
+  DVLOGF(4);
+  DCHECK(weak_this);
+
+  task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&ImageProcessor::OnProcessLegacyDone, *weak_this, cb_index,
+                     buffer_id, std::move(frame)));
+}
+
+void ImageProcessor::OnProcessLegacyDone(int cb_index,
+                                         size_t buffer_id,
+                                         scoped_refptr<VideoFrame> frame) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+
+  auto it = pending_cbs_.find(cb_index);
+  // Skip if the callback is dropped by Reset().
+  if (it == pending_cbs_.end())
+    return;
+
+  DCHECK(it->second.legacy_ready_cb);
+  LegacyFrameReadyCB cb = std::move(it->second.legacy_ready_cb);
+  pending_cbs_.erase(it);
+
+  std::move(cb).Run(buffer_id, std::move(frame));
+}
+
+bool ImageProcessor::Reset() {
+  DVLOGF(3);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+
+  backend_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&ImageProcessorBackend::Reset,
+                                base::Unretained(backend_.get())));
+
+  // After clearing all pending callbacks, we can guarantee no frame are
+  // returned after that.
+  pending_cbs_.clear();
+
+  return true;
+}
+
+int ImageProcessor::StoreCallback(ClientCallback cb) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+
+  int cb_index = next_cb_index_++;
+  pending_cbs_.emplace(cb_index, std::move(cb));
+  return cb_index;
 }
 
 }  // namespace media
diff --git a/media/gpu/chromeos/image_processor.h b/media/gpu/chromeos/image_processor.h
index ba32349..d0ce7ac 100644
--- a/media/gpu/chromeos/image_processor.h
+++ b/media/gpu/chromeos/image_processor.h
@@ -7,22 +7,19 @@
 
 #include <stdint.h>
 
-#include <string>
+#include <map>
+#include <utility>
 #include <vector>
 
 #include "base/callback_forward.h"
-#include "base/files/scoped_file.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
-#include "build/build_config.h"
-#include "media/base/color_plane_layout.h"
 #include "media/base/video_frame.h"
-#include "media/gpu/chromeos/fourcc.h"
+#include "media/gpu/chromeos/image_processor_backend.h"
 #include "media/gpu/media_gpu_export.h"
-#include "ui/gfx/geometry/size.h"
 
 namespace media {
 
@@ -32,93 +29,45 @@
 // in a format different from what the rest of the pipeline expects.
 class MEDIA_GPU_EXPORT ImageProcessor {
  public:
-  // OutputMode is used as intermediate stage. The ultimate goal is to make
-  // ImageProcessor's clients all use IMPORT output mode.
-  // TODO(crbug.com/907767): Remove this once ImageProcessor always works as
-  // IMPORT mode for output.
-  enum class OutputMode { ALLOCATE, IMPORT };
+  using PortConfig = ImageProcessorBackend::PortConfig;
+  using OutputMode = ImageProcessorBackend::OutputMode;
+  using ErrorCB = ImageProcessorBackend::ErrorCB;
+  using FrameReadyCB = ImageProcessorBackend::FrameReadyCB;
+  using LegacyFrameReadyCB = ImageProcessorBackend::LegacyFrameReadyCB;
 
-  // Encapsulates ImageProcessor input / output configurations.
-  struct MEDIA_GPU_EXPORT PortConfig {
-    PortConfig() = delete;
-    PortConfig(const PortConfig&);
-    PortConfig(
-        Fourcc fourcc,
-        const gfx::Size& size,
-        const std::vector<ColorPlaneLayout>& planes,
-        const gfx::Size& visible_size,
-        const std::vector<VideoFrame::StorageType>& preferred_storage_types);
-    ~PortConfig();
+  // Callback type for creating a ImageProcessorBackend instance. This allows us
+  // to create ImageProcessorBackend instance inside ImageProcessor::Create().
+  using CreateBackendCB =
+      base::RepeatingCallback<std::unique_ptr<ImageProcessorBackend>(
+          const PortConfig& input_config,
+          const PortConfig& output_config,
+          const std::vector<OutputMode>& preferred_output_modes,
+          ErrorCB error_cb,
+          scoped_refptr<base::SequencedTaskRunner> backend_task_runner)>;
 
-    // Get the first |preferred_storage_types|.
-    // If |preferred_storage_types| is empty, return STORAGE_UNKNOWN.
-    VideoFrame::StorageType storage_type() const {
-      return preferred_storage_types.empty() ? VideoFrame::STORAGE_UNKNOWN
-                                             : preferred_storage_types.front();
-    }
-
-    // Output human readable string of PortConfig.
-    // Example:
-    // PortConfig(format::NV12, size:640x480, planes:[(640, 0, 307200),
-    // (640,0,153600)], visible_size:640x480, storage_types:[DMABUFS])
-    std::string ToString() const;
-
-    // Video frame format represented as fourcc type.
-    const Fourcc fourcc;
-
-    // Width and height of the video frame in pixels. This must include pixel
-    // data for the whole image; i.e. for YUV formats with subsampled chroma
-    // planes. If a visible portion of the image does not line up on a sample
-    // boundary, |size_| must be rounded up appropriately.
-    const gfx::Size size;
-
-    // Layout property (stride, offset, size of bytes) for each color plane.
-    const std::vector<ColorPlaneLayout> planes;
-    const gfx::Size visible_size;
-    // List of preferred storage types.
-    const std::vector<VideoFrame::StorageType> preferred_storage_types;
-  };
-
-  // Callback to be used to return a processed image to the client.
-  // FrameReadyCB is guaranteed to be executed on |client_task_runner_|.
-  using FrameReadyCB = base::OnceCallback<void(scoped_refptr<VideoFrame>)>;
-  // Callback to be used to return a processed image to the client.
-  // Used when calling the "legacy" Process() method with buffers that are
-  // managed by the IP. The first argument is the index of the returned buffer.
-  // FrameReadyCB is guaranteed to be executed on |client_task_runner_|.
-  using LegacyFrameReadyCB =
-      base::OnceCallback<void(size_t, scoped_refptr<VideoFrame>)>;
-
-  // Callback to be used to notify client when ImageProcess encounters error.
-  // It should be assigned in subclass' factory method. ErrorCB is guaranteed to
-  // be executed on |client_task_runner_|.
-  using ErrorCB = base::RepeatingClosure;
+  static std::unique_ptr<ImageProcessor> Create(
+      CreateBackendCB create_backend_cb,
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      const std::vector<OutputMode>& preferred_output_modes,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> client_task_runner);
 
   virtual ~ImageProcessor();
 
-  const PortConfig& input_config() const { return input_config_; }
-  const PortConfig& output_config() const { return output_config_; }
+  const PortConfig& input_config() const { return backend_->input_config(); }
+  const PortConfig& output_config() const { return backend_->output_config(); }
+  OutputMode output_mode() const { return backend_->output_mode(); }
 
-  // Returns output mode.
-  // TODO(crbug.com/907767): Remove it once ImageProcessor always works as
-  // IMPORT mode for output.
-  OutputMode output_mode() const { return output_mode_; }
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
   // Called by client to process |frame|. The resulting processed frame will be
   // stored in a ImageProcessor-owned output buffer and notified via |cb|. The
   // processor will drop all its references to |frame| after it finishes
   // accessing it.
   // Process() must be called on |client_task_runner_|. This should not be
   // blocking function.
-  //
-  // Note: because base::ScopedFD is defined under OS_POXIS or OS_FUCHSIA, we
-  // define this function under the same build config. It doesn't affect its
-  // current users as they are all under the same build config.
   // TODO(crbug.com/907767): Remove this once ImageProcessor always works as
   // IMPORT mode for output.
   bool Process(scoped_refptr<VideoFrame> frame, LegacyFrameReadyCB cb);
-#endif
 
   // Called by client to process |input_frame| and store in |output_frame|. This
   // can only be used when output mode is IMPORT. The processor will drop all
@@ -133,34 +82,68 @@
   // Reset all processing frames. After this method returns, no more callbacks
   // will be invoked. ImageProcessor is ready to process more frames.
   // Reset() must be called on |client_task_runner_|.
-  virtual bool Reset() = 0;
+  bool Reset();
 
  protected:
-  ImageProcessor(const PortConfig& input_config,
-                 const PortConfig& output_config,
-                 OutputMode output_mode,
-                 scoped_refptr<base::SequencedTaskRunner> client_task_runner);
+  // Container for both FrameReadyCB and LegacyFrameReadyCB. With this class,
+  // we could store both kind of callback in the same container.
+  // TODO(crbug.com/907767): Remove this once ImageProcessor always works as
+  // IMPORT mode for output.
+  struct ClientCallback {
+    ClientCallback(FrameReadyCB ready_cb);
+    ClientCallback(LegacyFrameReadyCB legacy_ready_cb);
+    ClientCallback(ClientCallback&&);
+    ~ClientCallback();
 
-  const PortConfig input_config_;
-  const PortConfig output_config_;
+    FrameReadyCB ready_cb;
+    LegacyFrameReadyCB legacy_ready_cb;
+  };
 
-  // TODO(crbug.com/907767): Remove |output_mode_| once ImageProcessor always
-  // works as IMPORT mode for output.
-  const OutputMode output_mode_;
+  ImageProcessor(std::unique_ptr<ImageProcessorBackend> backend,
+                 scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+                 scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+
+  // Callbacks of processing frames.
+  static void OnProcessDoneThunk(
+      scoped_refptr<base::SequencedTaskRunner> task_runner,
+      base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+      int cb_index,
+      scoped_refptr<VideoFrame> frame);
+  static void OnProcessLegacyDoneThunk(
+      scoped_refptr<base::SequencedTaskRunner> task_runner,
+      base::Optional<base::WeakPtr<ImageProcessor>> weak_this,
+      int cb_index,
+      size_t buffer_id,
+      scoped_refptr<VideoFrame> frame);
+  void OnProcessDone(int cb_index, scoped_refptr<VideoFrame> frame);
+  void OnProcessLegacyDone(int cb_index,
+                           size_t buffer_id,
+                           scoped_refptr<VideoFrame> frame);
+
+  // Store |cb| at |pending_cbs_| and return a index for the callback.
+  int StoreCallback(ClientCallback cb);
+
+  // The backend of image processor. All of its methods are called on
+  // |backend_task_runner_|.
+  std::unique_ptr<ImageProcessorBackend> backend_;
+
+  // Store the callbacks from the client, accessed on |client_task_runner_|.
+  // This storage is to guarantee the callbacks are called or destroyed on the
+  // correct sequence.
+  std::map<int /* cb_index */, ClientCallback /* cb */> pending_cbs_;
+  // The index of next callback.
+  int next_cb_index_ = 0;
 
   // The sequence and its checker for interacting with the client.
   scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
   SEQUENCE_CHECKER(client_sequence_checker_);
 
- private:
-  // Each ImageProcessor shall implement ProcessInternal() as Process().
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
-  virtual bool ProcessInternal(scoped_refptr<VideoFrame> frame,
-                               LegacyFrameReadyCB cb);
-#endif
-  virtual bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
-                               scoped_refptr<VideoFrame> output_frame,
-                               FrameReadyCB cb) = 0;
+  // The sequence for interacting with |backend_|.
+  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
+
+  // The weak pointer of this, bound to |client_task_runner_|.
+  base::WeakPtr<ImageProcessor> weak_this_;
+  base::WeakPtrFactory<ImageProcessor> weak_this_factory_{this};
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(ImageProcessor);
 };
diff --git a/media/gpu/chromeos/image_processor_backend.cc b/media/gpu/chromeos/image_processor_backend.cc
new file mode 100644
index 0000000..391bfd6
--- /dev/null
+++ b/media/gpu/chromeos/image_processor_backend.cc
@@ -0,0 +1,106 @@
+// 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 "media/gpu/chromeos/image_processor_backend.h"
+
+#include <memory>
+#include <ostream>
+#include <sstream>
+
+#include "base/bind.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "base/task/task_traits.h"
+#include "media/gpu/macros.h"
+
+namespace media {
+
+namespace {
+
+template <class T>
+std::string VectorToString(const std::vector<T>& vec) {
+  std::ostringstream result;
+  std::string delim;
+  result << "[";
+  for (const T& v : vec) {
+    result << delim << v;
+    if (delim.size() == 0)
+      delim = ", ";
+  }
+  result << "]";
+  return result.str();
+}
+
+}  // namespace
+
+ImageProcessorBackend::PortConfig::PortConfig(const PortConfig&) = default;
+
+ImageProcessorBackend::PortConfig::PortConfig(
+    Fourcc fourcc,
+    const gfx::Size& size,
+    const std::vector<ColorPlaneLayout>& planes,
+    const gfx::Size& visible_size,
+    const std::vector<VideoFrame::StorageType>& preferred_storage_types)
+    : fourcc(fourcc),
+      size(size),
+      planes(planes),
+      visible_size(visible_size),
+      preferred_storage_types(preferred_storage_types) {}
+
+ImageProcessorBackend::PortConfig::~PortConfig() = default;
+
+std::string ImageProcessorBackend::PortConfig::ToString() const {
+  return base::StringPrintf(
+      "PortConfig(format:%s, size:%s, planes: %s, visible_size:%s, "
+      "storage_types:%s)",
+      fourcc.ToString().c_str(), size.ToString().c_str(),
+      VectorToString(planes).c_str(), visible_size.ToString().c_str(),
+      VectorToString(preferred_storage_types).c_str());
+}
+
+ImageProcessorBackend::ImageProcessorBackend(
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    OutputMode output_mode,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
+    : input_config_(input_config),
+      output_config_(output_config),
+      output_mode_(output_mode),
+      error_cb_(error_cb),
+      backend_task_runner_(std::move(backend_task_runner)) {
+  DETACH_FROM_SEQUENCE(backend_sequence_checker_);
+}
+
+ImageProcessorBackend::~ImageProcessorBackend() = default;
+
+void ImageProcessorBackend::Destroy() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
+
+  delete this;
+}
+
+void ImageProcessorBackend::ProcessLegacy(scoped_refptr<VideoFrame> frame,
+                                          LegacyFrameReadyCB cb) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
+
+  NOTIMPLEMENTED();
+}
+
+void ImageProcessorBackend::Reset() {
+  DVLOGF(3);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
+  // Do nothing as the default action.
+}
+
+}  // namespace media
+
+namespace std {
+
+void default_delete<media::ImageProcessorBackend>::operator()(
+    media::ImageProcessorBackend* ptr) const {
+  ptr->Destroy();
+}
+
+}  // namespace std
diff --git a/media/gpu/chromeos/image_processor_backend.h b/media/gpu/chromeos/image_processor_backend.h
new file mode 100644
index 0000000..433964e
--- /dev/null
+++ b/media/gpu/chromeos/image_processor_backend.h
@@ -0,0 +1,156 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_GPU_CHROMEOS_IMAGE_PROCESSOR_BACKEND_H_
+#define MEDIA_GPU_CHROMEOS_IMAGE_PROCESSOR_BACKEND_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
+#include "media/base/color_plane_layout.h"
+#include "media/base/video_frame.h"
+#include "media/gpu/chromeos/fourcc.h"
+#include "media/gpu/media_gpu_export.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace media {
+
+class MEDIA_GPU_EXPORT ImageProcessorBackend {
+ public:
+  // Callback for returning a processed image to the client.
+  using FrameReadyCB = base::OnceCallback<void(scoped_refptr<VideoFrame>)>;
+  // Callback for returning a processed image to the client.
+  // Used when calling the "legacy" Process() method with buffers that are
+  // managed by the processor. The first argument is the index of the returned
+  // buffer.
+  using LegacyFrameReadyCB =
+      base::OnceCallback<void(size_t, scoped_refptr<VideoFrame>)>;
+
+  // Callback for notifying client when error occurs.
+  using ErrorCB = base::RepeatingClosure;
+
+  // OutputMode is used as intermediate stage. The ultimate goal is to make
+  // ImageProcessor's clients all use IMPORT output mode.
+  // TODO(crbug.com/907767): Remove this once ImageProcessor always works as
+  // IMPORT mode for output.
+  enum class OutputMode { ALLOCATE, IMPORT };
+
+  // Encapsulates ImageProcessor input / output configurations.
+  struct MEDIA_GPU_EXPORT PortConfig {
+    PortConfig() = delete;
+    PortConfig(const PortConfig&);
+    PortConfig(
+        Fourcc fourcc,
+        const gfx::Size& size,
+        const std::vector<ColorPlaneLayout>& planes,
+        const gfx::Size& visible_size,
+        const std::vector<VideoFrame::StorageType>& preferred_storage_types);
+    ~PortConfig();
+
+    // Get the first |preferred_storage_types|.
+    // If |preferred_storage_types| is empty, return STORAGE_UNKNOWN.
+    VideoFrame::StorageType storage_type() const {
+      return preferred_storage_types.empty() ? VideoFrame::STORAGE_UNKNOWN
+                                             : preferred_storage_types.front();
+    }
+
+    // Output human readable string of PortConfig.
+    // Example:
+    // PortConfig(format::NV12, size:640x480, planes:[(640, 0, 307200),
+    // (640,0,153600)], visible_size:640x480, storage_types:[DMABUFS])
+    std::string ToString() const;
+
+    // Video frame format represented as fourcc type.
+    const Fourcc fourcc;
+
+    // Width and height of the video frame in pixels. This must include pixel
+    // data for the whole image; i.e. for YUV formats with subsampled chroma
+    // planes. If a visible portion of the image does not line up on a sample
+    // boundary, |size_| must be rounded up appropriately.
+    const gfx::Size size;
+
+    // Layout property (stride, offset, size of bytes) for each color plane.
+    const std::vector<ColorPlaneLayout> planes;
+    const gfx::Size visible_size;
+    // List of preferred storage types.
+    const std::vector<VideoFrame::StorageType> preferred_storage_types;
+  };
+
+  // Process |input_frame| and store in |output_frame|. Only used when output
+  // mode is IMPORT. After processing, call |cb| with |output_frame|.
+  virtual void Process(scoped_refptr<VideoFrame> input_frame,
+                       scoped_refptr<VideoFrame> output_frame,
+                       FrameReadyCB cb) = 0;
+
+  // Process |frame| and store in in a ImageProcessor-owned output buffer. Only
+  // used when output mode is ALLOCATE. After processing, call |cb| with the
+  // buffer.
+  // If ALLOCATE mode is not supported, the implementation is optional. In this
+  // case, this method should not be called and the default implementation will
+  // panic.
+  virtual void ProcessLegacy(scoped_refptr<VideoFrame> frame,
+                             LegacyFrameReadyCB cb);
+
+  // Drop all pending process requests. The default implementation is no-op.
+  virtual void Reset();
+
+  // Getter methods of data members, which could be called on any sequence.
+  const PortConfig& input_config() const { return input_config_; }
+  const PortConfig& output_config() const { return output_config_; }
+  OutputMode output_mode() const { return output_mode_; }
+
+ protected:
+  friend struct std::default_delete<ImageProcessorBackend>;
+
+  ImageProcessorBackend(
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      OutputMode output_mode,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+  virtual ~ImageProcessorBackend();
+  virtual void Destroy();
+
+  const PortConfig input_config_;
+  const PortConfig output_config_;
+
+  // TODO(crbug.com/907767): Remove |output_mode_| once ImageProcessor always
+  // works as IMPORT mode for output.
+  const OutputMode output_mode_;
+
+  // Call this callback when any error occurs.
+  const ErrorCB error_cb_;
+
+  // The main sequence and its checker. Except getter methods, all public
+  // methods and callbacks are called on this sequence.
+  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
+  SEQUENCE_CHECKER(backend_sequence_checker_);
+};
+
+}  // namespace media
+
+namespace std {
+
+// Specialize std::default_delete to call Destroy().
+template <>
+struct MEDIA_GPU_EXPORT default_delete<media::ImageProcessorBackend> {
+  constexpr default_delete() = default;
+
+  template <
+      typename U,
+      typename = typename std::enable_if<
+          std::is_convertible<U*, media::ImageProcessorBackend*>::value>::type>
+  default_delete(const default_delete<U>& d) {}
+
+  void operator()(media::ImageProcessorBackend* ptr) const;
+};
+
+}  // namespace std
+
+#endif  // MEDIA_GPU_CHROMEOS_IMAGE_PROCESSOR_BACKEND_H_
diff --git a/media/gpu/chromeos/image_processor_factory.cc b/media/gpu/chromeos/image_processor_factory.cc
index ca1e596e..1611126 100644
--- a/media/gpu/chromeos/image_processor_factory.cc
+++ b/media/gpu/chromeos/image_processor_factory.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "media/base/video_types.h"
@@ -97,26 +98,21 @@
     size_t num_buffers,
     scoped_refptr<base::SequencedTaskRunner> client_task_runner,
     ImageProcessor::ErrorCB error_cb) {
-  std::unique_ptr<ImageProcessor> image_processor;
+  std::vector<ImageProcessor::CreateBackendCB> create_funcs;
 #if BUILDFLAG(USE_VAAPI)
-  image_processor = VaapiImageProcessor::Create(input_config, output_config,
-                                                preferred_output_modes,
-                                                client_task_runner, error_cb);
-  if (image_processor)
-    return image_processor;
+  create_funcs.push_back(base::BindRepeating(&VaapiImageProcessor::Create));
 #endif  // BUILDFLAG(USE_VAAPI)
 #if BUILDFLAG(USE_V4L2_CODEC)
-  for (auto output_mode : preferred_output_modes) {
-    image_processor = V4L2ImageProcessor::Create(
-        client_task_runner, V4L2Device::Create(), input_config, output_config,
-        output_mode, num_buffers, error_cb);
-    if (image_processor)
-      return image_processor;
-  }
+  create_funcs.push_back(base::BindRepeating(
+      &V4L2ImageProcessor::Create, V4L2Device::Create(), num_buffers));
 #endif  // BUILDFLAG(USE_V4L2_CODEC)
-  for (auto output_mode : preferred_output_modes) {
-    image_processor = LibYUVImageProcessor::Create(
-        input_config, output_config, output_mode, client_task_runner, error_cb);
+  create_funcs.push_back(base::BindRepeating(&LibYUVImageProcessor::Create));
+
+  std::unique_ptr<ImageProcessor> image_processor;
+  for (auto& create_func : create_funcs) {
+    image_processor = ImageProcessor::Create(
+        std::move(create_func), input_config, output_config,
+        preferred_output_modes, error_cb, client_task_runner);
     if (image_processor)
       return image_processor;
   }
diff --git a/media/gpu/chromeos/libyuv_image_processor.cc b/media/gpu/chromeos/libyuv_image_processor.cc
index 5a91a78..d40dfaff 100644
--- a/media/gpu/chromeos/libyuv_image_processor.cc
+++ b/media/gpu/chromeos/libyuv_image_processor.cc
@@ -4,8 +4,6 @@
 
 #include "media/gpu/chromeos/libyuv_image_processor.h"
 
-#include "base/bind.h"
-#include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/macros.h"
@@ -54,34 +52,14 @@
 
 }  // namespace
 
-LibYUVImageProcessor::LibYUVImageProcessor(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
-    std::unique_ptr<VideoFrameMapper> video_frame_mapper,
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-    ErrorCB error_cb)
-    : ImageProcessor(input_config,
-                     output_config,
-                     OutputMode::IMPORT,
-                     std::move(client_task_runner)),
-      video_frame_mapper_(std::move(video_frame_mapper)),
-      error_cb_(error_cb),
-      process_thread_("LibYUVImageProcessorThread") {}
-
-LibYUVImageProcessor::~LibYUVImageProcessor() {
-  DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
-  Reset();
-
-  process_thread_.Stop();
-}
 
 // static
-std::unique_ptr<LibYUVImageProcessor> LibYUVImageProcessor::Create(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
-    ImageProcessor::OutputMode output_mode,
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-    ErrorCB error_cb) {
+std::unique_ptr<ImageProcessorBackend> LibYUVImageProcessor::Create(
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    const std::vector<OutputMode>& preferred_output_modes,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner) {
   VLOGF(2);
 
   std::unique_ptr<VideoFrameMapper> video_frame_mapper;
@@ -121,7 +99,7 @@
     return nullptr;
   }
 
-  if (output_mode != OutputMode::IMPORT) {
+  if (!base::Contains(preferred_output_modes, OutputMode::IMPORT)) {
     VLOGF(2) << "Only support OutputMode::IMPORT";
     return nullptr;
   }
@@ -134,73 +112,66 @@
     return nullptr;
   }
 
-  auto processor = base::WrapUnique(new LibYUVImageProcessor(
-      ImageProcessor::PortConfig(input_config.fourcc, input_config.size,
-                                 input_config.planes, input_config.visible_size,
-                                 {input_storage_type}),
-      ImageProcessor::PortConfig(
-          output_config.fourcc, output_config.size, output_config.planes,
-          output_config.visible_size, {output_storage_type}),
-      std::move(video_frame_mapper), std::move(client_task_runner),
-      std::move(error_cb)));
+  scoped_refptr<VideoFrame> intermediate_frame;
+
   if (res == SupportResult::SupportedWithPivot) {
-    processor->intermediate_frame_ =
+    intermediate_frame =
         VideoFrame::CreateFrame(PIXEL_FORMAT_I420, input_config.visible_size,
                                 gfx::Rect(input_config.visible_size),
                                 input_config.visible_size, base::TimeDelta());
-    if (!processor->intermediate_frame_) {
+    if (!intermediate_frame) {
       VLOGF(1) << "Failed to create intermediate frame";
       return nullptr;
     }
   }
 
-  if (!processor->process_thread_.Start()) {
-    VLOGF(1) << "Failed to start processing thread";
-    return nullptr;
-  }
-
+  auto processor =
+      base::WrapUnique<ImageProcessorBackend>(new LibYUVImageProcessor(
+          std::move(video_frame_mapper), std::move(intermediate_frame),
+          PortConfig(input_config.fourcc, input_config.size,
+                     input_config.planes, input_config.visible_size,
+                     {input_storage_type}),
+          PortConfig(output_config.fourcc, output_config.size,
+                     output_config.planes, output_config.visible_size,
+                     {output_storage_type}),
+          OutputMode::IMPORT, std::move(error_cb),
+          std::move(backend_task_runner)));
   VLOGF(2) << "LibYUVImageProcessor created for converting from "
            << input_config.ToString() << " to " << output_config.ToString();
   return processor;
 }
 
-bool LibYUVImageProcessor::ProcessInternal(
-    scoped_refptr<VideoFrame> input_frame,
-    scoped_refptr<VideoFrame> output_frame,
-    FrameReadyCB cb) {
-  DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
-  DVLOGF(4);
-  DCHECK_EQ(input_frame->layout().format(),
-            input_config_.fourcc.ToVideoPixelFormat());
-  DCHECK(input_frame->layout().coded_size() == input_config_.size);
-  DCHECK_EQ(output_frame->layout().format(),
-            output_config_.fourcc.ToVideoPixelFormat());
-  DCHECK(output_frame->layout().coded_size() == output_config_.size);
-  DCHECK(input_config_.storage_type() == input_frame->storage_type() ||
-         VideoFrame::IsStorageTypeMappable(input_frame->storage_type()));
-  DCHECK(VideoFrame::IsStorageTypeMappable(output_frame->storage_type()));
+LibYUVImageProcessor::LibYUVImageProcessor(
+    std::unique_ptr<VideoFrameMapper> video_frame_mapper,
+    scoped_refptr<VideoFrame> intermediate_frame,
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    OutputMode output_mode,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
+    : ImageProcessorBackend(input_config,
+                            output_config,
+                            output_mode,
+                            std::move(error_cb),
+                            std::move(backend_task_runner)),
+      video_frame_mapper_(std::move(video_frame_mapper)),
+      intermediate_frame_(std::move(intermediate_frame)) {}
 
-  // Since process_thread_ is owned by this class. base::Unretained(this) and
-  // the raw pointer of that task runner are safe.
-  process_task_tracker_.PostTask(
-      process_thread_.task_runner().get(), FROM_HERE,
-      base::BindOnce(&LibYUVImageProcessor::ProcessTask, base::Unretained(this),
-                     std::move(input_frame), std::move(output_frame),
-                     std::move(cb)));
-  return true;
+LibYUVImageProcessor::~LibYUVImageProcessor() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 }
 
-void LibYUVImageProcessor::ProcessTask(scoped_refptr<VideoFrame> input_frame,
-                                       scoped_refptr<VideoFrame> output_frame,
-                                       FrameReadyCB cb) {
-  DCHECK(process_thread_.task_runner()->BelongsToCurrentThread());
+void LibYUVImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
+                                   scoped_refptr<VideoFrame> output_frame,
+                                   FrameReadyCB cb) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DVLOGF(4);
   if (input_frame->storage_type() == VideoFrame::STORAGE_DMABUFS) {
     DCHECK_NE(video_frame_mapper_.get(), nullptr);
     input_frame = video_frame_mapper_->Map(std::move(input_frame));
     if (!input_frame) {
       VLOGF(1) << "Failed to map input VideoFrame";
-      NotifyError();
+      error_cb_.Run();
       return;
     }
   }
@@ -208,30 +179,17 @@
   int res = DoConversion(input_frame.get(), output_frame.get());
   if (res != 0) {
     VLOGF(1) << "libyuv::I420ToNV12 returns non-zero code: " << res;
-    NotifyError();
+    error_cb_.Run();
     return;
   }
   output_frame->set_timestamp(input_frame->timestamp());
-  client_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(std::move(cb), std::move(output_frame)));
-}
 
-bool LibYUVImageProcessor::Reset() {
-  DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
-
-  process_task_tracker_.TryCancelAll();
-  return true;
-}
-
-void LibYUVImageProcessor::NotifyError() {
-  VLOGF(1);
-
-  client_task_runner_->PostTask(FROM_HERE, error_cb_);
+  std::move(cb).Run(std::move(output_frame));
 }
 
 int LibYUVImageProcessor::DoConversion(const VideoFrame* const input,
                                        VideoFrame* const output) {
-  DCHECK(process_thread_.task_runner()->BelongsToCurrentThread());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
 #define Y_U_V_DATA(fr)                                                \
   fr->data(VideoFrame::kYPlane), fr->stride(VideoFrame::kYPlane),     \
diff --git a/media/gpu/chromeos/libyuv_image_processor.h b/media/gpu/chromeos/libyuv_image_processor.h
index 54138eb..5bc2e0af 100644
--- a/media/gpu/chromeos/libyuv_image_processor.h
+++ b/media/gpu/chromeos/libyuv_image_processor.h
@@ -5,24 +5,13 @@
 #ifndef MEDIA_GPU_CHROMEOS_LIBYUV_IMAGE_PROCESSOR_H_
 #define MEDIA_GPU_CHROMEOS_LIBYUV_IMAGE_PROCESSOR_H_
 
-#include <atomic>
 #include <memory>
 #include <vector>
 
-#include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/task/cancelable_task_tracker.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
-#include "build/build_config.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_frame_layout.h"
-#include "media/base/video_types.h"
-#include "media/gpu/chromeos/image_processor.h"
+#include "media/gpu/chromeos/image_processor_backend.h"
 #include "media/gpu/media_gpu_export.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
 
 namespace media {
 
@@ -31,40 +20,35 @@
 // A software image processor which uses libyuv to perform format conversion.
 // It expects input VideoFrame is mapped into CPU space, and output VideoFrame
 // is allocated in user space.
-class MEDIA_GPU_EXPORT LibYUVImageProcessor : public ImageProcessor {
+class MEDIA_GPU_EXPORT LibYUVImageProcessor : public ImageProcessorBackend {
  public:
-  // ImageProcessor override
-  ~LibYUVImageProcessor() override;
-  bool Reset() override;
-
   // Factory method to create LibYUVImageProcessor to convert video format
   // specified in input_config and output_config. Provided |error_cb| will be
   // posted to the same thread Create() is called if an error occurs after
   // initialization.
   // Returns nullptr if it fails to create LibYUVImageProcessor.
-  static std::unique_ptr<LibYUVImageProcessor> Create(
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
-      ImageProcessor::OutputMode output_mode,
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-      ErrorCB error_cb);
+  static std::unique_ptr<ImageProcessorBackend> Create(
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      const std::vector<OutputMode>& preferred_output_modes,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+
+  // ImageProcessorBackend override
+  void Process(scoped_refptr<VideoFrame> input_frame,
+               scoped_refptr<VideoFrame> output_frame,
+               FrameReadyCB cb) override;
 
  private:
   LibYUVImageProcessor(
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
       std::unique_ptr<VideoFrameMapper> video_frame_mapper,
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-      ErrorCB error_cb);
-
-  // ImageProcessor override
-  bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
-                       scoped_refptr<VideoFrame> output_frame,
-                       FrameReadyCB cb) override;
-
-  void ProcessTask(scoped_refptr<VideoFrame> input_frame,
-                   scoped_refptr<VideoFrame> output_frame,
-                   FrameReadyCB cb);
+      scoped_refptr<VideoFrame> intermediate_frame,
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      OutputMode output_mode,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+  ~LibYUVImageProcessor() override;
 
   void NotifyError();
 
@@ -80,22 +64,6 @@
   // conversion method in libyuv, e.g., RGBA -> I420 (pivot) -> NV12.
   scoped_refptr<VideoFrame> intermediate_frame_;
 
-  // Error callback to the client.
-  ErrorCB error_cb_;
-
-  // Thread to process frame format conversion.
-  base::Thread process_thread_;
-
-  // CancelableTaskTracker for ProcessTask().
-  // Because ProcessTask is posted from |client_task_runner_|'s thread to
-  // another sequence, |process_thread_|, it is unsafe to cancel the posted task
-  // from |client_task_runner_|'s thread using CancelableCallback and WeakPtr
-  // binding. CancelableTaskTracker is designed to deal with this scenario.
-  base::CancelableTaskTracker process_task_tracker_;
-
-  // Checker for the thread that creates this LibYUVImageProcessor.
-  THREAD_CHECKER(client_thread_checker_);
-
   DISALLOW_COPY_AND_ASSIGN(LibYUVImageProcessor);
 };
 
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index cad10662..ebdac3a 100644
--- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -867,10 +867,10 @@
           // Record the configuration.
           DCHECK(seen_pps_.count(slice_hdr.pic_parameter_set_id));
           DCHECK(seen_sps_.count(pps->seq_parameter_set_id));
-          active_sps_ = seen_sps_[slice_hdr.pic_parameter_set_id];
+          active_sps_ = seen_sps_[pps->seq_parameter_set_id];
           // Note: SPS extension lookup may create an empty entry.
-          active_spsext_ = seen_spsext_[slice_hdr.pic_parameter_set_id];
-          active_pps_ = seen_pps_[pps->seq_parameter_set_id];
+          active_spsext_ = seen_spsext_[pps->seq_parameter_set_id];
+          active_pps_ = seen_pps_[slice_hdr.pic_parameter_set_id];
 
           // Compute and store frame properties. |image_size| gets filled in
           // later, since it comes from the decoder configuration.
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn
index fb44e6c..21ff527 100644
--- a/media/gpu/test/BUILD.gn
+++ b/media/gpu/test/BUILD.gn
@@ -158,7 +158,7 @@
   }
 }
 
-if (is_linux) {
+if (is_chromeos) {
   static_library("local_gpu_memory_buffer_manager") {
     testonly = true
     sources = [
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 0e0bb98..16c39d79 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.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 "media/gpu/v4l2/v4l2_image_processor.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
@@ -11,24 +13,19 @@
 #include <sys/mman.h>
 
 #include <limits>
-#include <tuple>
+#include <memory>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
-#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/sequenced_task_runner.h"
-#include "base/synchronization/waitable_event.h"
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "media/base/color_plane_layout.h"
 #include "media/base/scopedfd_helper.h"
-#include "media/base/video_types.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/macros.h"
-#include "media/gpu/v4l2/v4l2_image_processor.h"
 
 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
   do {                                                          \
@@ -38,18 +35,9 @@
     }                                                           \
   } while (0)
 
-#define IOCTL_OR_ERROR_RETURN(type, arg) \
-  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
-
 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
   IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
 
-#define IOCTL_OR_LOG_ERROR(type, arg)           \
-  do {                                          \
-    if (device_->Ioctl(type, arg) != 0)         \
-      VPLOGF(1) << "ioctl() failed: " << #type; \
-  } while (0)
-
 namespace media {
 
 V4L2ImageProcessor::JobRecord::JobRecord()
@@ -58,74 +46,41 @@
 V4L2ImageProcessor::JobRecord::~JobRecord() = default;
 
 V4L2ImageProcessor::V4L2ImageProcessor(
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
     scoped_refptr<V4L2Device> device,
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
+    const PortConfig& input_config,
+    const PortConfig& output_config,
     v4l2_memory input_memory_type,
     v4l2_memory output_memory_type,
     OutputMode output_mode,
     size_t num_buffers,
     ErrorCB error_cb)
-    : ImageProcessor(input_config,
-                     output_config,
-                     output_mode,
-                     std::move(client_task_runner)),
+    : ImageProcessorBackend(input_config,
+                            output_config,
+                            output_mode,
+                            std::move(error_cb),
+                            std::move(backend_task_runner)),
       input_memory_type_(input_memory_type),
       output_memory_type_(output_memory_type),
       device_(device),
-      device_task_runner_(
-          base::CreateSingleThreadTaskRunner({base::ThreadPool()})),
+      num_buffers_(num_buffers),
       // We poll V4L2 device on this task runner, which blocks the task runner.
       // Therefore we use dedicated SingleThreadTaskRunner here.
       poll_task_runner_(base::CreateSingleThreadTaskRunner(
           {base::ThreadPool()},
-          base::SingleThreadTaskRunnerThreadMode::DEDICATED)),
-      num_buffers_(num_buffers),
-      error_cb_(error_cb) {
+          base::SingleThreadTaskRunnerThreadMode::DEDICATED)) {
   DVLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-  DETACH_FROM_SEQUENCE(device_sequence_checker_);
   DETACH_FROM_SEQUENCE(poll_sequence_checker_);
 
-  client_weak_this_ = client_weak_this_factory_.GetWeakPtr();
-  device_weak_this_ = device_weak_this_factory_.GetWeakPtr();
+  backend_weak_this_ = backend_weak_this_factory_.GetWeakPtr();
   poll_weak_this_ = poll_weak_this_factory_.GetWeakPtr();
 }
 
-V4L2ImageProcessor::~V4L2ImageProcessor() {
+void V4L2ImageProcessor::Destroy() {
   DVLOGF(3);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
-  // Don't post a client tasks any more because they are redundant.
-  client_weak_this_factory_.InvalidateWeakPtrs();
-
-  // Cancel all pending tasks and then clean up on |device_task_runner_|.
-  process_task_tracker_.TryCancelAll();
-
-  // TODO(akahuang): Change to async destructor to avoid base::WaitableEvent.
-  // Clean up |device_task_runner_|.
-  base::WaitableEvent device_done;
-  device_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&V4L2ImageProcessor::DestroyOnDeviceSequence,
-                     device_weak_this_, base::Unretained(&device_done)));
-  device_done.Wait();
-
-  // After |device_task_runner_| is finished cleaning up, we don't schedule new
-  // DevicePollTask() to |poll_task_runner_|. Now clean up |poll_task_runner_|.
-  base::WaitableEvent poll_done;
-  poll_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&V4L2ImageProcessor::DestroyOnPollSequence,
-                                poll_weak_this_, base::Unretained(&poll_done)));
-  poll_done.Wait();
-}
-
-void V4L2ImageProcessor::DestroyOnDeviceSequence(base::WaitableEvent* event) {
-  VLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
-
-  device_weak_this_factory_.InvalidateWeakPtrs();
+  backend_weak_this_factory_.InvalidateWeakPtrs();
 
   if (input_queue_) {
     input_queue_->Streamoff();
@@ -143,27 +98,34 @@
   running_jobs_ = {};
 
   // Stop the running DevicePollTask() if it exists.
-  if (!device_->SetDevicePollInterrupt()) {
+  if (!device_->SetDevicePollInterrupt())
     NotifyError();
-    return;
-  }
 
-  event->Signal();
+  // After stopping queue, we don't schedule new DevicePollTask() to
+  // |poll_task_runner_|. Now clean up |poll_task_runner_|.
+  poll_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&V4L2ImageProcessor::DestroyOnPollSequence,
+                                poll_weak_this_));
 }
 
-void V4L2ImageProcessor::DestroyOnPollSequence(base::WaitableEvent* event) {
+void V4L2ImageProcessor::DestroyOnPollSequence() {
   VLOGF(2);
   DCHECK_CALLED_ON_VALID_SEQUENCE(poll_sequence_checker_);
 
   poll_weak_this_factory_.InvalidateWeakPtrs();
 
-  event->Signal();
+  delete this;
+}
+
+V4L2ImageProcessor::~V4L2ImageProcessor() {
+  VLOGF(3);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(poll_sequence_checker_);
 }
 
 void V4L2ImageProcessor::NotifyError() {
   VLOGF(1);
 
-  client_task_runner_->PostTask(FROM_HERE, error_cb_);
+  error_cb_.Run();
 }
 
 namespace {
@@ -185,16 +147,37 @@
 }  // namespace
 
 // static
-std::unique_ptr<V4L2ImageProcessor> V4L2ImageProcessor::Create(
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+std::unique_ptr<ImageProcessorBackend> V4L2ImageProcessor::Create(
     scoped_refptr<V4L2Device> device,
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
-    const ImageProcessor::OutputMode output_mode,
     size_t num_buffers,
-    ErrorCB error_cb) {
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    const std::vector<OutputMode>& preferred_output_modes,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner) {
+  for (const auto& output_mode : preferred_output_modes) {
+    auto image_processor = V4L2ImageProcessor::CreateWithOutputMode(
+        device, num_buffers, input_config, output_config, output_mode, error_cb,
+        backend_task_runner);
+    if (image_processor)
+      return image_processor;
+  }
+
+  return nullptr;
+}
+
+// static
+std::unique_ptr<ImageProcessorBackend> V4L2ImageProcessor::CreateWithOutputMode(
+    scoped_refptr<V4L2Device> device,
+    size_t num_buffers,
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    const OutputMode& output_mode,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner) {
   VLOGF(2);
   DCHECK_GT(num_buffers, 0u);
+
   if (!device) {
     VLOGF(2) << "Failed creating V4L2Device";
     return nullptr;
@@ -235,9 +218,9 @@
     return nullptr;
   }
 
-  const v4l2_memory output_memory_type =
-      output_mode == ImageProcessor::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP
-                                                          : V4L2_MEMORY_DMABUF;
+  const v4l2_memory output_memory_type = output_mode == OutputMode::ALLOCATE
+                                             ? V4L2_MEMORY_MMAP
+                                             : V4L2_MEMORY_DMABUF;
 
   if (!device->IsImageProcessingSupported()) {
     VLOGF(1) << "V4L2ImageProcessor not supported in this platform";
@@ -318,48 +301,62 @@
     output_planes[i].size = pix_mp.plane_fmt[i].sizeimage;
   }
 
-  auto processor = base::WrapUnique(new V4L2ImageProcessor(
-      std::move(client_task_runner), std::move(device),
-      ImageProcessor::PortConfig(input_config.fourcc, negotiated_input_size,
-                                 input_planes, input_config.visible_size,
-                                 {input_storage_type}),
-      ImageProcessor::PortConfig(output_config.fourcc, negotiated_output_size,
-                                 output_planes, output_config.visible_size,
-                                 {output_storage_type}),
-      input_memory_type, output_memory_type, output_mode, num_buffers,
-      std::move(error_cb)));
-  if (!processor->Initialize()) {
-    VLOGF(1) << "Failed to initialize V4L2ImageProcessor";
+  auto image_processor = std::unique_ptr<
+      V4L2ImageProcessor, std::default_delete<ImageProcessorBackend>>(
+      new V4L2ImageProcessor(
+          backend_task_runner, std::move(device),
+          PortConfig(input_config.fourcc, negotiated_input_size, input_planes,
+                     input_config.visible_size, {input_storage_type}),
+          PortConfig(output_config.fourcc, negotiated_output_size,
+                     output_planes, output_config.visible_size,
+                     {output_storage_type}),
+          input_memory_type, output_memory_type, output_mode, num_buffers,
+          std::move(error_cb)));
+
+  // Initialize at |backend_task_runner_|.
+  bool success = false;
+  base::WaitableEvent done;
+  auto init_cb = base::BindOnce(
+      [](base::WaitableEvent* done, bool* success, bool value) {
+        *success = value;
+        done->Signal();
+      },
+      base::Unretained(&done), base::Unretained(&success));
+  // Using base::Unretained() is safe because it is blocking call.
+  backend_task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&V4L2ImageProcessor::Initialize,
+                                base::Unretained(image_processor.get()),
+                                std::move(init_cb)));
+  done.Wait();
+  if (!success)
     return nullptr;
-  }
-  return processor;
+
+  return image_processor;
 }
 
-bool V4L2ImageProcessor::Initialize() {
+void V4L2ImageProcessor::Initialize(InitCB init_cb) {
   DVLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
   // Capabilities check.
   struct v4l2_capability caps;
   memset(&caps, 0, sizeof(caps));
   const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
-  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
+  if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) {
+    VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP";
+    std::move(init_cb).Run(false);
+    return;
+  }
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
     VLOGF(1) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
              << "caps check failed: 0x" << std::hex << caps.capabilities;
-    return false;
+    std::move(init_cb).Run(false);
+    return;
   }
 
-  // Call to AllocateBuffers must be asynchronous.
-  base::WaitableEvent done;
-  bool result;
-  device_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&V4L2ImageProcessor::AllocateBuffersTask,
-                     device_weak_this_, &result, base::Unretained(&done)));
-  done.Wait();
-  if (!result) {
-    return false;
+  if (!CreateInputBuffers() || !CreateOutputBuffers()) {
+    std::move(init_cb).Run(false);
+    return;
   }
 
   // Enqueue a poll task with no devices to poll on - will wait only for the
@@ -373,7 +370,7 @@
            << "input: " << input_config_.ToString()
            << ", output: " << output_config_.ToString();
 
-  return true;
+  std::move(init_cb).Run(true);
 }
 
 // static
@@ -452,56 +449,42 @@
   return true;
 }
 
-bool V4L2ImageProcessor::ProcessInternal(
-    scoped_refptr<VideoFrame> frame,
-    LegacyFrameReadyCB cb) {
+void V4L2ImageProcessor::ProcessLegacy(scoped_refptr<VideoFrame> frame,
+                                       LegacyFrameReadyCB cb) {
   DVLOGF(4) << "ts=" << frame->timestamp().InMilliseconds();
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
+
+  if (output_memory_type_ != V4L2_MEMORY_MMAP) {
+    NOTREACHED();
+    return;
+  }
 
   auto job_record = std::make_unique<JobRecord>();
   job_record->input_frame = frame;
   job_record->legacy_ready_cb = std::move(cb);
 
-  if (output_memory_type_ != V4L2_MEMORY_MMAP) {
-    NOTREACHED();
-  }
-
-  process_task_tracker_.PostTask(
-      device_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&V4L2ImageProcessor::ProcessTask, device_weak_this_,
-                     std::move(job_record)));
-  return true;
+  input_job_queue_.emplace(std::move(job_record));
+  ProcessJobsTask();
 }
 
-bool V4L2ImageProcessor::ProcessInternal(scoped_refptr<VideoFrame> input_frame,
-                                         scoped_refptr<VideoFrame> output_frame,
-                                         FrameReadyCB cb) {
+void V4L2ImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
+                                 scoped_refptr<VideoFrame> output_frame,
+                                 FrameReadyCB cb) {
   DVLOGF(4) << "ts=" << input_frame->timestamp().InMilliseconds();
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
   auto job_record = std::make_unique<JobRecord>();
   job_record->input_frame = std::move(input_frame);
   job_record->output_frame = std::move(output_frame);
   job_record->ready_cb = std::move(cb);
 
-  process_task_tracker_.PostTask(
-      device_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&V4L2ImageProcessor::ProcessTask, device_weak_this_,
-                     std::move(job_record)));
-  return true;
-}
-
-void V4L2ImageProcessor::ProcessTask(std::unique_ptr<JobRecord> job_record) {
-  DVLOGF(4) << "ts=" << job_record->input_frame->timestamp().InMilliseconds();
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
-
   input_job_queue_.emplace(std::move(job_record));
   ProcessJobsTask();
 }
 
 void V4L2ImageProcessor::ProcessJobsTask() {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
   while (!input_job_queue_.empty()) {
     // We need one input and one output buffer to schedule the job
@@ -517,38 +500,17 @@
   }
 }
 
-bool V4L2ImageProcessor::Reset() {
+void V4L2ImageProcessor::Reset() {
   DVLOGF(3);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-
-  process_task_tracker_.TryCancelAll();
-  base::WaitableEvent event;
-  device_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&V4L2ImageProcessor::ResetTask,
-                                device_weak_this_, base::Unretained(&event)));
-  event.Wait();
-
-  // Then cancel pending tasks on |client_task_runner_| to avoid returning
-  // frames after reset.
-  client_weak_this_factory_.InvalidateWeakPtrs();
-  client_weak_this_ = client_weak_this_factory_.GetWeakPtr();
-
-  return true;
-}
-
-void V4L2ImageProcessor::ResetTask(base::WaitableEvent* event) {
-  DVLOGF(3);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
   input_job_queue_ = {};
   running_jobs_ = {};
-
-  event->Signal();
 }
 
 bool V4L2ImageProcessor::CreateInputBuffers() {
   VLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK_EQ(input_queue_, nullptr);
 
   struct v4l2_control control;
@@ -614,7 +576,7 @@
 
 bool V4L2ImageProcessor::CreateOutputBuffers() {
   VLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK_EQ(output_queue_, nullptr);
 
   struct v4l2_rect visible_rect;
@@ -668,14 +630,14 @@
 
   // All processing should happen on ServiceDeviceTask(), since we shouldn't
   // touch processor state from this thread.
-  device_task_runner_->PostTask(
+  backend_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&V4L2ImageProcessor::ServiceDeviceTask,
-                                device_weak_this_));
+                                backend_weak_this_));
 }
 
 void V4L2ImageProcessor::ServiceDeviceTask() {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK(input_queue_);
 
   Dequeue();
@@ -705,7 +667,7 @@
 
 void V4L2ImageProcessor::EnqueueInput(const JobRecord* job_record) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK(input_queue_);
 
   const size_t old_inputs_queued = input_queue_->QueuedBuffersCount();
@@ -727,7 +689,7 @@
 
 void V4L2ImageProcessor::EnqueueOutput(JobRecord* job_record) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK(output_queue_);
 
   const int old_outputs_queued = output_queue_->QueuedBuffersCount();
@@ -762,7 +724,7 @@
 
 void V4L2ImageProcessor::V4L2VFRecycleTask(V4L2ReadableBufferRef buf) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
   // Release the buffer reference so we can directly call ProcessJobsTask()
   // knowing that we have an extra output buffer.
@@ -781,7 +743,7 @@
 
 void V4L2ImageProcessor::Dequeue() {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK(input_queue_);
   DCHECK(output_queue_);
   DCHECK(input_queue_->IsStreaming());
@@ -837,10 +799,11 @@
               orig_frame, orig_frame->format(), orig_frame->visible_rect(),
               orig_frame->natural_size());
           // Because VideoFrame destruction callback might be executed on any
-          // sequence, we use a thunk to post the task to |device_task_runner_|.
+          // sequence, we use a thunk to post the task to
+          // |backend_task_runner_|.
           output_frame->AddDestructionObserver(
               base::BindOnce(&V4L2ImageProcessor::V4L2VFRecycleThunk,
-                             device_task_runner_, device_weak_this_, buffer));
+                             backend_task_runner_, backend_weak_this_, buffer));
         }
         break;
 
@@ -855,34 +818,18 @@
 
     output_frame->set_timestamp(job_record->input_frame->timestamp());
 
-    base::OnceClosure output_cb;
     if (!job_record->legacy_ready_cb.is_null()) {
-      output_cb = base::BindOnce(std::move(job_record->legacy_ready_cb),
-                                 buffer->BufferId(), std::move(output_frame));
+      std::move(job_record->legacy_ready_cb)
+          .Run(buffer->BufferId(), std::move(output_frame));
     } else {
-      output_cb = base::BindOnce(std::move(job_record->ready_cb),
-                                 std::move(output_frame));
+      std::move(job_record->ready_cb).Run(std::move(output_frame));
     }
-    // The task might be cancelled when Reset() is called and then
-    // |client_weak_this_| becomes invalid.
-    client_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&V4L2ImageProcessor::OutputFrameOnClientSequence,
-                       client_weak_this_, std::move(output_cb)));
   }
 }
 
-void V4L2ImageProcessor::OutputFrameOnClientSequence(
-    base::OnceClosure output_cb) {
-  DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-
-  std::move(output_cb).Run();
-}
-
 bool V4L2ImageProcessor::EnqueueInputRecord(const JobRecord* job_record) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK(input_queue_);
   DCHECK_GT(input_queue_->FreeBuffersCount(), 0u);
 
@@ -921,7 +868,7 @@
 
 bool V4L2ImageProcessor::EnqueueOutputRecord(JobRecord* job_record) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
   DCHECK_GT(output_queue_->FreeBuffersCount(), 0u);
 
   V4L2WritableBufferRef buffer(output_queue_->GetFreeBuffer());
@@ -941,13 +888,4 @@
   }
 }
 
-void V4L2ImageProcessor::AllocateBuffersTask(bool* result,
-                                             base::WaitableEvent* done) {
-  VLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(device_sequence_checker_);
-
-  *result = CreateInputBuffers() && CreateOutputBuffers();
-  done->Signal();
-}
-
 }  // namespace media
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h
index bb1acb3..b896f98 100644
--- a/media/gpu/v4l2/v4l2_image_processor.h
+++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -13,21 +13,15 @@
 
 #include <linux/videodev2.h>
 
-#include "base/callback_forward.h"
 #include "base/containers/queue.h"
-#include "base/files/scoped_file.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
-#include "base/task/cancelable_task_tracker.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_frame_layout.h"
-#include "media/gpu/chromeos/image_processor.h"
+#include "media/gpu/chromeos/image_processor_backend.h"
 #include "media/gpu/media_gpu_export.h"
 #include "media/gpu/v4l2/v4l2_device.h"
 #include "ui/gfx/geometry/size.h"
@@ -37,7 +31,7 @@
 // Handles image processing accelerators that expose a V4L2 memory-to-memory
 // interface. The threading model of this class is the same as for other V4L2
 // hardware accelerators (see V4L2VideoDecodeAccelerator) for more details.
-class MEDIA_GPU_EXPORT V4L2ImageProcessor : public ImageProcessor {
+class MEDIA_GPU_EXPORT V4L2ImageProcessor : public ImageProcessorBackend {
  public:
   // Factory method to create V4L2ImageProcessor to convert from
   // input_config to output_config. The number of input buffers and output
@@ -48,18 +42,22 @@
   // TODO(crbug.com/917798): remove |device| parameter once
   //     V4L2VideoDecodeAccelerator no longer creates and uses
   //     |image_processor_device_| before V4L2ImageProcessor is created.
-  static std::unique_ptr<V4L2ImageProcessor> Create(
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+  static std::unique_ptr<ImageProcessorBackend> Create(
       scoped_refptr<V4L2Device> device,
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
-      const ImageProcessor::OutputMode output_mode,
       size_t num_buffers,
-      ErrorCB error_cb);
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      const std::vector<OutputMode>& preferred_output_modes,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
 
   // ImageProcessor implementation.
-  ~V4L2ImageProcessor() override;
-  bool Reset() override;
+  void Process(scoped_refptr<VideoFrame> input_frame,
+               scoped_refptr<VideoFrame> output_frame,
+               FrameReadyCB cb) override;
+  void ProcessLegacy(scoped_refptr<VideoFrame> frame,
+                     LegacyFrameReadyCB cb) override;
+  void Reset() override;
 
   // Returns true if image processing is supported on this platform.
   static bool IsSupported();
@@ -82,6 +80,9 @@
                               size_t* num_planes);
 
  private:
+  // Callback for initialization.
+  using InitCB = base::OnceCallback<void(bool)>;
+
   // Job record. Jobs are processed in a FIFO order. |input_frame| will be
   // processed and the result written into |output_frame|. Once processing is
   // complete, |ready_cb| or |legacy_ready_cb| will be called depending on which
@@ -96,18 +97,34 @@
     size_t output_buffer_id;
   };
 
-  V4L2ImageProcessor(
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
+  static std::unique_ptr<ImageProcessorBackend> CreateWithOutputMode(
       scoped_refptr<V4L2Device> device,
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
+      size_t num_buffers,
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      const OutputMode& preferred_output_modes,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+
+  V4L2ImageProcessor(
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner,
+      scoped_refptr<V4L2Device> device,
+      const PortConfig& input_config,
+      const PortConfig& output_config,
       v4l2_memory input_memory_type,
       v4l2_memory output_memory_type,
       OutputMode output_mode,
       size_t num_buffers,
       ErrorCB error_cb);
+  ~V4L2ImageProcessor() override;
+  void Destroy() override;
+  // Stop all processing on |poll_task_runner_|.
+  void DestroyOnPollSequence();
 
-  bool Initialize();
+  // Initialize on |backend_task_runner_|. After finished, call |init_cb|
+  // with the result whether initialization is successful or not
+  void Initialize(InitCB init_cb);
+
   void EnqueueInput(const JobRecord* job_record);
   void EnqueueOutput(JobRecord* job_record);
   void Dequeue();
@@ -128,50 +145,18 @@
   void NotifyError();
 
   // ImageProcessor implementation.
-  bool ProcessInternal(scoped_refptr<VideoFrame> frame,
-                       LegacyFrameReadyCB cb) override;
-  bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
-                       scoped_refptr<VideoFrame> output_frame,
-                       FrameReadyCB cb) override;
-
-  void ProcessTask(std::unique_ptr<JobRecord> job_record);
   void ProcessJobsTask();
   void ServiceDeviceTask();
 
-  // Call |output_cb| on |client_task_runner_|.
-  void OutputFrameOnClientSequence(base::OnceClosure output_cb);
-
-  // Allocate/Destroy the input/output V4L2 buffers.
-  void AllocateBuffersTask(bool* result, base::WaitableEvent* done);
-
-  // Ran on device_poll_thread_ to wait for device events.
+  // Ran on |poll_task_runner_| to wait for device events.
   void DevicePollTask(bool poll_device);
 
-  // Stop all processing and clean up on |device_task_runner_|.
-  void DestroyOnDeviceSequence(base::WaitableEvent* event);
-  // Stop all processing on |poll_task_runner_|.
-  void DestroyOnPollSequence(base::WaitableEvent* event);
-
-  // Clean up pending job on |device_task_runner_|, and signal |event| after
-  // reset is finished.
-  void ResetTask(base::WaitableEvent* event);
-
   const v4l2_memory input_memory_type_;
   const v4l2_memory output_memory_type_;
 
   // V4L2 device in use.
   scoped_refptr<V4L2Device> device_;
 
-  // Sequence to communicate with the V4L2 device.
-  scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
-  // Thread used to poll the V4L2 for events only.
-  scoped_refptr<base::SingleThreadTaskRunner> poll_task_runner_;
-
-  // It is unsafe to cancel the posted tasks from different sequence using
-  // CancelableCallback and WeakPtr binding. We use CancelableTaskTracker to
-  // safely cancel tasks on |device_task_runner_| from |client_task_runner_|.
-  base::CancelableTaskTracker process_task_tracker_;
-
   // All the below members are to be accessed from |device_task_runner_| only
   // (if it's running).
   base::queue<std::unique_ptr<JobRecord>> input_job_queue_;
@@ -183,22 +168,15 @@
   // The number of input or output buffers.
   const size_t num_buffers_;
 
-  // Error callback to the client.
-  ErrorCB error_cb_;
-
-  // Checker for the device thread owned by this V4L2ImageProcessor.
-  SEQUENCE_CHECKER(device_sequence_checker_);
-  // Checker for the device thread owned by this V4L2ImageProcessor.
+  // Sequence and its checker used to poll the V4L2 for events only.
+  scoped_refptr<base::SingleThreadTaskRunner> poll_task_runner_;
   SEQUENCE_CHECKER(poll_sequence_checker_);
 
-  // WeakPtr bound to |client_task_runner_|.
-  base::WeakPtr<V4L2ImageProcessor> client_weak_this_;
-  // WeakPtr bound to |device_task_runner_|.
-  base::WeakPtr<V4L2ImageProcessor> device_weak_this_;
+  // WeakPtr bound to |backend_task_runner_|.
+  base::WeakPtr<V4L2ImageProcessor> backend_weak_this_;
   // WeakPtr bound to |poll_task_runner_|.
   base::WeakPtr<V4L2ImageProcessor> poll_weak_this_;
-  base::WeakPtrFactory<V4L2ImageProcessor> client_weak_this_factory_{this};
-  base::WeakPtrFactory<V4L2ImageProcessor> device_weak_this_factory_{this};
+  base::WeakPtrFactory<V4L2ImageProcessor> backend_weak_this_factory_{this};
   base::WeakPtrFactory<V4L2ImageProcessor> poll_weak_this_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor);
diff --git a/media/gpu/v4l2/v4l2_vda_helpers.cc b/media/gpu/v4l2/v4l2_vda_helpers.cc
index f9e272c..29a0184 100644
--- a/media/gpu/v4l2/v4l2_vda_helpers.cc
+++ b/media/gpu/v4l2/v4l2_vda_helpers.cc
@@ -4,6 +4,7 @@
 
 #include "media/gpu/v4l2/v4l2_vda_helpers.h"
 
+#include "base/bind.h"
 #include "media/base/color_plane_layout.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/macros.h"
@@ -74,13 +75,15 @@
     ImageProcessor::ErrorCB error_cb) {
   // TODO(crbug.com/917798): Use ImageProcessorFactory::Create() once we remove
   //     |image_processor_device_| from V4L2VideoDecodeAccelerator.
-  auto image_processor = V4L2ImageProcessor::Create(
-      std::move(client_task_runner), image_processor_device,
+  auto image_processor = ImageProcessor::Create(
+      base::BindRepeating(&V4L2ImageProcessor::Create, image_processor_device,
+                          nb_buffers),
       ImageProcessor::PortConfig(vda_output_format, vda_output_coded_size, {},
                                  visible_size, {VideoFrame::STORAGE_DMABUFS}),
       ImageProcessor::PortConfig(ip_output_format, ip_output_coded_size, {},
                                  visible_size, {VideoFrame::STORAGE_DMABUFS}),
-      image_processor_output_mode, nb_buffers, std::move(error_cb));
+      {image_processor_output_mode}, std::move(error_cb),
+      std::move(client_task_runner));
   if (!image_processor)
     return nullptr;
 
diff --git a/media/gpu/vaapi/vaapi_image_processor.cc b/media/gpu/vaapi/vaapi_image_processor.cc
index f95707a..69d6ba3 100644
--- a/media/gpu/vaapi/vaapi_image_processor.cc
+++ b/media/gpu/vaapi/vaapi_image_processor.cc
@@ -13,11 +13,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/sequence_checker.h"
-#include "base/sequenced_task_runner.h"
 #include "base/stl_util.h"
 #include "base/task/post_task.h"
-#include "media/base/video_frame.h"
 #include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/chromeos/platform_video_frame_utils.h"
 #include "media/gpu/macros.h"
@@ -35,11 +32,9 @@
   kMaxValue = kVaapiVppError,
 };
 
-void ReportToUMA(scoped_refptr<base::SequencedTaskRunner> task_runner,
-                 base::RepeatingClosure error_cb,
-                 VaIPFailure failure) {
+void ReportToUMA(base::RepeatingClosure error_cb, VaIPFailure failure) {
   base::UmaHistogramEnumeration("Media.VAIP.VppFailure", failure);
-  task_runner->PostTask(FROM_HERE, error_cb);
+  error_cb.Run();
 }
 
 bool IsSupported(uint32_t input_va_fourcc,
@@ -71,37 +66,15 @@
   return true;
 }
 
-void ProcessFrame(scoped_refptr<VaapiWrapper> vaapi_wrapper,
-                  scoped_refptr<VideoFrame> input_frame,
-                  scoped_refptr<VideoFrame> output_frame,
-                  scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-                  ImageProcessor::FrameReadyCB cb) {
-  DVLOGF(4);
-
-  auto src_va_surface =
-      vaapi_wrapper->CreateVASurfaceForVideoFrame(input_frame.get());
-  auto dst_va_surface =
-      vaapi_wrapper->CreateVASurfaceForVideoFrame(output_frame.get());
-  if (!src_va_surface || !dst_va_surface) {
-    // Failed to create VASurface for frames. |cb| isn't executed in the case.
-    return;
-  }
-  // VA-API performs pixel format conversion and scaling without any filters.
-  vaapi_wrapper->BlitSurface(std::move(src_va_surface),
-                             std::move(dst_va_surface));
-  client_task_runner->PostTask(
-      FROM_HERE, base::BindOnce(std::move(cb), std::move(output_frame)));
-}
-
 }  // namespace
 
 // static
-std::unique_ptr<VaapiImageProcessor> VaapiImageProcessor::Create(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
-    const std::vector<ImageProcessor::OutputMode>& preferred_output_modes,
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-    const base::RepeatingClosure& error_cb) {
+std::unique_ptr<ImageProcessorBackend> VaapiImageProcessor::Create(
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    const std::vector<OutputMode>& preferred_output_modes,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner) {
 // VaapiImageProcessor supports ChromeOS only.
 #if !defined(OS_CHROMEOS)
   return nullptr;
@@ -150,8 +123,7 @@
 
   auto vaapi_wrapper = VaapiWrapper::Create(
       VaapiWrapper::kVideoProcess, VAProfileNone,
-      base::BindRepeating(&ReportToUMA, client_task_runner, error_cb,
-                          VaIPFailure::kVaapiVppError));
+      base::BindRepeating(&ReportToUMA, error_cb, VaIPFailure::kVaapiVppError));
   if (!vaapi_wrapper) {
     VLOGF(1) << "Failed to create VaapiWrapper";
     return nullptr;
@@ -171,58 +143,48 @@
   // GetPlatformVideoFrameLayout() with a proper gfx::BufferUsage.
   // TODO(crbug.com/898423): Adjust layout once ImageProcessor provide the use
   // scenario.
-  return base::WrapUnique(new VaapiImageProcessor(
-      input_config, output_config, std::move(vaapi_wrapper),
-      std::move(client_task_runner)));
+  return base::WrapUnique<ImageProcessorBackend>(new VaapiImageProcessor(
+      std::move(vaapi_wrapper), input_config, output_config, OutputMode::IMPORT,
+      std::move(error_cb), std::move(backend_task_runner)));
 }
 
 VaapiImageProcessor::VaapiImageProcessor(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
     scoped_refptr<VaapiWrapper> vaapi_wrapper,
-    scoped_refptr<base::SequencedTaskRunner> client_task_runner)
-    : ImageProcessor(input_config,
-                     output_config,
-                     OutputMode::IMPORT,
-                     std::move(client_task_runner)),
-      processor_task_runner_(base::CreateSequencedTaskRunner(
-          base::TaskTraits{base::ThreadPool()})),
-      vaapi_wrapper_(std::move(vaapi_wrapper)) {
-  DETACH_FROM_SEQUENCE(client_sequence_checker_);
-}
+    const PortConfig& input_config,
+    const PortConfig& output_config,
+    OutputMode output_mode,
+    ErrorCB error_cb,
+    scoped_refptr<base::SequencedTaskRunner> backend_task_runner)
+    : ImageProcessorBackend(input_config,
+                            output_config,
+                            output_mode,
+                            std::move(error_cb),
+                            std::move(backend_task_runner)),
+      vaapi_wrapper_(std::move(vaapi_wrapper)) {}
 
 VaapiImageProcessor::~VaapiImageProcessor() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 }
 
-bool VaapiImageProcessor::ProcessInternal(
-    scoped_refptr<VideoFrame> input_frame,
-    scoped_refptr<VideoFrame> output_frame,
-    FrameReadyCB cb) {
+void VaapiImageProcessor::Process(scoped_refptr<VideoFrame> input_frame,
+                                  scoped_refptr<VideoFrame> output_frame,
+                                  FrameReadyCB cb) {
   DVLOGF(4);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
 
-  FrameReadyCB on_frame_ready =
-      base::BindOnce(&VaapiImageProcessor::OnOutputFrameReady,
-                     weak_factory_.GetWeakPtr(), std::move(cb));
-  processor_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&ProcessFrame, vaapi_wrapper_, std::move(input_frame),
-                     std::move(output_frame), client_task_runner_,
-                     std::move(on_frame_ready)));
-  return true;
+  auto src_va_surface =
+      vaapi_wrapper_->CreateVASurfaceForVideoFrame(input_frame.get());
+  auto dst_va_surface =
+      vaapi_wrapper_->CreateVASurfaceForVideoFrame(output_frame.get());
+  if (!src_va_surface || !dst_va_surface) {
+    // Failed to create VASurface for frames. |cb| isn't executed in the case.
+    return;
+  }
+  // VA-API performs pixel format conversion and scaling without any filters.
+  vaapi_wrapper_->BlitSurface(std::move(src_va_surface),
+                              std::move(dst_va_surface));
+
+  std::move(cb).Run(std::move(output_frame));
 }
 
-void VaapiImageProcessor::OnOutputFrameReady(FrameReadyCB cb,
-                                             scoped_refptr<VideoFrame> frame) {
-  std::move(cb).Run(std::move(frame));
-}
-
-bool VaapiImageProcessor::Reset() {
-  VLOGF(2);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-
-  weak_factory_.InvalidateWeakPtrs();
-  return true;
-}
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_image_processor.h b/media/gpu/vaapi/vaapi_image_processor.h
index f1a83aa..7c605e22 100644
--- a/media/gpu/vaapi/vaapi_image_processor.h
+++ b/media/gpu/vaapi/vaapi_image_processor.h
@@ -7,12 +7,9 @@
 
 #include <memory>
 
-#include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "build/build_config.h"
-#include "media/gpu/chromeos/image_processor.h"
+#include "media/gpu/chromeos/image_processor_backend.h"
+#include "media/gpu/media_gpu_export.h"
 
 namespace media {
 
@@ -20,46 +17,37 @@
 
 // ImageProcessor that is hardware accelerated with VA-API. This ImageProcessor
 // supports DmaBuf only for both input and output.
-class VaapiImageProcessor : public ImageProcessor {
+class VaapiImageProcessor : public ImageProcessorBackend {
  public:
   // Factory method to create VaapiImageProcessor for a buffer conversion
   // specified by |input_config| and |output_config|. Provided |error_cb| will
   // be posted to the same thread that executes Create(), if an error occurs
   // after initialization.
   // Returns nullptr if it fails to create VaapiImageProcessor.
-  static std::unique_ptr<VaapiImageProcessor> Create(
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
-      const std::vector<ImageProcessor::OutputMode>& preferred_output_modes,
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner,
-      const base::RepeatingClosure& error_cb);
+  static std::unique_ptr<ImageProcessorBackend> Create(
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      const std::vector<OutputMode>& preferred_output_modes,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
 
   // ImageProcessor implementation.
-  ~VaapiImageProcessor() override;
-  bool Reset() override;
+  void Process(scoped_refptr<VideoFrame> input_frame,
+               scoped_refptr<VideoFrame> output_frame,
+               FrameReadyCB cb) override;
 
  private:
   VaapiImageProcessor(
-      const ImageProcessor::PortConfig& input_config,
-      const ImageProcessor::PortConfig& output_config,
       scoped_refptr<VaapiWrapper> vaapi_wrapper,
-      scoped_refptr<base::SequencedTaskRunner> client_task_runner);
-
-  // ImageProcessor implementation.
-  bool ProcessInternal(scoped_refptr<VideoFrame> input_frame,
-                       scoped_refptr<VideoFrame> output_frame,
-                       FrameReadyCB cb) override;
-
-  // Callback invoked on completion of VAAPI frame processing tasks.
-  void OnOutputFrameReady(FrameReadyCB cb, scoped_refptr<VideoFrame> frame);
-
-  // Sequence task runner in which the buffer conversion is performed.
-  const scoped_refptr<base::SequencedTaskRunner> processor_task_runner_;
+      const PortConfig& input_config,
+      const PortConfig& output_config,
+      OutputMode output_mode,
+      ErrorCB error_cb,
+      scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
+  ~VaapiImageProcessor() override;
 
   const scoped_refptr<VaapiWrapper> vaapi_wrapper_;
 
-  base::WeakPtrFactory<VaapiImageProcessor> weak_factory_{this};
-
   DISALLOW_COPY_AND_ASSIGN(VaapiImageProcessor);
 };
 
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index 08886e2..67d47f5 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -96,7 +96,7 @@
     case PIXEL_FORMAT_XB30:
       buffer_formats[0] = (format == PIXEL_FORMAT_XR30)
                               ? gfx::BufferFormat::BGRX_1010102
-                              : gfx::BufferFormat::RGBX_1010102;
+                              : gfx::BufferFormat::RGBA_1010102;
       return VideoFrameResourceType::RGB;
     case PIXEL_FORMAT_I420:
       DCHECK_EQ(num_textures, 3);
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index f70b686..819a6b5 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -232,8 +232,7 @@
                void(BufferingState, BufferingStateChangeReason));
   MOCK_METHOD0(OnDurationChange, void());
   MOCK_METHOD2(OnAddTextTrack,
-               void(const TextTrackConfig& config,
-                    const AddTextTrackDoneCB& done_cb));
+               void(const TextTrackConfig& config, AddTextTrackDoneCB done_cb));
   MOCK_METHOD1(OnWaiting, void(WaitingReason));
   MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
   MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index be0818ee..a8fe055 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -249,7 +249,7 @@
       return gfx::BufferFormat::BGRX_1010102;
     case GpuVideoAcceleratorFactories::OutputFormat::XB30:
       DCHECK_EQ(0u, plane);
-      return gfx::BufferFormat::RGBX_1010102;
+      return gfx::BufferFormat::RGBA_1010102;
     case GpuVideoAcceleratorFactories::OutputFormat::RGBA:
       DCHECK_EQ(0u, plane);
       return gfx::BufferFormat::RGBA_8888;
diff --git a/media/video/mock_gpu_video_accelerator_factories.cc b/media/video/mock_gpu_video_accelerator_factories.cc
index 78f3538..9210617 100644
--- a/media/video/mock_gpu_video_accelerator_factories.cc
+++ b/media/video/mock_gpu_video_accelerator_factories.cc
@@ -29,7 +29,7 @@
            gfx::BufferFormat::RG_88 == format_ ||
            gfx::BufferFormat::YUV_420_BIPLANAR == format_ ||
            gfx::BufferFormat::BGRX_1010102 == format_ ||
-           gfx::BufferFormat::RGBX_1010102 == format_ ||
+           gfx::BufferFormat::RGBA_1010102 == format_ ||
            gfx::BufferFormat::RGBA_8888 == format_ ||
            gfx::BufferFormat::BGRA_8888 == format_);
     DCHECK(num_planes_ <= kMaxPlanes);
diff --git a/mojo/public/tools/bindings/blink_bindings_configuration.gni b/mojo/public/tools/bindings/blink_bindings_configuration.gni
index 0dff1689..b8c0abb 100644
--- a/mojo/public/tools/bindings/blink_bindings_configuration.gni
+++ b/mojo/public/tools/bindings/blink_bindings_configuration.gni
@@ -13,6 +13,7 @@
   "//skia/public/mojom/typemaps.gni",
   "//third_party/blink/renderer/platform/mojo/blink_typemaps.gni",
   "//third_party/blink/public/blink_typemaps.gni",
+  "//ui/events/mojom/blink_typemaps.gni",
 ]
 _typemaps = []
 
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
index 677b4fa8..eae907f 100644
--- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni
+++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -60,7 +60,6 @@
   "//ui/gfx/typemaps.gni",
   "//ui/gl/typemaps.gni",
   "//ui/latency/mojom/typemaps.gni",
-  "//ui/ozone/public/mojom/typemaps.gni",
   "//url/mojom/typemaps.gni",
 ]
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 39255bb..5fefeb7 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -755,7 +755,6 @@
       "http/url_security_manager.h",
       "http/webfonts_histogram.cc",
       "http/webfonts_histogram.h",
-      "http2/platform/impl/http2_arraysize_impl.h",
       "http2/platform/impl/http2_bug_tracker_impl.h",
       "http2/platform/impl/http2_containers_impl.h",
       "http2/platform/impl/http2_estimate_memory_usage_impl.h",
@@ -859,7 +858,6 @@
       "quic/network_connection.cc",
       "quic/network_connection.h",
       "quic/platform/impl/quic_aligned_impl.h",
-      "quic/platform/impl/quic_arraysize_impl.h",
       "quic/platform/impl/quic_bbr2_sender_impl.h",
       "quic/platform/impl/quic_bug_tracker_impl.h",
       "quic/platform/impl/quic_cert_utils_impl.h",
@@ -944,6 +942,7 @@
       "quic/quic_stream_factory.h",
       "quic/quic_utils_chromium.cc",
       "quic/quic_utils_chromium.h",
+      "quiche/common/platform/impl/quiche_arraysize_impl.h",
       "quiche/common/platform/impl/quiche_endian_impl.h",
       "quiche/common/platform/impl/quiche_export_impl.h",
       "quiche/common/platform/impl/quiche_logging_impl.h",
@@ -1024,7 +1023,6 @@
       "spdy/multiplexed_http_stream.h",
       "spdy/multiplexed_session.cc",
       "spdy/multiplexed_session.h",
-      "spdy/platform/impl/spdy_arraysize_impl.h",
       "spdy/platform/impl/spdy_bug_tracker_impl.h",
       "spdy/platform/impl/spdy_containers_impl.h",
       "spdy/platform/impl/spdy_endianness_util_impl.h",
@@ -1076,6 +1074,7 @@
       "ssl/ssl_platform_key_util.h",
       "ssl/threaded_ssl_private_key.cc",
       "ssl/threaded_ssl_private_key.h",
+      "third_party/quiche/src/common/platform/api/quiche_arraysize.h",
       "third_party/quiche/src/common/platform/api/quiche_endian.h",
       "third_party/quiche/src/common/platform/api/quiche_export.h",
       "third_party/quiche/src/common/platform/api/quiche_logging.h",
@@ -1167,7 +1166,6 @@
       "third_party/quiche/src/http2/http2_constants.h",
       "third_party/quiche/src/http2/http2_structures.cc",
       "third_party/quiche/src/http2/http2_structures.h",
-      "third_party/quiche/src/http2/platform/api/http2_arraysize.h",
       "third_party/quiche/src/http2/platform/api/http2_bug_tracker.h",
       "third_party/quiche/src/http2/platform/api/http2_containers.h",
       "third_party/quiche/src/http2/platform/api/http2_estimate_memory_usage.h",
@@ -1543,7 +1541,6 @@
       "third_party/quiche/src/quic/core/uber_received_packet_manager.cc",
       "third_party/quiche/src/quic/core/uber_received_packet_manager.h",
       "third_party/quiche/src/quic/platform/api/quic_aligned.h",
-      "third_party/quiche/src/quic/platform/api/quic_arraysize.h",
       "third_party/quiche/src/quic/platform/api/quic_bbr2_sender.h",
       "third_party/quiche/src/quic/platform/api/quic_bug_tracker.h",
       "third_party/quiche/src/quic/platform/api/quic_cert_utils.h",
@@ -1641,7 +1638,6 @@
       "third_party/quiche/src/spdy/core/spdy_simple_arena.h",
       "third_party/quiche/src/spdy/core/write_scheduler.h",
       "third_party/quiche/src/spdy/core/zero_copy_output_buffer.h",
-      "third_party/quiche/src/spdy/platform/api/spdy_arraysize.h",
       "third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h",
       "third_party/quiche/src/spdy/platform/api/spdy_containers.h",
       "third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h",
diff --git a/net/base/network_isolation_key.cc b/net/base/network_isolation_key.cc
index 56e1be6a..420c6fa 100644
--- a/net/base/network_isolation_key.cc
+++ b/net/base/network_isolation_key.cc
@@ -40,9 +40,11 @@
                                          const url::Origin& frame_origin)
     : use_frame_origin_(base::FeatureList::IsEnabled(
           net::features::kAppendFrameOriginToNetworkIsolationKey)),
-      top_frame_origin_(top_frame_origin) {
+      top_frame_origin_(top_frame_origin),
+      original_top_frame_origin_(top_frame_origin) {
   if (use_frame_origin_) {
     frame_origin_ = frame_origin;
+    original_frame_origin_ = frame_origin;
   }
   if (base::FeatureList::IsEnabled(
           net::features::kUseRegistrableDomainInNetworkIsolationKey)) {
diff --git a/net/base/network_isolation_key.h b/net/base/network_isolation_key.h
index 164b105..4888607 100644
--- a/net/base/network_isolation_key.h
+++ b/net/base/network_isolation_key.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/values.h"
@@ -87,13 +88,20 @@
   // disk related to it (e.g., disk cache).
   bool IsTransient() const;
 
-  // APIs for serialization to and from the mojo structure.
+  // Getters for the original top frame and frame origins used as inputs to
+  // construct |this|. This could return different values from what the
+  // isolation key eventually uses based on whether the NIK uses eTLD+1 or not.
+  // WARNING(crbug.com/1032081): Note that these might not return the correct
+  // value associated with a request if the NIK on which this is called is from
+  // a component using multiple requests mapped to the same NIK.
   const base::Optional<url::Origin>& GetTopFrameOrigin() const {
-    return top_frame_origin_;
+    DCHECK_EQ(original_top_frame_origin_.has_value(),
+              top_frame_origin_.has_value());
+    return original_top_frame_origin_;
   }
-
   const base::Optional<url::Origin>& GetFrameOrigin() const {
-    return frame_origin_;
+    DCHECK_EQ(original_frame_origin_.has_value(), frame_origin_.has_value());
+    return original_frame_origin_;
   }
 
   // Returns true if all parts of the key are empty.
@@ -113,16 +121,25 @@
       WARN_UNUSED_RESULT;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(NetworkIsolationKeyWithFrameOriginTest,
+                           UseRegistrableDomain);
+
   void ReplaceOriginsWithRegistrableDomains();
 
   // Whether or not to use the |frame_origin_| as part of the key.
   bool use_frame_origin_;
 
-  // The origin of the top frame of the page making the request.
+  // The origin/etld+1 of the top frame of the page making the request.
   base::Optional<url::Origin> top_frame_origin_;
 
-  // The origin of the frame that initiates the request.
+  // The original top frame origin sent to the constructor of this request.
+  base::Optional<url::Origin> original_top_frame_origin_;
+
+  // The origin/etld+1 of the frame that initiates the request.
   base::Optional<url::Origin> frame_origin_;
+
+  // The original frame origin sent to the constructor of this request.
+  base::Optional<url::Origin> original_frame_origin_;
 };
 
 }  // namespace net
diff --git a/net/base/network_isolation_key_unittest.cc b/net/base/network_isolation_key_unittest.cc
index e18943ac..af421263 100644
--- a/net/base/network_isolation_key_unittest.cc
+++ b/net/base/network_isolation_key_unittest.cc
@@ -304,8 +304,9 @@
   // enabled.
   url::Origin expected_domain_a = url::Origin::Create(GURL("http://foo.test"));
   NetworkIsolationKey key(origin_a, origin_b);
-  EXPECT_EQ(expected_domain_a, key.GetTopFrameOrigin().value());
+  EXPECT_EQ(origin_a, key.GetTopFrameOrigin().value());
   EXPECT_FALSE(key.GetFrameOrigin().has_value());
+  EXPECT_EQ(expected_domain_a.Serialize(), key.ToString());
 
   // More tests for using registrable domain are in
   // NetworkIsolationKeyWithFrameOriginTest.UseRegistrableDomain.
@@ -412,27 +413,30 @@
   url::Origin expected_domain_a = url::Origin::Create(GURL("http://foo.test"));
   url::Origin expected_domain_b = url::Origin::Create(GURL("https://foo.test"));
   NetworkIsolationKey key(origin_a, origin_b);
-  EXPECT_EQ(expected_domain_a, key.GetTopFrameOrigin().value());
-  EXPECT_EQ(expected_domain_b, key.GetFrameOrigin().value());
+  EXPECT_EQ(origin_a, key.GetTopFrameOrigin().value());
+  EXPECT_EQ(origin_b, key.GetFrameOrigin().value());
+  EXPECT_EQ(expected_domain_a.Serialize() + " " + expected_domain_b.Serialize(),
+            key.ToString());
 
   // Top frame origin is opaque but not the frame origin.
   url::Origin origin_data =
       url::Origin::Create(GURL("data:text/html,<body>Hello World</body>"));
   key = NetworkIsolationKey(origin_data, origin_b);
-  EXPECT_TRUE(key.GetTopFrameOrigin()->opaque());
-  EXPECT_EQ(origin_data, key.GetTopFrameOrigin().value());
-  EXPECT_EQ(expected_domain_b, key.GetFrameOrigin().value());
+  EXPECT_TRUE(key.top_frame_origin_->opaque());
+  EXPECT_TRUE(key.ToString().empty());
+  EXPECT_EQ(origin_data, key.top_frame_origin_.value());
+  EXPECT_EQ(expected_domain_b, key.frame_origin_.value());
 
   // Top frame origin is non-opaque but frame origin is opaque.
   key = NetworkIsolationKey(origin_a, origin_data);
-  EXPECT_EQ(expected_domain_a, key.GetTopFrameOrigin().value());
+  EXPECT_EQ(expected_domain_a, key.top_frame_origin_.value());
+  EXPECT_TRUE(key.ToString().empty());
   EXPECT_EQ(origin_data, key.GetFrameOrigin().value());
-  EXPECT_TRUE(key.GetFrameOrigin()->opaque());
+  EXPECT_TRUE(key.frame_origin_->opaque());
 
   // Empty NIK stays empty.
   NetworkIsolationKey empty_key;
-  EXPECT_FALSE(empty_key.GetTopFrameOrigin().has_value());
-  EXPECT_FALSE(empty_key.GetFrameOrigin().has_value());
+  EXPECT_TRUE(key.ToString().empty());
 
   // IPv4 and IPv6 origins should not be modified, except for removing their
   // ports.
@@ -440,17 +444,17 @@
   url::Origin origin_ipv6 = url::Origin::Create(GURL("https://[::1]"));
   key = NetworkIsolationKey(origin_ipv4, origin_ipv6);
   EXPECT_EQ(url::Origin::Create(GURL("http://127.0.0.1")),
-            key.GetTopFrameOrigin().value());
-  EXPECT_EQ(origin_ipv6, key.GetFrameOrigin().value());
+            key.top_frame_origin_.value());
+  EXPECT_EQ(origin_ipv6, key.frame_origin_.value());
 
   // Nor should TLDs, recognized or not.
   url::Origin origin_tld = url::Origin::Create(GURL("http://com"));
   url::Origin origin_tld_unknown =
       url::Origin::Create(GURL("https://bar:1234"));
   key = NetworkIsolationKey(origin_tld, origin_tld_unknown);
-  EXPECT_EQ(origin_tld, key.GetTopFrameOrigin().value());
+  EXPECT_EQ(origin_tld, key.top_frame_origin_.value());
   EXPECT_EQ(url::Origin::Create(GURL("https://bar")),
-            key.GetFrameOrigin().value());
+            key.frame_origin_.value());
 
   // Check for two-part TLDs.
   url::Origin origin_two_part_tld = url::Origin::Create(GURL("http://co.uk"));
@@ -458,9 +462,32 @@
       url::Origin::Create(GURL("https://a.b.co.uk"));
   key =
       NetworkIsolationKey(origin_two_part_tld, origin_two_part_tld_with_prefix);
-  EXPECT_EQ(origin_two_part_tld, key.GetTopFrameOrigin().value());
+  EXPECT_EQ(origin_two_part_tld, key.top_frame_origin_.value());
   EXPECT_EQ(url::Origin::Create(GURL("https://b.co.uk")),
-            key.GetFrameOrigin().value());
+            key.frame_origin_.value());
+
+  // Two keys with different origins but same etld+1.
+  // Also test the getter APIs.
+  url::Origin origin_a_foo = url::Origin::Create(GURL("http://a.foo.com"));
+  url::Origin foo = url::Origin::Create(GURL("http://foo.com"));
+  url::Origin origin_b_foo = url::Origin::Create(GURL("http://b.foo.com"));
+  NetworkIsolationKey key1 = NetworkIsolationKey(origin_a_foo, origin_a_foo);
+  NetworkIsolationKey key2 = NetworkIsolationKey(origin_b_foo, origin_b_foo);
+  EXPECT_EQ(key1, key2);
+  EXPECT_EQ(foo.Serialize() + " " + foo.Serialize(), key1.ToString());
+  EXPECT_EQ(foo.Serialize() + " " + foo.Serialize(), key2.ToString());
+  EXPECT_EQ(origin_a_foo, key1.GetTopFrameOrigin());
+  EXPECT_EQ(origin_a_foo, key1.GetFrameOrigin());
+  EXPECT_EQ(origin_b_foo, key2.GetTopFrameOrigin());
+  EXPECT_EQ(origin_b_foo, key2.GetFrameOrigin());
+
+  // Copying one key to another should also copy the original origins.
+  url::Origin origin_bar = url::Origin::Create(GURL("http://a.bar.com"));
+  NetworkIsolationKey key_bar = NetworkIsolationKey(origin_bar, origin_bar);
+  NetworkIsolationKey key_copied = key_bar;
+  EXPECT_EQ(key_copied.GetTopFrameOrigin(), key_bar.GetTopFrameOrigin());
+  EXPECT_EQ(key_copied.GetFrameOrigin(), key_bar.GetFrameOrigin());
+  EXPECT_EQ(key_copied, key_bar);
 }
 
 TEST_F(NetworkIsolationKeyWithFrameOriginTest, CreateWithNewFrameOrigin) {
diff --git a/net/http2/platform/impl/http2_arraysize_impl.h b/net/http2/platform/impl/http2_arraysize_impl.h
deleted file mode 100644
index 5a927234..0000000
--- a/net/http2/platform/impl/http2_arraysize_impl.h
+++ /dev/null
@@ -1,12 +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 NET_HTTP2_PLATFORM_IMPL_HTTP2_ARRAYSIZE_IMPL_H_
-#define NET_HTTP2_PLATFORM_IMPL_HTTP2_ARRAYSIZE_IMPL_H_
-
-#include "base/stl_util.h"
-
-#define HTTP2_ARRAYSIZE_IMPL(x) base::size(x)
-
-#endif  // NET_HTTP2_PLATFORM_IMPL_HTTP2_ARRAYSIZE_IMPL_H_
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index a40414a..45f1a52 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -49,7 +49,6 @@
 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
 #include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
 #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
 #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
 #include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
diff --git a/net/quic/mock_crypto_client_stream.cc b/net/quic/mock_crypto_client_stream.cc
index 9458af6a..198932a 100644
--- a/net/quic/mock_crypto_client_stream.cc
+++ b/net/quic/mock_crypto_client_stream.cc
@@ -76,6 +76,8 @@
       proof_verify_details_(proof_verify_details),
       config_(config) {
   crypto_framer_.set_visitor(this);
+  // Simulate a negotiated cipher_suite with a fake value.
+  crypto_negotiated_params_->cipher_suite = 1;
 }
 
 MockCryptoClientStream::~MockCryptoClientStream() {}
diff --git a/net/quic/platform/impl/quic_socket_utils.cc b/net/quic/platform/impl/quic_socket_utils.cc
index 3bf2477..bb06203 100644
--- a/net/quic/platform/impl/quic_socket_utils.cc
+++ b/net/quic/platform/impl/quic_socket_utils.cc
@@ -14,8 +14,8 @@
 #include <unistd.h>
 #include <string>
 
+#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -221,9 +221,9 @@
   hdr.msg_flags = 0;
 
   struct cmsghdr* cmsg = reinterpret_cast<struct cmsghdr*>(cbuf);
-  cmsg->cmsg_len = QUIC_ARRAYSIZE(cbuf);
+  cmsg->cmsg_len = QUICHE_ARRAYSIZE(cbuf);
   hdr.msg_control = cmsg;
-  hdr.msg_controllen = QUIC_ARRAYSIZE(cbuf);
+  hdr.msg_controllen = QUICHE_ARRAYSIZE(cbuf);
 
   int bytes_read = recvmsg(fd, &hdr, 0);
 
@@ -238,7 +238,7 @@
 
   if (hdr.msg_flags & MSG_CTRUNC) {
     QUIC_BUG << "Incorrectly set control length: " << hdr.msg_controllen
-             << ", expected " << QUIC_ARRAYSIZE(cbuf);
+             << ", expected " << QUICHE_ARRAYSIZE(cbuf);
     return -1;
   }
 
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h
index 0838a15..25d05a67 100644
--- a/net/quic/quic_flags_list.h
+++ b/net/quic/quic_flags_list.h
@@ -408,3 +408,9 @@
 // If true, QuicSentPacketManager will cap ack_delay to
 // peer_advertized_ack_delay before using it.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_sanitize_ack_delay, false)
+
+// If true, allow connection IDs of length [21,255] in version
+// negotiation packets.
+QUIC_FLAG(bool,
+          FLAGS_quic_restart_flag_quic_allow_very_long_connection_ids,
+          false)
diff --git a/net/quiche/common/platform/impl/quiche_arraysize_impl.h b/net/quiche/common/platform/impl/quiche_arraysize_impl.h
new file mode 100644
index 0000000..fe15b81
--- /dev/null
+++ b/net/quiche/common/platform/impl/quiche_arraysize_impl.h
@@ -0,0 +1,12 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_ARRAYSIZE_IMPL_H_
+#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_ARRAYSIZE_IMPL_H_
+
+#include "base/stl_util.h"
+
+#define QUICHE_ARRAYSIZE_IMPL(x) base::size(x)
+
+#endif  // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_ARRAYSIZE_IMPL_H_
diff --git a/net/spdy/platform/impl/spdy_arraysize_impl.h b/net/spdy/platform/impl/spdy_arraysize_impl.h
deleted file mode 100644
index 47a09d19..0000000
--- a/net/spdy/platform/impl/spdy_arraysize_impl.h
+++ /dev/null
@@ -1,12 +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 NET_SPDY_PLATFORM_IMPL_SPDY_ARRAYSIZE_IMPL_H_
-#define NET_SPDY_PLATFORM_IMPL_SPDY_ARRAYSIZE_IMPL_H_
-
-#include "base/stl_util.h"
-
-#define SPDY_ARRAYSIZE_IMPL(x) base::size(x)
-
-#endif  // NET_SPDY_PLATFORM_IMPL_SPDY_ARRAYSIZE_IMPL_H_
diff --git a/pdf/pdfium/pdfium_print.cc b/pdf/pdfium/pdfium_print.cc
index 8aff468..cdfc788 100644
--- a/pdf/pdfium/pdfium_print.cc
+++ b/pdf/pdfium/pdfium_print.cc
@@ -442,8 +442,6 @@
                         bitmap_size.height(), print_settings.orientation,
                         FPDF_PRINTING);
 
-  unsigned char* bitmap_data =
-      static_cast<unsigned char*>(FPDFBitmap_GetBuffer(bitmap.get()));
   double ratio_x = ConvertUnitDouble(bitmap_size.width(), print_settings.dpi,
                                      kPointsPerInch);
   double ratio_y = ConvertUnitDouble(bitmap_size.height(), print_settings.dpi,
@@ -451,7 +449,7 @@
 
   // Add the bitmap to an image object and add the image object to the output
   // page.
-  FPDF_PAGEOBJECT temp_img = FPDFPageObj_NewImageObj(temp_doc.get());
+  ScopedFPDFPageObject temp_img(FPDFPageObj_NewImageObj(temp_doc.get()));
 
   bool encoded = false;
   std::vector<uint8_t> compressed_bitmap_data;
@@ -463,7 +461,8 @@
     SkImageInfo info = SkImageInfo::Make(
         FPDFBitmap_GetWidth(bitmap.get()), FPDFBitmap_GetHeight(bitmap.get()),
         kBGRA_8888_SkColorType, kOpaque_SkAlphaType);
-    SkPixmap src(info, bitmap_data, FPDFBitmap_GetStride(bitmap.get()));
+    SkPixmap src(info, FPDFBitmap_GetBuffer(bitmap.get()),
+                 FPDFBitmap_GetStride(bitmap.get()));
     encoded = gfx::JPEGCodec::Encode(src, kQuality, &compressed_bitmap_data);
   }
 
@@ -478,13 +477,14 @@
       file_access.m_GetBlock = &GetBlockForJpeg;
       file_access.m_Param = &compressed_bitmap_data;
 
-      FPDFImageObj_LoadJpegFileInline(&temp_page, 1, temp_img, &file_access);
+      FPDFImageObj_LoadJpegFileInline(&temp_page, 1, temp_img.get(),
+                                      &file_access);
     } else {
-      FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap.get());
+      FPDFImageObj_SetBitmap(&temp_page, 1, temp_img.get(), bitmap.get());
     }
 
-    FPDFImageObj_SetMatrix(temp_img, ratio_x, 0, 0, ratio_y, 0, 0);
-    FPDFPage_InsertObject(temp_page, temp_img);
+    FPDFImageObj_SetMatrix(temp_img.get(), ratio_x, 0, 0, ratio_y, 0, 0);
+    FPDFPage_InsertObject(temp_page, temp_img.release());
     FPDFPage_GenerateContent(temp_page);
   }
 
diff --git a/remoting/host/input_monitor/local_mouse_input_monitor_mac.mm b/remoting/host/input_monitor/local_mouse_input_monitor_mac.mm
index 8bab7fc..fb33809 100644
--- a/remoting/host/input_monitor/local_mouse_input_monitor_mac.mm
+++ b/remoting/host/input_monitor/local_mouse_input_monitor_mac.mm
@@ -244,7 +244,8 @@
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     LocalInputMonitor::PointerMoveCallback on_mouse_move,
     base::OnceClosure disconnect_callback) {
-  return nullptr;
+  return std::make_unique<LocalMouseInputMonitorMac>(
+      caller_task_runner, ui_task_runner, std::move(on_mouse_move));
 }
 
 }  // namespace remoting
diff --git a/remoting/ios/app/remoting_ios_tmpl.gni b/remoting/ios/app/remoting_ios_tmpl.gni
index 212880d1..1080e2b 100644
--- a/remoting/ios/app/remoting_ios_tmpl.gni
+++ b/remoting/ios/app/remoting_ios_tmpl.gni
@@ -104,8 +104,8 @@
     deps = invoker.deps
 
     bundle_deps = [
-      ":$_launchscreen_storyboard_target_name",
       ":$_credits_bundle_target_name",
+      ":$_launchscreen_storyboard_target_name",
     ]
 
     assert_no_deps = [ "//third_party/ffmpeg:*" ]
diff --git a/remoting/protocol/channel_socket_adapter.cc b/remoting/protocol/channel_socket_adapter.cc
index 0018977..03811a4 100644
--- a/remoting/protocol/channel_socket_adapter.cc
+++ b/remoting/protocol/channel_socket_adapter.cc
@@ -125,7 +125,7 @@
 }
 
 void TransportChannelSocketAdapter::OnNewPacket(
-    rtc::PacketTransportInterface* transport,
+    rtc::PacketTransportInternal* transport,
     const char* data,
     size_t data_size,
     const int64_t& packet_time,
@@ -155,7 +155,7 @@
 }
 
 void TransportChannelSocketAdapter::OnWritableState(
-    rtc::PacketTransportInterface* transport) {
+    rtc::PacketTransportInternal* transport) {
   DCHECK(thread_checker_.CalledOnValidThread());
   // Try to send the packet if there is a pending write.
   if (!write_callback_.is_null()) {
diff --git a/remoting/protocol/channel_socket_adapter.h b/remoting/protocol/channel_socket_adapter.h
index b61657d..1894c70 100644
--- a/remoting/protocol/channel_socket_adapter.h
+++ b/remoting/protocol/channel_socket_adapter.h
@@ -19,7 +19,7 @@
 // TODO(johan): Replace #include by forward declaration once proper
 // inheritance is defined for rtc::PacketTransportInterface and
 // cricket::TransportChannel.
-#include "third_party/webrtc/p2p/base/packet_transport_interface.h"
+#include "third_party/webrtc/p2p/base/packet_transport_internal.h"
 #include "third_party/webrtc/rtc_base/async_packet_socket.h"
 #include "third_party/webrtc/rtc_base/socket_address.h"
 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
@@ -58,12 +58,12 @@
            const net::CompletionRepeatingCallback& callback) override;
 
  private:
-  void OnNewPacket(rtc::PacketTransportInterface* transport,
+  void OnNewPacket(rtc::PacketTransportInternal* transport,
                    const char* data,
                    size_t data_size,
                    const int64_t& packet_time,
                    int flags);
-  void OnWritableState(rtc::PacketTransportInterface* transport);
+  void OnWritableState(rtc::PacketTransportInternal* transport);
   void OnChannelDestroyed(cricket::IceTransportInternal* ice_transport);
 
   base::ThreadChecker thread_checker_;
diff --git a/remoting/protocol/ice_transport_channel.cc b/remoting/protocol/ice_transport_channel.cc
index 085db40..92355f7 100644
--- a/remoting/protocol/ice_transport_channel.cc
+++ b/remoting/protocol/ice_transport_channel.cc
@@ -18,7 +18,7 @@
 #include "remoting/protocol/transport_context.h"
 #include "third_party/webrtc/p2p/base/p2p_constants.h"
 #include "third_party/webrtc/p2p/base/p2p_transport_channel.h"
-#include "third_party/webrtc/p2p/base/packet_transport_interface.h"
+#include "third_party/webrtc/p2p/base/packet_transport_internal.h"
 #include "third_party/webrtc/p2p/base/port.h"
 #include "third_party/webrtc/rtc_base/network.h"
 
@@ -197,9 +197,9 @@
 }
 
 void IceTransportChannel::OnWritableState(
-    rtc::PacketTransportInterface* transport) {
+    rtc::PacketTransportInternal* transport) {
   DCHECK_EQ(transport,
-            static_cast<rtc::PacketTransportInterface*>(channel_.get()));
+            static_cast<rtc::PacketTransportInternal*>(channel_.get()));
 
   if (transport->writable()) {
     connect_attempts_left_ =
diff --git a/remoting/protocol/ice_transport_channel.h b/remoting/protocol/ice_transport_channel.h
index b3ded2b..9f0d182 100644
--- a/remoting/protocol/ice_transport_channel.h
+++ b/remoting/protocol/ice_transport_channel.h
@@ -19,7 +19,7 @@
 #include "third_party/webrtc/p2p/base/ice_transport_internal.h"
 // TODO(johan): Replace #include by forward declaration once proper inheritance
 // is defined for rtc::PacketTransportInterface and cricket::TransportChannel.
-#include "third_party/webrtc/p2p/base/packet_transport_interface.h"
+#include "third_party/webrtc/p2p/base/packet_transport_internal.h"
 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
 
 namespace cricket {
@@ -102,7 +102,7 @@
                            const cricket::Candidate& candidate);
   void OnRouteChange(cricket::IceTransportInternal* ice_transport,
                      const cricket::Candidate& candidate);
-  void OnWritableState(rtc::PacketTransportInterface* transport);
+  void OnWritableState(rtc::PacketTransportInternal* transport);
 
   // Callback for TransportChannelSocketAdapter to notify when the socket is
   // destroyed.
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index d7647ce..0760056 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -254,9 +254,11 @@
           HANDLE job_handle = tracker->job.Get();
 
           // Erase by comparing with the job handle.
-          jobs.erase(std::remove_if(
-              jobs.begin(), jobs.end(),
-              [&](auto&& p) -> bool { return p->job.Get() == job_handle; }));
+          jobs.erase(std::remove_if(jobs.begin(), jobs.end(),
+                                    [&](auto&& p) -> bool {
+                                      return p->job.Get() == job_handle;
+                                    }),
+                     jobs.end());
           break;
         }
 
@@ -345,10 +347,12 @@
       tracker->wait_handle = INVALID_HANDLE_VALUE;
 
       // PID is unique until the process handle is closed in dtor.
-      processes.erase(std::remove_if(
-          processes.begin(), processes.end(), [&](auto&& p) -> bool {
-            return p->process_id == tracker->process_id;
-          }));
+      processes.erase(std::remove_if(processes.begin(), processes.end(),
+                                     [&](auto&& p) -> bool {
+                                       return p->process_id ==
+                                              tracker->process_id;
+                                     }),
+                      processes.end());
 
     } else if (THREAD_CTRL_GET_POLICY_INFO == key) {
       // Clone the policies for sandbox diagnostics.
diff --git a/services/network/cert_verifier_with_trust_anchors.cc b/services/network/cert_verifier_with_trust_anchors.cc
index f307277d..d39b305 100644
--- a/services/network/cert_verifier_with_trust_anchors.cc
+++ b/services/network/cert_verifier_with_trust_anchors.cc
@@ -19,7 +19,7 @@
 namespace {
 
 void MaybeSignalAnchorUse(int error,
-                          const base::Closure& anchor_used_callback,
+                          const base::RepeatingClosure& anchor_used_callback,
                           const net::CertVerifyResult& verify_result) {
   if (error != net::OK || !verify_result.is_issued_by_additional_trust_anchor ||
       anchor_used_callback.is_null()) {
@@ -28,10 +28,11 @@
   anchor_used_callback.Run();
 }
 
-void CompleteAndSignalAnchorUse(const base::Closure& anchor_used_callback,
-                                net::CompletionOnceCallback completion_callback,
-                                const net::CertVerifyResult* verify_result,
-                                int error) {
+void CompleteAndSignalAnchorUse(
+    const base::RepeatingClosure& anchor_used_callback,
+    net::CompletionOnceCallback completion_callback,
+    const net::CertVerifyResult* verify_result,
+    int error) {
   MaybeSignalAnchorUse(error, anchor_used_callback, *verify_result);
   std::move(completion_callback).Run(error);
 }
@@ -49,7 +50,7 @@
 }  // namespace
 
 CertVerifierWithTrustAnchors::CertVerifierWithTrustAnchors(
-    const base::Closure& anchor_used_callback)
+    const base::RepeatingClosure& anchor_used_callback)
     : anchor_used_callback_(anchor_used_callback) {
   DETACH_FROM_THREAD(thread_checker_);
 }
diff --git a/services/network/cert_verifier_with_trust_anchors.h b/services/network/cert_verifier_with_trust_anchors.h
index 1104a36a..b03a52e 100644
--- a/services/network/cert_verifier_with_trust_anchors.h
+++ b/services/network/cert_verifier_with_trust_anchors.h
@@ -36,7 +36,7 @@
   // certificate from the additional trust anchors (set with SetTrustAnchors) is
   // used.
   explicit CertVerifierWithTrustAnchors(
-      const base::Closure& anchor_used_callback);
+      const base::RepeatingClosure& anchor_used_callback);
   ~CertVerifierWithTrustAnchors() override;
 
   // TODO(jam): once the network service is the only path, rename or get rid of
@@ -58,7 +58,7 @@
  private:
   net::CertVerifier::Config orig_config_;
   net::CertificateList trust_anchors_;
-  base::Closure anchor_used_callback_;
+  base::RepeatingClosure anchor_used_callback_;
   std::unique_ptr<CertVerifier> delegate_;
   THREAD_CHECKER(thread_checker_);
 
diff --git a/services/network/cert_verify_proc_chromeos_unittest.cc b/services/network/cert_verify_proc_chromeos_unittest.cc
index fef1da5a..160198e 100644
--- a/services/network/cert_verify_proc_chromeos_unittest.cc
+++ b/services/network/cert_verify_proc_chromeos_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include "base/bind_helpers.h"
 #include "crypto/nss_util_internal.h"
 #include "crypto/scoped_test_nss_chromeos_user.h"
 #include "net/base/net_errors.h"
@@ -47,14 +48,12 @@
     // Create NSSCertDatabaseChromeOS for each user.
     db_1_.reset(new net::NSSCertDatabaseChromeOS(
         crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()),
-        crypto::GetPrivateSlotForChromeOSUser(
-            user_1_.username_hash(),
-            base::Callback<void(crypto::ScopedPK11Slot)>())));
+        crypto::GetPrivateSlotForChromeOSUser(user_1_.username_hash(),
+                                              base::NullCallback())));
     db_2_.reset(new net::NSSCertDatabaseChromeOS(
         crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()),
-        crypto::GetPrivateSlotForChromeOSUser(
-            user_2_.username_hash(),
-            base::Callback<void(crypto::ScopedPK11Slot)>())));
+        crypto::GetPrivateSlotForChromeOSUser(user_2_.username_hash(),
+                                              base::NullCallback())));
 
     // Create default verifier and for each user.
     verify_proc_default_ = new CertVerifyProcChromeOS();
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc
index 48a08012..c646295 100644
--- a/services/network/cors/preflight_controller.cc
+++ b/services/network/cors/preflight_controller.cc
@@ -85,6 +85,7 @@
   preflight_request->priority = request.priority;
   preflight_request->fetch_request_context_type =
       request.fetch_request_context_type;
+  preflight_request->destination = request.destination;
   preflight_request->referrer = request.referrer;
   preflight_request->referrer_policy = request.referrer_policy;
 
diff --git a/services/network/expect_ct_reporter.cc b/services/network/expect_ct_reporter.cc
index cd3a56c6..438c6cd 100644
--- a/services/network/expect_ct_reporter.cc
+++ b/services/network/expect_ct_reporter.cc
@@ -138,9 +138,10 @@
 
 }  // namespace
 
-ExpectCTReporter::ExpectCTReporter(net::URLRequestContext* request_context,
-                                   const base::Closure& success_callback,
-                                   const base::Closure& failure_callback)
+ExpectCTReporter::ExpectCTReporter(
+    net::URLRequestContext* request_context,
+    const base::RepeatingClosure& success_callback,
+    const base::RepeatingClosure& failure_callback)
     : report_sender_(new net::ReportSender(request_context,
                                            kExpectCTReporterTrafficAnnotation)),
       request_context_(request_context),
@@ -226,13 +227,14 @@
     return;
   }
 
-  report_sender_->Send(
-      preflight->report_uri, "application/expect-ct-report+json; charset=utf-8",
-      preflight->serialized_report, success_callback_,
-      // Since |this| owns the |report_sender_|, it's safe to
-      // use base::Unretained here: |report_sender_| will be
-      // destroyed before |this|.
-      base::Bind(&ExpectCTReporter::OnReportFailure, base::Unretained(this)));
+  report_sender_->Send(preflight->report_uri,
+                       "application/expect-ct-report+json; charset=utf-8",
+                       preflight->serialized_report, success_callback_,
+                       // Since |this| owns the |report_sender_|, it's safe to
+                       // use base::Unretained here: |report_sender_| will be
+                       // destroyed before |this|.
+                       base::BindRepeating(&ExpectCTReporter::OnReportFailure,
+                                           base::Unretained(this)));
   inflight_preflights_.erase(request);
 }
 
diff --git a/services/network/expect_ct_reporter.h b/services/network/expect_ct_reporter.h
index b7f1b60f..141b370 100644
--- a/services/network/expect_ct_reporter.h
+++ b/services/network/expect_ct_reporter.h
@@ -37,8 +37,8 @@
   // |request_context|. |success_callback| is called whenever a report sends
   // successfully, and |failure_callback| whenever a report fails to send.
   ExpectCTReporter(net::URLRequestContext* request_context,
-                   const base::Closure& success_callback,
-                   const base::Closure& failure_callback);
+                   const base::RepeatingClosure& success_callback,
+                   const base::RepeatingClosure& failure_callback);
   ~ExpectCTReporter() override;
 
   // net::TransportSecurityState::ExpectCTReporter:
@@ -99,8 +99,8 @@
 
   net::URLRequestContext* request_context_;
 
-  base::Closure success_callback_;
-  base::Closure failure_callback_;
+  base::RepeatingClosure success_callback_;
+  base::RepeatingClosure failure_callback_;
 
   // The CORS preflight requests, with corresponding report information, that
   // are currently in-flight. Entries in this map are deleted when the
diff --git a/services/network/expect_ct_reporter_unittest.cc b/services/network/expect_ct_reporter_unittest.cc
index 8982d1e6..de6a99e 100644
--- a/services/network/expect_ct_reporter_unittest.cc
+++ b/services/network/expect_ct_reporter_unittest.cc
@@ -48,16 +48,16 @@
   void Send(const GURL& report_uri,
             base::StringPiece content_type,
             base::StringPiece serialized_report,
-            const base::Callback<void()>& success_callback,
-            const base::Callback<void(const GURL&, int, int)>& error_callback)
-      override {
+            const base::RepeatingCallback<void()>& success_callback,
+            const base::RepeatingCallback<void(const GURL&, int, int)>&
+                error_callback) override {
     sent_report_count_++;
     latest_report_uri_ = report_uri;
     serialized_report.CopyToString(&latest_serialized_report_);
     content_type.CopyToString(&latest_content_type_);
     if (!report_callback_.is_null()) {
       EXPECT_EQ(expected_report_uri_, latest_report_uri_);
-      report_callback_.Run();
+      std::move(report_callback_).Run();
     }
   }
 
@@ -92,7 +92,7 @@
   GURL latest_report_uri_;
   std::string latest_content_type_;
   std::string latest_serialized_report_;
-  base::Closure report_callback_;
+  base::OnceClosure report_callback_;
   GURL expected_report_uri_;
 };
 
@@ -269,9 +269,10 @@
 class TestExpectCTNetworkDelegate : public net::NetworkDelegateImpl {
  public:
   TestExpectCTNetworkDelegate()
-      : url_request_destroyed_callback_(base::Closure()) {}
+      : url_request_destroyed_callback_(base::NullCallback()) {}
 
-  void set_url_request_destroyed_callback(const base::Closure& callback) {
+  void set_url_request_destroyed_callback(
+      const base::RepeatingClosure& callback) {
     url_request_destroyed_callback_ = callback;
   }
 
@@ -281,7 +282,7 @@
   }
 
  private:
-  base::Closure url_request_destroyed_callback_;
+  base::RepeatingClosure url_request_destroyed_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(TestExpectCTNetworkDelegate);
 };
@@ -408,11 +409,11 @@
 
     base::RunLoop bad_cors_run_loop;
     report_server_.RegisterRequestHandler(
-        base::Bind(&HandleReportPreflightForPath, fail_path, bad_cors_headers,
-                   bad_cors_run_loop.QuitClosure()));
+        base::BindRepeating(&HandleReportPreflightForPath, fail_path,
+                            bad_cors_headers, bad_cors_run_loop.QuitClosure()));
     report_server_.RegisterRequestHandler(
-        base::Bind(&HandleReportPreflightForPath, successful_path,
-                   good_cors_headers, base::RepeatingClosure()));
+        base::BindRepeating(&HandleReportPreflightForPath, successful_path,
+                            good_cors_headers, base::RepeatingClosure()));
     ASSERT_TRUE(report_server_.Start());
 
     const GURL fail_report_uri = test_server().GetURL(fail_path);
@@ -449,7 +450,7 @@
 
 // Test that no report is sent when the feature is not enabled.
 TEST_F(ExpectCTReporterTest, FeatureDisabled) {
-  test_server().RegisterRequestHandler(base::Bind(
+  test_server().RegisterRequestHandler(base::BindRepeating(
       &HandleReportPreflight, kGoodCorsHeaders, base::RepeatingClosure()));
   ASSERT_TRUE(test_server().Start());
 
@@ -458,7 +459,8 @@
 
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -509,7 +511,8 @@
 
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -529,7 +532,8 @@
   histograms.ExpectTotalCount(kFailureHistogramName, 0);
   histograms.ExpectTotalCount(kSendHistogramName, 0);
 
-  ExpectCTReporter reporter(context(), base::Closure(), base::Closure());
+  ExpectCTReporter reporter(context(), base::NullCallback(),
+                            base::NullCallback());
 
   net::SSLInfo ssl_info;
   ssl_info.cert =
@@ -553,7 +557,8 @@
 // Test that if a report fails to send, the failure callback is called.
 TEST_F(ExpectCTReporterWaitTest, SendReportFailureCallback) {
   base::RunLoop run_loop;
-  ExpectCTReporter reporter(context(), base::Closure(), run_loop.QuitClosure());
+  ExpectCTReporter reporter(context(), base::NullCallback(),
+                            run_loop.QuitClosure());
 
   net::SSLInfo ssl_info;
   ssl_info.cert =
@@ -579,7 +584,8 @@
 
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -647,9 +653,9 @@
 
   const std::string report_path = "/report";
   base::RunLoop cors_run_loop;
-  test_server().RegisterRequestHandler(base::Bind(&HandleReportPreflightForPath,
-                                                  report_path, kGoodCorsHeaders,
-                                                  cors_run_loop.QuitClosure()));
+  test_server().RegisterRequestHandler(
+      base::BindRepeating(&HandleReportPreflightForPath, report_path,
+                          kGoodCorsHeaders, cors_run_loop.QuitClosure()));
   ASSERT_TRUE(test_server().Start());
   const GURL report_uri = test_server().GetURL(report_path);
 
@@ -678,17 +684,19 @@
 
 // Test that the success callback is called when a report is successfully sent.
 TEST_F(ExpectCTReporterTest, SendReportSuccessCallback) {
-  test_server().RegisterRequestHandler(base::Bind(
+  test_server().RegisterRequestHandler(base::BindRepeating(
       &HandleReportPreflight, kGoodCorsHeaders, base::RepeatingClosure()));
   // This test actually sends the report to the testserver, so register a
   // handler that will return OK.
-  test_server().RegisterRequestHandler(base::Bind(&ReplyToPostWith200));
+  test_server().RegisterRequestHandler(
+      base::BindRepeating(&ReplyToPostWith200));
   ASSERT_TRUE(test_server().Start());
 
   base::RunLoop run_loop;
 
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, run_loop.QuitClosure(), base::Closure());
+  ExpectCTReporter reporter(&context, run_loop.QuitClosure(),
+                            base::NullCallback());
 
   net::SSLInfo ssl_info;
   ssl_info.cert =
@@ -730,14 +738,15 @@
   std::map<std::string, std::string> cors_headers = kGoodCorsHeaders;
   cors_headers["Access-Control-Allow-Methods"] = "GET, POST";
   base::RunLoop cors_run_loop;
-  test_server().RegisterRequestHandler(base::Bind(&HandleReportPreflightForPath,
-                                                  report_path, cors_headers,
-                                                  cors_run_loop.QuitClosure()));
+  test_server().RegisterRequestHandler(
+      base::BindRepeating(&HandleReportPreflightForPath, report_path,
+                          cors_headers, cors_run_loop.QuitClosure()));
   ASSERT_TRUE(test_server().Start());
 
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -767,7 +776,8 @@
 TEST_F(ExpectCTReporterTest, BadCorsPreflightResponseOrigin) {
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -791,7 +801,8 @@
 TEST_F(ExpectCTReporterTest, BadCorsPreflightResponseMethods) {
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
@@ -815,7 +826,8 @@
 TEST_F(ExpectCTReporterTest, BadCorsPreflightResponseHeaders) {
   TestCertificateReportSender* sender = new TestCertificateReportSender();
   net::TestURLRequestContext context;
-  ExpectCTReporter reporter(&context, base::Closure(), base::Closure());
+  ExpectCTReporter reporter(&context, base::NullCallback(),
+                            base::NullCallback());
   reporter.report_sender_.reset(sender);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
diff --git a/services/network/http_cache_data_remover.cc b/services/network/http_cache_data_remover.cc
index c94363cd..7d76ca9 100644
--- a/services/network/http_cache_data_remover.cc
+++ b/services/network/http_cache_data_remover.cc
@@ -129,13 +129,13 @@
   }
 
   if (delete_begin_.is_null() && delete_end_.is_max()) {
-    rv = backend_->DoomAllEntries(base::Bind(
+    rv = backend_->DoomAllEntries(base::BindOnce(
         &HttpCacheDataRemover::ClearHttpCacheDone, weak_factory_.GetWeakPtr()));
   } else {
     rv = backend_->DoomEntriesBetween(
         delete_begin_, delete_end_,
-        base::Bind(&HttpCacheDataRemover::ClearHttpCacheDone,
-                   weak_factory_.GetWeakPtr()));
+        base::BindOnce(&HttpCacheDataRemover::ClearHttpCacheDone,
+                       weak_factory_.GetWeakPtr()));
   }
   if (rv != net::ERR_IO_PENDING) {
     // Notify by posting a task to avoid reentrency.
diff --git a/services/network/mojo_host_resolver_impl.cc b/services/network/mojo_host_resolver_impl.cc
index bbd88ef..b7765ec 100644
--- a/services/network/mojo_host_resolver_impl.cc
+++ b/services/network/mojo_host_resolver_impl.cc
@@ -95,7 +95,7 @@
     : resolver_service_(resolver_service),
       client_(std::move(client)),
       hostname_(hostname) {
-  client_.set_disconnect_handler(base::Bind(
+  client_.set_disconnect_handler(base::BindOnce(
       &MojoHostResolverImpl::Job::OnMojoDisconnect, base::Unretained(this)));
 
   net::HostResolver::ResolveHostParameters parameters;
diff --git a/services/network/mojo_host_resolver_impl_unittest.cc b/services/network/mojo_host_resolver_impl_unittest.cc
index cbc9321..aa81336 100644
--- a/services/network/mojo_host_resolver_impl_unittest.cc
+++ b/services/network/mojo_host_resolver_impl_unittest.cc
@@ -39,7 +39,7 @@
       mojo::PendingReceiver<proxy_resolver::mojom::HostResolverRequestClient>
           receiver)
       : done_(false), receiver_(this, std::move(receiver)) {
-    receiver_.set_disconnect_handler(base::Bind(
+    receiver_.set_disconnect_handler(base::BindOnce(
         &TestRequestClient::OnMojoDisconnect, base::Unretained(this)));
   }
 
@@ -58,8 +58,8 @@
   void OnMojoDisconnect();
 
   bool done_;
-  base::Closure run_loop_quit_closure_;
-  base::Closure connection_error_quit_closure_;
+  base::OnceClosure run_loop_quit_closure_;
+  base::OnceClosure connection_error_quit_closure_;
 
   mojo::Receiver<proxy_resolver::mojom::HostResolverRequestClient> receiver_;
 };
@@ -84,7 +84,7 @@
     int32_t error,
     const std::vector<net::IPAddress>& results) {
   if (!run_loop_quit_closure_.is_null()) {
-    run_loop_quit_closure_.Run();
+    std::move(run_loop_quit_closure_).Run();
   }
   ASSERT_FALSE(done_);
   error_ = error;
@@ -94,7 +94,7 @@
 
 void TestRequestClient::OnMojoDisconnect() {
   if (!connection_error_quit_closure_.is_null())
-    connection_error_quit_closure_.Run();
+    std::move(connection_error_quit_closure_).Run();
 }
 
 }  // namespace
diff --git a/services/network/network_change_manager.cc b/services/network/network_change_manager.cc
index 0c59904e5..171ebae 100644
--- a/services/network/network_change_manager.cc
+++ b/services/network/network_change_manager.cc
@@ -37,7 +37,7 @@
         client_pending_remote) {
   mojo::Remote<mojom::NetworkChangeManagerClient> client_remote(
       std::move(client_pending_remote));
-  client_remote.set_disconnect_handler(base::Bind(
+  client_remote.set_disconnect_handler(base::BindOnce(
       &NetworkChangeManager::NotificationPipeBroken,
       // base::Unretained is safe as destruction of the
       // NetworkChangeManager will also destroy the
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 9619c90..a19f24e 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1485,8 +1485,8 @@
       std::make_unique<P2PSocketManager>(
           std::move(client), std::move(trusted_socket_manager),
           std::move(socket_manager_receiver),
-          base::Bind(&NetworkContext::DestroySocketManager,
-                     base::Unretained(this)),
+          base::BindRepeating(&NetworkContext::DestroySocketManager,
+                              base::Unretained(this)),
           url_request_context_);
   socket_managers_[socket_manager.get()] = std::move(socket_manager);
 }
@@ -1670,8 +1670,9 @@
       verify_proc = CreateCertVerifyProcForUser(cert_net_fetcher_,
                                                 std::move(public_slot));
     }
-    cert_verifier_with_trust_anchors_ = new CertVerifierWithTrustAnchors(
-        base::Bind(&NetworkContext::TrustAnchorUsed, base::Unretained(this)));
+    cert_verifier_with_trust_anchors_ =
+        new CertVerifierWithTrustAnchors(base::BindRepeating(
+            &NetworkContext::TrustAnchorUsed, base::Unretained(this)));
     UpdateAdditionalCertificates(
         std::move(params_->initial_additional_certificates));
     cert_verifier_with_trust_anchors_->InitializeOnIOThread(verify_proc);
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index 67b33a8..8ea5645 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -162,17 +162,17 @@
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
 #if BUILDFLAG(IS_CT_SUPPORTED)
-void StoreBool(bool* result, const base::Closure& callback, bool value) {
+void StoreBool(bool* result, base::OnceClosure callback, bool value) {
   *result = value;
-  callback.Run();
+  std::move(callback).Run();
 }
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
 
 void StoreValue(base::Value* result,
-                const base::Closure& callback,
+                base::OnceClosure callback,
                 base::Value value) {
   *result = std::move(value);
-  callback.Run();
+  std::move(callback).Run();
 }
 
 mojom::NetworkContextParamsPtr CreateContextParams() {
@@ -2218,7 +2218,7 @@
       ->GetCookieListWithOptionsAsync(
           GURL("http://www.test.com/whatever"),
           net::CookieOptions::MakeAllInclusive(),
-          base::Bind(&GetCookieListCallback, &run_loop2, &cookies));
+          base::BindOnce(&GetCookieListCallback, &run_loop2, &cookies));
   run_loop2.Run();
   ASSERT_EQ(1u, cookies.size());
   EXPECT_EQ("TestCookie", cookies[0].Name());
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc
index 201ab001..fd14058 100644
--- a/services/network/p2p/socket_manager.cc
+++ b/services/network/p2p/socket_manager.cc
@@ -73,22 +73,21 @@
 
 class P2PSocketManager::DnsRequest {
  public:
-  typedef base::Callback<void(const net::IPAddressList&)> DoneCallback;
+  using DoneCallback = base::OnceCallback<void(const net::IPAddressList&)>;
 
   DnsRequest(net::HostResolver* host_resolver, bool enable_mdns)
       : resolver_(host_resolver), enable_mdns_(enable_mdns) {}
 
-  void Resolve(const std::string& host_name,
-               const DoneCallback& done_callback) {
+  void Resolve(const std::string& host_name, DoneCallback done_callback) {
     DCHECK(!done_callback.is_null());
 
     host_name_ = host_name;
-    done_callback_ = done_callback;
+    done_callback_ = std::move(done_callback);
 
     // Return an error if it's an empty string.
     if (host_name_.empty()) {
       net::IPAddressList address_list;
-      done_callback_.Run(address_list);
+      std::move(done_callback_).Run(address_list);
       return;
     }
 
@@ -124,14 +123,14 @@
     if (result != net::OK || !addresses) {
       LOG(ERROR) << "Failed to resolve address for " << host_name_
                  << ", errorcode: " << result;
-      done_callback_.Run(list);
+      std::move(done_callback_).Run(list);
       return;
     }
 
     for (const auto& endpoint : *addresses) {
       list.push_back(endpoint.address());
     }
-    done_callback_.Run(list);
+    std::move(done_callback_).Run(list);
   }
 
   std::string host_name_;
@@ -161,10 +160,10 @@
           this,
           std::move(trusted_socket_manager_receiver)),
       socket_manager_receiver_(this, std::move(socket_manager_receiver)) {
-  trusted_socket_manager_receiver_.set_disconnect_handler(
-      base::Bind(&P2PSocketManager::OnConnectionError, base::Unretained(this)));
-  socket_manager_receiver_.set_disconnect_handler(
-      base::Bind(&P2PSocketManager::OnConnectionError, base::Unretained(this)));
+  trusted_socket_manager_receiver_.set_disconnect_handler(base::BindOnce(
+      &P2PSocketManager::OnConnectionError, base::Unretained(this)));
+  socket_manager_receiver_.set_disconnect_handler(base::BindOnce(
+      &P2PSocketManager::OnConnectionError, base::Unretained(this)));
 }
 
 P2PSocketManager::~P2PSocketManager() {
@@ -285,8 +284,8 @@
   dns_requests_.insert(std::move(request));
   request_ptr->Resolve(
       host_name,
-      base::Bind(&P2PSocketManager::OnAddressResolved, base::Unretained(this),
-                 request_ptr, base::Passed(&callback)));
+      base::BindOnce(&P2PSocketManager::OnAddressResolved,
+                     base::Unretained(this), request_ptr, std::move(callback)));
 }
 
 void P2PSocketManager::CreateSocket(
diff --git a/services/network/p2p/socket_udp.cc b/services/network/p2p/socket_udp.cc
index e263bf3..392adab6 100644
--- a/services/network/p2p/socket_udp.cc
+++ b/services/network/p2p/socket_udp.cc
@@ -295,14 +295,14 @@
   cricket::ApplyPacketOptions(
       reinterpret_cast<uint8_t*>(packet.data->data()), packet.size,
       packet.packet_options.packet_time_params, send_time_us);
-  auto callback_binding =
-      base::Bind(&P2PSocketUdp::OnSend, base::Unretained(this), packet.id,
-                 packet.packet_options.packet_id, send_time_us / 1000);
+  auto callback_binding = base::BindRepeating(
+      &P2PSocketUdp::OnSend, base::Unretained(this), packet.id,
+      packet.packet_options.packet_id, send_time_us / 1000);
 
   // TODO(crbug.com/656607): Pass traffic annotation after DatagramSocketServer
   // is updated.
   int result = socket_->SendTo(packet.data.get(), packet.size, packet.to,
-                               callback_binding);
+                               base::BindOnce(callback_binding));
 
   // sendto() may return an error, e.g. if we've received an ICMP Destination
   // Unreachable message. When this happens try sending the same packet again,
diff --git a/services/network/p2p/socket_udp.h b/services/network/p2p/socket_udp.h
index 4223a9b..7ffa5e5 100644
--- a/services/network/p2p/socket_udp.h
+++ b/services/network/p2p/socket_udp.h
@@ -38,9 +38,9 @@
 
 class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocketUdp : public P2PSocket {
  public:
-  typedef base::Callback<std::unique_ptr<net::DatagramServerSocket>(
-      net::NetLog* net_log)>
-      DatagramServerSocketFactory;
+  using DatagramServerSocketFactory =
+      base::RepeatingCallback<std::unique_ptr<net::DatagramServerSocket>(
+          net::NetLog* net_log)>;
   P2PSocketUdp(Delegate* delegate,
                mojo::PendingRemote<mojom::P2PSocketClient> client,
                mojo::PendingReceiver<mojom::P2PSocket> socket,
diff --git a/services/network/proxy_resolver_factory_mojo.cc b/services/network/proxy_resolver_factory_mojo.cc
index b9dcd0c..325772ae 100644
--- a/services/network/proxy_resolver_factory_mojo.cc
+++ b/services/network/proxy_resolver_factory_mojo.cc
@@ -270,7 +270,7 @@
       callback_(std::move(callback)) {
   resolver->mojo_proxy_resolver_remote_->GetProxyForUrl(
       url_, network_isolation_key, receiver_.BindNewPipeAndPassRemote());
-  receiver_.set_disconnect_handler(base::Bind(
+  receiver_.set_disconnect_handler(base::BindOnce(
       &ProxyResolverMojo::Job::OnMojoDisconnect, base::Unretained(this)));
 }
 
@@ -316,8 +316,8 @@
       host_resolver_(host_resolver),
       error_observer_(std::move(error_observer)),
       net_log_(net_log) {
-  mojo_proxy_resolver_remote_.set_disconnect_handler(
-      base::Bind(&ProxyResolverMojo::OnMojoDisconnect, base::Unretained(this)));
+  mojo_proxy_resolver_remote_.set_disconnect_handler(base::BindOnce(
+      &ProxyResolverMojo::OnMojoDisconnect, base::Unretained(this)));
 }
 
 ProxyResolverMojo::~ProxyResolverMojo() {
@@ -381,8 +381,8 @@
         resolver_remote_.InitWithNewPipeAndPassReceiver(),
         receiver_.BindNewPipeAndPassRemote());
     receiver_.set_disconnect_handler(
-        base::Bind(&ProxyResolverFactoryMojo::Job::OnMojoDisconnect,
-                   base::Unretained(this)));
+        base::BindOnce(&ProxyResolverFactoryMojo::Job::OnMojoDisconnect,
+                       base::Unretained(this)));
   }
 
   void OnMojoDisconnect() { ReportResult(net::ERR_PAC_SCRIPT_TERMINATED); }
@@ -414,7 +414,8 @@
     mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
         mojo_proxy_factory,
     net::HostResolver* host_resolver,
-    const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>&
+    const base::RepeatingCallback<
+        std::unique_ptr<net::ProxyResolverErrorObserver>()>&
         error_observer_factory,
     net::NetLog* net_log)
     : ProxyResolverFactory(true),
diff --git a/services/network/proxy_resolver_factory_mojo.h b/services/network/proxy_resolver_factory_mojo.h
index 2dd8238..1ca4e00 100644
--- a/services/network/proxy_resolver_factory_mojo.h
+++ b/services/network/proxy_resolver_factory_mojo.h
@@ -35,7 +35,8 @@
       mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
           mojo_proxy_factory,
       net::HostResolver* host_resolver,
-      const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>&
+      const base::RepeatingCallback<
+          std::unique_ptr<net::ProxyResolverErrorObserver>()>&
           error_observer_factory,
       net::NetLog* net_log);
   ~ProxyResolverFactoryMojo() override;
@@ -51,7 +52,8 @@
 
   mojo::Remote<proxy_resolver::mojom::ProxyResolverFactory> mojo_proxy_factory_;
   net::HostResolver* const host_resolver_;
-  const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>
+  const base::RepeatingCallback<
+      std::unique_ptr<net::ProxyResolverErrorObserver>()>
       error_observer_factory_;
   net::NetLog* const net_log_;
 
diff --git a/services/network/proxy_resolver_factory_mojo_unittest.cc b/services/network/proxy_resolver_factory_mojo_unittest.cc
index 753a9625..56074444 100644
--- a/services/network/proxy_resolver_factory_mojo_unittest.cc
+++ b/services/network/proxy_resolver_factory_mojo_unittest.cc
@@ -209,7 +209,7 @@
 
   base::queue<GetProxyForUrlAction> get_proxy_actions_;
 
-  base::Closure quit_closure_;
+  base::OnceClosure quit_closure_;
 
   std::vector<mojo::Remote<proxy_resolver::mojom::ProxyResolverRequestClient>>
       blocked_clients_;
@@ -235,8 +235,7 @@
 
 void MockMojoProxyResolver::WakeWaiter() {
   if (!quit_closure_.is_null())
-    quit_closure_.Run();
-  quit_closure_.Reset();
+    std::move(quit_closure_).Run();
 }
 
 void MockMojoProxyResolver::ClearBlockedClients() {
@@ -378,7 +377,7 @@
   MockMojoProxyResolver* resolver_;
   base::queue<CreateProxyResolverAction> create_resolver_actions_;
 
-  base::Closure quit_closure_;
+  base::OnceClosure quit_closure_;
 
   std::vector<
       mojo::Remote<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>>
@@ -411,8 +410,7 @@
 
 void MockMojoProxyResolverFactory::WakeWaiter() {
   if (!quit_closure_.is_null())
-    quit_closure_.Run();
-  quit_closure_.Reset();
+    std::move(quit_closure_).Run();
 }
 
 void MockMojoProxyResolverFactory::ClearBlockedClients() {
@@ -516,10 +514,9 @@
     mock_proxy_resolver_factory_.reset(new MockMojoProxyResolverFactory(
         &mock_proxy_resolver_,
         factory_remote.InitWithNewPipeAndPassReceiver()));
-    proxy_resolver_factory_mojo_.reset(new ProxyResolverFactoryMojo(
-        std::move(factory_remote), &host_resolver_,
-        base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>(),
-        &net_log_));
+    proxy_resolver_factory_mojo_.reset(
+        new ProxyResolverFactoryMojo(std::move(factory_remote), &host_resolver_,
+                                     base::NullCallback(), &net_log_));
   }
 
   std::unique_ptr<Request> MakeRequest(
diff --git a/services/network/proxy_service_mojo.cc b/services/network/proxy_service_mojo.cc
index 0382857..70cf9e1 100644
--- a/services/network/proxy_service_mojo.cc
+++ b/services/network/proxy_service_mojo.cc
@@ -37,8 +37,9 @@
           std::move(proxy_config_service),
           std::make_unique<ProxyResolverFactoryMojo>(
               std::move(mojo_proxy_factory), host_resolver,
-              base::Bind(&net::NetworkDelegateErrorObserver::Create,
-                         network_delegate, base::ThreadTaskRunnerHandle::Get()),
+              base::BindRepeating(&net::NetworkDelegateErrorObserver::Create,
+                                  network_delegate,
+                                  base::ThreadTaskRunnerHandle::Get()),
               net_log),
           net_log));
 
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index 5bc8119..463009c 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -56,6 +56,8 @@
     "network_quality_tracker.h",
     "network_switches.cc",
     "network_switches.h",
+    "request_destination.cc",
+    "request_destination.h",
     "request_mode.cc",
     "request_mode.h",
     "resolve_host_client_base.cc",
diff --git a/services/network/public/cpp/cross_origin_opener_policy_parser.h b/services/network/public/cpp/cross_origin_opener_policy_parser.h
index 7fe5016..9308a25 100644
--- a/services/network/public/cpp/cross_origin_opener_policy_parser.h
+++ b/services/network/public/cpp/cross_origin_opener_policy_parser.h
@@ -11,8 +11,6 @@
 
 namespace network {
 
-const char kCrossOriginOpenerPolicyHeader[] = "cross-origin-opener-policy";
-
 // Parsing is done following the COOP spec draft:
 // https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
 // TODO(ahemery): add a fuzzer for the parser, see
diff --git a/services/network/public/cpp/network_isolation_key_mojom_traits_unittest.cc b/services/network/public/cpp/network_isolation_key_mojom_traits_unittest.cc
index 5e5f433..d9fa2c7 100644
--- a/services/network/public/cpp/network_isolation_key_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/network_isolation_key_mojom_traits_unittest.cc
@@ -52,7 +52,42 @@
     EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
                 network::mojom::NetworkIsolationKey>(&original, &copied));
     EXPECT_EQ(original, copied);
+    EXPECT_EQ(original.GetTopFrameOrigin(), copied.GetTopFrameOrigin());
+    EXPECT_EQ(original.GetFrameOrigin(), copied.GetFrameOrigin());
   }
 }
 
+class NetworkIsolationKeyMojomTraitsWithRegistrableDomain
+    : public testing::Test {
+ public:
+  NetworkIsolationKeyMojomTraitsWithRegistrableDomain() {
+    feature_list_.InitWithFeatures(
+        {net::features::kUseRegistrableDomainInNetworkIsolationKey,
+         net::features::kAppendFrameOriginToNetworkIsolationKey},
+        {});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_F(NetworkIsolationKeyMojomTraitsWithRegistrableDomain,
+       SerializeAndDeserialize) {
+  url::Origin origin_a = url::Origin::Create(GURL("http://a.foo.test/"));
+  url::Origin origin_b = url::Origin::Create(GURL("http://b.foo.test/"));
+  url::Origin domain = url::Origin::Create(GURL("http://foo.test/"));
+  net::NetworkIsolationKey original(origin_a, origin_b);
+  EXPECT_EQ(origin_a, original.GetTopFrameOrigin());
+  EXPECT_EQ(origin_b, original.GetFrameOrigin());
+
+  net::NetworkIsolationKey copied;
+  EXPECT_TRUE(
+      mojo::test::SerializeAndDeserialize<network::mojom::NetworkIsolationKey>(
+          &original, &copied));
+  EXPECT_EQ(original, copied);
+
+  EXPECT_EQ(origin_a, copied.GetTopFrameOrigin());
+  EXPECT_EQ(origin_b, copied.GetFrameOrigin());
+}
+
 }  // namespace mojo
diff --git a/services/network/public/cpp/request_destination.cc b/services/network/public/cpp/request_destination.cc
new file mode 100644
index 0000000..4cc1933
--- /dev/null
+++ b/services/network/public/cpp/request_destination.cc
@@ -0,0 +1,59 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/network/public/cpp/request_destination.h"
+
+namespace network {
+
+const char* RequestDestinationToString(
+    network::mojom::RequestDestination dest) {
+  switch (dest) {
+    case network::mojom::RequestDestination::kEmpty:
+      return "empty";
+    case network::mojom::RequestDestination::kAudio:
+      return "audio";
+    case network::mojom::RequestDestination::kAudioWorklet:
+      return "audioworklet";
+    case network::mojom::RequestDestination::kDocument:
+      return "document";
+    case network::mojom::RequestDestination::kEmbed:
+      return "embed";
+    case network::mojom::RequestDestination::kFont:
+      return "font";
+    case network::mojom::RequestDestination::kFrame:
+      return "frame";
+    case network::mojom::RequestDestination::kIframe:
+      return "iframe";
+    case network::mojom::RequestDestination::kImage:
+      return "image";
+    case network::mojom::RequestDestination::kManifest:
+      return "manifest";
+    case network::mojom::RequestDestination::kObject:
+      return "object";
+    case network::mojom::RequestDestination::kPaintWorklet:
+      return "paintworklet";
+    case network::mojom::RequestDestination::kReport:
+      return "report";
+    case network::mojom::RequestDestination::kScript:
+      return "script";
+    case network::mojom::RequestDestination::kServiceWorker:
+      return "serviceworker";
+    case network::mojom::RequestDestination::kSharedWorker:
+      return "sharedworker";
+    case network::mojom::RequestDestination::kStyle:
+      return "style";
+    case network::mojom::RequestDestination::kTrack:
+      return "track";
+    case network::mojom::RequestDestination::kVideo:
+      return "video";
+    case network::mojom::RequestDestination::kWorker:
+      return "worker";
+    case network::mojom::RequestDestination::kXslt:
+      return "xslt";
+  }
+  NOTREACHED();
+  return "empty";
+}
+
+}  // namespace network
\ No newline at end of file
diff --git a/services/network/public/cpp/request_destination.h b/services/network/public/cpp/request_destination.h
new file mode 100644
index 0000000..095e1666
--- /dev/null
+++ b/services/network/public/cpp/request_destination.h
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_NETWORK_PUBLIC_CPP_REQUEST_DESTINATION_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_REQUEST_DESTINATION_H_
+
+#include "base/component_export.h"
+#include "services/network/public/mojom/fetch_api.mojom-shared.h"
+
+namespace network {
+
+// Returns a string corresponding to the |destination| as defined in the spec:
+// https://fetch.spec.whatwg.org/#concept-request-destination.
+COMPONENT_EXPORT(NETWORK_CPP)
+const char* RequestDestinationToString(network::mojom::RequestDestination dest);
+
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_REQUEST_DESTINATION_H_
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index deadecab..d908842 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -51,6 +51,7 @@
          redirect_mode == request.redirect_mode &&
          fetch_integrity == request.fetch_integrity &&
          fetch_request_context_type == request.fetch_request_context_type &&
+         destination == request.destination &&
          request_body == request.request_body &&
          keepalive == request.keepalive &&
          has_user_gesture == request.has_user_gesture &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index 7cbd7ae1..8053136f 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -87,6 +87,7 @@
   mojom::RedirectMode redirect_mode = mojom::RedirectMode::kFollow;
   std::string fetch_integrity;
   int fetch_request_context_type = 0;
+  mojom::RequestDestination destination = mojom::RequestDestination::kEmpty;
   scoped_refptr<ResourceRequestBody> request_body;
   bool keepalive = false;
   bool has_user_gesture = false;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index d2778f0..1d2ea40 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -206,6 +206,7 @@
   out->corb_detachable = data.corb_detachable();
   out->corb_excluded = data.corb_excluded();
   out->fetch_request_context_type = data.fetch_request_context_type();
+  out->destination = data.destination();
   out->keepalive = data.keepalive();
   out->has_user_gesture = data.has_user_gesture();
   out->enable_load_timing = data.enable_load_timing();
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index 0486795..5bbbee6 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -170,6 +170,10 @@
       const network::ResourceRequest& request) {
     return request.fetch_request_context_type;
   }
+  static network::mojom::RequestDestination destination(
+      const network::ResourceRequest& request) {
+    return request.destination;
+  }
   static const scoped_refptr<network::ResourceRequestBody>& request_body(
       const network::ResourceRequest& request) {
     return request.request_body;
diff --git a/services/network/public/mojom/fetch_api.mojom b/services/network/public/mojom/fetch_api.mojom
index b734474..8d239c2 100644
--- a/services/network/public/mojom/fetch_api.mojom
+++ b/services/network/public/mojom/fetch_api.mojom
@@ -24,6 +24,32 @@
   // Add a new type here, then update enums.xml.
 };
 
+// Corresponds to Fetch request's "destination":
+// https://fetch.spec.whatwg.org/#concept-request-destination
+enum RequestDestination {
+  kEmpty,
+  kAudio,
+  kAudioWorklet,
+  kDocument,
+  kEmbed,
+  kFont,
+  kFrame,
+  kIframe,
+  kImage,
+  kManifest,
+  kObject,
+  kPaintWorklet,
+  kReport,
+  kScript,
+  kServiceWorker,
+  kSharedWorker,
+  kStyle,
+  kTrack,
+  kVideo,
+  kWorker,
+  kXslt,
+};
+
 // Corresponds to Fetch request's "redirect mode":
 // https://fetch.spec.whatwg.org/#concept-request-redirect-mode
 enum RedirectMode {
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom
index 65770e0..bde5c57 100644
--- a/services/network/public/mojom/url_loader.mojom
+++ b/services/network/public/mojom/url_loader.mojom
@@ -276,6 +276,9 @@
   // about this.
   int32 fetch_request_context_type;
 
+  // https://fetch.spec.whatwg.org/#concept-request-destiantion
+  RequestDestination destination;
+
   // Optional resource request body.
   URLRequestBody? request_body;
 
diff --git a/services/network/public/mojom/url_response_head.mojom b/services/network/public/mojom/url_response_head.mojom
index dde752d..73032766 100644
--- a/services/network/public/mojom/url_response_head.mojom
+++ b/services/network/public/mojom/url_response_head.mojom
@@ -7,6 +7,7 @@
 import "mojo/public/mojom/base/time.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 import "services/network/public/mojom/content_security_policy.mojom";
+import "services/network/public/mojom/cross_origin_embedder_policy.mojom";
 import "services/network/public/mojom/cross_origin_opener_policy.mojom";
 import "services/network/public/mojom/fetch_api.mojom";
 import "services/network/public/mojom/http_raw_request_response_info.mojom";
@@ -202,6 +203,11 @@
   // (see corresponding documentation in url_loader.mojom).
   mojo_base.mojom.UnguessableToken? recursive_prefetch_token;
 
-  // The parsed value of the Cross-Origin-Opener-Policy header.
-  CrossOriginOpenerPolicy cross_origin_opener_policy;
+  // The parsed value of the Cross-Origin-Embedder-Policy (COEP) header.
+  CrossOriginEmbedderPolicy cross_origin_embedder_policy =
+      CrossOriginEmbedderPolicy.kNone;
+
+  // The parsed value of the Cross-Origin-Opener-Policy (COOP) header.
+  CrossOriginOpenerPolicy cross_origin_opener_policy =
+      CrossOriginOpenerPolicy.kUnsafeNone;
 };
diff --git a/services/network/resource_scheduler/resource_scheduler.cc b/services/network/resource_scheduler/resource_scheduler.cc
index 5b9ac45..2012ac5 100644
--- a/services/network/resource_scheduler/resource_scheduler.cc
+++ b/services/network/resource_scheduler/resource_scheduler.cc
@@ -139,7 +139,10 @@
   // queue is not checked too frequently. The interval is also not too long, so
   // we do not expect too many requests to go on the network at the
   // same time.
-  return base::TimeDelta::FromMilliseconds(100);
+  return base::TimeDelta::FromMilliseconds(
+      base::GetFieldTrialParamByFeatureAsInt(
+          features::kProactivelyThrottleLowPriorityRequests,
+          "queued_requests_dispatch_periodicity_ms", 100));
 }
 
 struct ResourceScheduler::RequestPriorityParams {
diff --git a/services/network/sec_header_helpers.cc b/services/network/sec_header_helpers.cc
index cecde69..c14fddb 100644
--- a/services/network/sec_header_helpers.cc
+++ b/services/network/sec_header_helpers.cc
@@ -15,6 +15,7 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/initiator_lock_compatibility.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "services/network/public/cpp/request_destination.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -26,6 +27,7 @@
 const char kSecFetchMode[] = "Sec-Fetch-Mode";
 const char kSecFetchSite[] = "Sec-Fetch-Site";
 const char kSecFetchUser[] = "Sec-Fetch-User";
+const char kSecFetchDest[] = "Sec-Fetch-Dest";
 
 // Sec-Fetch-Site infrastructure:
 //
@@ -133,12 +135,20 @@
     request->RemoveRequestHeaderByName(kSecFetchUser);
 }
 
+// Sec-Fetch-Dest
+void SetSecFetchDestHeader(net::URLRequest* request,
+                           network::mojom::RequestDestination dest) {
+  std::string header_value = RequestDestinationToString(dest);
+  request->SetExtraRequestHeaderByName(kSecFetchDest, header_value, true);
+}
+
 }  // namespace
 
 void SetFetchMetadataHeaders(
     net::URLRequest* request,
     network::mojom::RequestMode mode,
     bool has_user_activation,
+    network::mojom::RequestDestination dest,
     const GURL* pending_redirect_url,
     const mojom::URLLoaderFactoryParams& factory_params) {
   DCHECK(request);
@@ -155,6 +165,7 @@
   SetSecFetchSiteHeader(request, pending_redirect_url, factory_params);
   SetSecFetchModeHeader(request, mode);
   SetSecFetchUserHeader(request, has_user_activation);
+  SetSecFetchDestHeader(request, dest);
 }
 
 void MaybeRemoveSecHeaders(net::URLRequest* request,
diff --git a/services/network/sec_header_helpers.h b/services/network/sec_header_helpers.h
index 3a90b2a..63d52d2 100644
--- a/services/network/sec_header_helpers.h
+++ b/services/network/sec_header_helpers.h
@@ -34,6 +34,7 @@
     net::URLRequest* request,
     network::mojom::RequestMode mode,
     bool has_user_activation,
+    network::mojom::RequestDestination dest,
     const GURL* pending_redirect_url,
     const mojom::URLLoaderFactoryParams& factory_params);
 
diff --git a/services/network/sec_header_helpers_unittest.cc b/services/network/sec_header_helpers_unittest.cc
index 0ba7866..8bdbae4 100644
--- a/services/network/sec_header_helpers_unittest.cc
+++ b/services/network/sec_header_helpers_unittest.cc
@@ -25,6 +25,7 @@
 constexpr char kKnownSecFetchSiteHeader[] = "Sec-Fetch-Site";
 constexpr char kKnownSecFetchModeHeader[] = "Sec-Fetch-Mode";
 constexpr char kKnownSecFetchUserHeader[] = "Sec-Fetch-User";
+constexpr char kKnownSecFetchDestHeader[] = "Sec-Fetch-Dest";
 constexpr char kOtherSecHeader[] = "sec-other-info-header";
 constexpr char kOtherHeader[] = "Other-Header";
 
@@ -168,10 +169,10 @@
   params.factory_bound_access_patterns->source_origin =
       url::Origin::Create(url);
 
-  SetFetchMetadataHeaders(current_url_request,
-                          network::mojom::RequestMode::kCors, false, &url,
-                          params);
-  ASSERT_EQ(2, static_cast<int>(current_url_request->extra_request_headers()
+  SetFetchMetadataHeaders(
+      current_url_request, network::mojom::RequestMode::kCors, false,
+      network::mojom::RequestDestination::kIframe, &url, params);
+  ASSERT_EQ(3, static_cast<int>(current_url_request->extra_request_headers()
                                     .GetHeaderVector()
                                     .size()));
 
@@ -183,6 +184,10 @@
   ASSERT_TRUE(current_url_request->extra_request_headers().GetHeader(
       kKnownSecFetchModeHeader, &header_value));
   ASSERT_EQ(header_value, "cors");
+
+  ASSERT_TRUE(current_url_request->extra_request_headers().GetHeader(
+      kKnownSecFetchDestHeader, &header_value));
+  ASSERT_EQ(header_value, "iframe");
 }
 
 // Validate Sec-Fetch-Site and Sec-Fetch-Mode are set correctly with privileged
@@ -203,11 +208,11 @@
           mojom::CorsDomainMatchMode::kDisallowSubdomains,
           mojom::CorsPortMatchMode::kAllowAnyPort,
           mojom::CorsOriginAccessMatchPriority::kDefaultPriority));
+  SetFetchMetadataHeaders(
+      current_url_request, network::mojom::RequestMode::kCors, true,
+      network::mojom::RequestDestination::kEmbed, &url, params);
 
-  SetFetchMetadataHeaders(current_url_request,
-                          network::mojom::RequestMode::kCors, true, &url,
-                          params);
-  ASSERT_EQ(3, static_cast<int>(current_url_request->extra_request_headers()
+  ASSERT_EQ(4, static_cast<int>(current_url_request->extra_request_headers()
                                     .GetHeaderVector()
                                     .size()));
 
@@ -223,6 +228,10 @@
   ASSERT_TRUE(current_url_request->extra_request_headers().GetHeader(
       kKnownSecFetchUserHeader, &header_value));
   ASSERT_EQ(header_value, "?1");
+
+  ASSERT_TRUE(current_url_request->extra_request_headers().GetHeader(
+      kKnownSecFetchDestHeader, &header_value));
+  ASSERT_EQ(header_value, "embed");
 }
 
 }  // namespace network
diff --git a/services/network/tcp_socket_unittest.cc b/services/network/tcp_socket_unittest.cc
index f713216..58aa459 100644
--- a/services/network/tcp_socket_unittest.cc
+++ b/services/network/tcp_socket_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/test/bind_test_util.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread.h"
+#include "build/build_config.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -37,6 +38,10 @@
 #include "services/network/tcp_server_socket.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "base/mac/mac_util.h"
+#endif
+
 namespace network {
 
 namespace {
@@ -568,9 +573,19 @@
   }
   EXPECT_TRUE(client_socket_send_handle->QuerySignalsState().peer_closed());
   int result = observer()->WaitForWriteError();
-  EXPECT_TRUE(result == net::ERR_CONNECTION_RESET ||
-              result == net::ERR_CONNECTION_ABORTED)
-      << "actual result: " << result;
+  bool result_ok = result == net::ERR_CONNECTION_RESET ||
+                   result == net::ERR_CONNECTION_ABORTED;
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  // On some macOS kernels, send() on a closing TCP socket can return
+  // EPROTOTYPE, which is unknown to the net stack and gets mapped to
+  // net::ERR_FAILED.
+  // This behavior is known to exist as late as 10.12. Whether it exists after
+  // that is unknown.
+  // See https://crbug.com/1034991
+  if (base::mac::IsAtMostOS10_12())
+    result_ok |= result == net::ERR_FAILED;
+#endif
+  EXPECT_TRUE(result_ok) << "actual result: " << result;
 }
 
 TEST_F(TCPSocketTest, ReadPipeClosed) {
diff --git a/services/network/throttling/throttling_network_interceptor.cc b/services/network/throttling/throttling_network_interceptor.cc
index dbde0cc..203d6d3 100644
--- a/services/network/throttling/throttling_network_interceptor.cc
+++ b/services/network/throttling/throttling_network_interceptor.cc
@@ -217,8 +217,8 @@
   }
 
   timer_.Start(FROM_HERE, desired_time - now,
-               base::Bind(&ThrottlingNetworkInterceptor::OnTimer,
-                          base::Unretained(this)));
+               base::BindOnce(&ThrottlingNetworkInterceptor::OnTimer,
+                              base::Unretained(this)));
 }
 
 int ThrottlingNetworkInterceptor::StartThrottle(
diff --git a/services/network/throttling/throttling_network_interceptor.h b/services/network/throttling/throttling_network_interceptor.h
index a2c4c46..cd09534 100644
--- a/services/network/throttling/throttling_network_interceptor.h
+++ b/services/network/throttling/throttling_network_interceptor.h
@@ -29,7 +29,7 @@
 // with specific client id.
 class COMPONENT_EXPORT(NETWORK_SERVICE) ThrottlingNetworkInterceptor {
  public:
-  using ThrottleCallback = base::Callback<void(int, int64_t)>;
+  using ThrottleCallback = base::RepeatingCallback<void(int, int64_t)>;
 
   ThrottlingNetworkInterceptor();
   virtual ~ThrottlingNetworkInterceptor();
diff --git a/services/network/throttling/throttling_network_transaction.cc b/services/network/throttling/throttling_network_transaction.cc
index 50aa304..51bb405b 100644
--- a/services/network/throttling/throttling_network_transaction.cc
+++ b/services/network/throttling/throttling_network_transaction.cc
@@ -63,7 +63,7 @@
   if (result > 0)
     throttled_byte_count_ += result;
 
-  throttle_callback_ = base::Bind(
+  throttle_callback_ = base::BindRepeating(
       &ThrottlingNetworkTransaction::ThrottleCallback, base::Unretained(this));
   int rv = interceptor_->StartThrottle(result, throttled_byte_count_, send_end,
                                        start, false, throttle_callback_);
diff --git a/services/network/throttling/throttling_upload_data_stream.cc b/services/network/throttling/throttling_upload_data_stream.cc
index d0770c524..1d191bf 100644
--- a/services/network/throttling/throttling_upload_data_stream.cc
+++ b/services/network/throttling/throttling_upload_data_stream.cc
@@ -14,8 +14,8 @@
     : net::UploadDataStream(upload_data_stream->is_chunked(),
                             upload_data_stream->identifier()),
       throttle_callback_(
-          base::Bind(&ThrottlingUploadDataStream::ThrottleCallback,
-                     base::Unretained(this))),
+          base::BindRepeating(&ThrottlingUploadDataStream::ThrottleCallback,
+                              base::Unretained(this))),
       throttled_byte_count_(0),
       upload_data_stream_(upload_data_stream) {}
 
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 634aa56..8f1e917 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -69,6 +69,10 @@
 // mojo::core::Core::CreateDataPipe
 constexpr size_t kBlockedBodyAllocationSize = 1;
 
+constexpr char kCrossOriginEmbedderPolicyHeader[] =
+    "Cross-Origin-Embedder-Policy";
+constexpr char kCrossOriginOpenerPolicyHeader[] = "Cross-Origin-Opener-Policy";
+
 // TODO: this duplicates some of PopulateResourceResponse in
 // content/browser/loader/resource_loader.cc
 void PopulateResourceResponse(net::URLRequest* request,
@@ -361,6 +365,7 @@
       report_raw_headers_(false),
       devtools_request_id_(request.devtools_request_id),
       has_user_activation_(false),
+      request_destination_(request.destination),
       resource_scheduler_client_(std::move(resource_scheduler_client)),
       keepalive_statistics_recorder_(std::move(keepalive_statistics_recorder)),
       network_usage_accumulator_(std::move(network_usage_accumulator)),
@@ -454,7 +459,8 @@
   url_request_->set_initiator(request.request_initiator);
 
   SetFetchMetadataHeaders(url_request_.get(), request_mode_,
-                          has_user_activation_, nullptr, *factory_params_);
+                          has_user_activation_, request_destination_, nullptr,
+                          *factory_params_);
 
   if (request.update_first_party_url_on_redirect) {
     url_request_->set_first_party_url_policy(
@@ -479,8 +485,8 @@
       &URLLoader::SetRawRequestHeadersAndNotify, base::Unretained(this)));
 
   if (want_raw_headers_) {
-    url_request_->SetResponseHeadersCallback(
-        base::Bind(&URLLoader::SetRawResponseHeaders, base::Unretained(this)));
+    url_request_->SetResponseHeadersCallback(base::BindRepeating(
+        &URLLoader::SetRawResponseHeaders, base::Unretained(this)));
   }
 
   if (keepalive_ && keepalive_statistics_recorder_) {
@@ -814,8 +820,8 @@
   // to do this before we re-add any.
   MaybeRemoveSecHeaders(url_request_.get(), redirect_info.new_url);
   SetFetchMetadataHeaders(url_request_.get(), request_mode_,
-                          has_user_activation_, &redirect_info.new_url,
-                          *factory_params_);
+                          has_user_activation_, request_destination_,
+                          &redirect_info.new_url, *factory_params_);
 
   url_loader_client_->OnReceiveRedirect(redirect_info, std::move(response));
 }
@@ -895,8 +901,8 @@
   network_context_client_->OnSSLCertificateError(
       factory_params_->process_id, render_frame_id_, url_request_->url(),
       net_error, ssl_info, fatal,
-      base::Bind(&URLLoader::OnSSLCertificateErrorResponse,
-                 weak_ptr_factory_.GetWeakPtr(), ssl_info));
+      base::BindRepeating(&URLLoader::OnSSLCertificateErrorResponse,
+                          weak_ptr_factory_.GetWeakPtr(), ssl_info));
 }
 
 void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
@@ -946,14 +952,14 @@
 
   peer_closed_handle_watcher_.Watch(
       response_body_stream_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
-      base::Bind(&URLLoader::OnResponseBodyStreamConsumerClosed,
-                 base::Unretained(this)));
+      base::BindRepeating(&URLLoader::OnResponseBodyStreamConsumerClosed,
+                          base::Unretained(this)));
   peer_closed_handle_watcher_.ArmOrNotify();
 
   writable_handle_watcher_.Watch(
       response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
-      base::Bind(&URLLoader::OnResponseBodyStreamReady,
-                 base::Unretained(this)));
+      base::BindRepeating(&URLLoader::OnResponseBodyStreamReady,
+                          base::Unretained(this)));
 
   // Enforce the Cross-Origin-Resource-Policy (CORP) header.
   if (CrossOriginResourcePolicy::kBlock ==
@@ -1006,13 +1012,26 @@
       response_->content_security_policy = policy.TakeContentSecurityPolicy();
   }
 
-  // Parse the Cross-Origin-Opener-Policy header.
-  std::string raw_coop_string;
-  if (url_request_->response_headers() &&
-      url_request_->response_headers()->GetNormalizedHeader(
-          kCrossOriginOpenerPolicyHeader, &raw_coop_string)) {
-    response_->cross_origin_opener_policy =
-        ParseCrossOriginOpenerPolicyHeader(raw_coop_string);
+  if (base::FeatureList::IsEnabled(features::kCrossOriginIsolation)) {
+    // Parse the Cross-Origin-Embedder-Policy header.
+    std::string raw_coep_string;
+    if (url_request_->response_headers() &&
+        url_request_->response_headers()->GetNormalizedHeader(
+            kCrossOriginEmbedderPolicyHeader, &raw_coep_string)) {
+      if (raw_coep_string == "require-corp") {
+        response_->cross_origin_embedder_policy =
+            mojom::CrossOriginEmbedderPolicy::kRequireCorp;
+      }
+    }
+
+    // Parse the Cross-Origin-Opener-Policy header.
+    std::string raw_coop_string;
+    if (url_request_->response_headers() &&
+        url_request_->response_headers()->GetNormalizedHeader(
+            kCrossOriginOpenerPolicyHeader, &raw_coop_string)) {
+      response_->cross_origin_opener_policy =
+          ParseCrossOriginOpenerPolicyHeader(raw_coop_string);
+    }
   }
 
   // If necessary, retrieve the associated origin policy, before sending the
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index 553f15d..f56c990 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -362,6 +362,9 @@
 
   bool has_user_activation_;
 
+  mojom::RequestDestination request_destination_ =
+      mojom::RequestDestination::kEmpty;
+
   scoped_refptr<ResourceSchedulerClient> resource_scheduler_client_;
 
   base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder_;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index e0f4bf8e..2adfb166 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -427,7 +427,7 @@
         base::FilePath(FILE_PATH_LITERAL("services/test/data")));
     // This Unretained is safe because test_server_ is owned by |this|.
     test_server_.RegisterRequestMonitor(
-        base::Bind(&URLLoaderTest::Monitor, base::Unretained(this)));
+        base::BindRepeating(&URLLoaderTest::Monitor, base::Unretained(this)));
     ASSERT_TRUE(test_server_.Start());
 
     // Set up a scoped host resolver so that |kInsecureHost| will resolve to
@@ -690,7 +690,7 @@
             MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
             MOJO_WATCH_CONDITION_SATISFIED,
             base::BindRepeating(
-                [](base::Closure quit, MojoResult result,
+                [](base::RepeatingClosure quit, MojoResult result,
                    const mojo::HandleSignalsState& state) { quit.Run(); },
                 run_loop.QuitClosure()));
         run_loop.Run();
@@ -1585,7 +1585,7 @@
                              OnFileUploadRequestedCallback callback) override {
     file_upload_requested_callback_ = std::move(callback);
     if (quit_closure_for_on_file_upload_requested_)
-      quit_closure_for_on_file_upload_requested_.Run();
+      std::move(quit_closure_for_on_file_upload_requested_).Run();
   }
 
   void RunUntilUploadRequested(OnFileUploadRequestedCallback* callback) {
@@ -1593,13 +1593,12 @@
       base::RunLoop run_loop;
       quit_closure_for_on_file_upload_requested_ = run_loop.QuitClosure();
       run_loop.Run();
-      quit_closure_for_on_file_upload_requested_.Reset();
     }
     *callback = std::move(file_upload_requested_callback_);
   }
 
  private:
-  base::Closure quit_closure_for_on_file_upload_requested_;
+  base::OnceClosure quit_closure_for_on_file_upload_requested_;
   OnFileUploadRequestedCallback file_upload_requested_callback_;
 };
 
@@ -2326,6 +2325,7 @@
   // Try to modify `Sec-Fetch-User` directly.
   ResourceRequest request = CreateResourceRequest("GET", url);
   request.headers.SetHeader("Sec-Fetch-User", "?1");
+  request.headers.SetHeader("Sec-Fetch-Dest", "embed");
 
   base::RunLoop delete_run_loop;
   mojo::PendingRemote<mojom::URLLoader> loader;
@@ -2347,6 +2347,7 @@
 
   const auto& request_headers = sent_request().headers;
   EXPECT_EQ(request_headers.end(), request_headers.find("Sec-Fetch-User"));
+  EXPECT_EQ("empty", request_headers.find("Sec-Fetch-Dest")->second);
 }
 
 // A mock URLRequestJob which simulates an HTTPS request with a certificate
diff --git a/services/network/url_request_context_builder_mojo_unittest.cc b/services/network/url_request_context_builder_mojo_unittest.cc
index 235df91..5b90b7c 100644
--- a/services/network/url_request_context_builder_mojo_unittest.cc
+++ b/services/network/url_request_context_builder_mojo_unittest.cc
@@ -53,7 +53,7 @@
  protected:
   URLRequestContextBuilderMojoTest()
       : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
-    test_server_.RegisterRequestHandler(base::Bind(&HandlePacRequest));
+    test_server_.RegisterRequestHandler(base::BindRepeating(&HandlePacRequest));
     test_server_.AddDefaultHandlers(
         base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
   }
diff --git a/services/preferences/public/cpp/dictionary_value_update.h b/services/preferences/public/cpp/dictionary_value_update.h
index 16382a8..3142ec9 100644
--- a/services/preferences/public/cpp/dictionary_value_update.h
+++ b/services/preferences/public/cpp/dictionary_value_update.h
@@ -18,7 +18,7 @@
 class DictionaryValue;
 class ListValue;
 class Value;
-}
+}  // namespace base
 
 namespace prefs {
 
@@ -26,7 +26,8 @@
 // via a callback.
 class DictionaryValueUpdate {
  public:
-  using UpdateCallback = base::Callback<void(const std::vector<std::string>&)>;
+  using UpdateCallback =
+      base::RepeatingCallback<void(const std::vector<std::string>&)>;
 
   DictionaryValueUpdate(UpdateCallback report_update,
                         base::DictionaryValue* value,
diff --git a/services/preferences/public/cpp/scoped_pref_update.cc b/services/preferences/public/cpp/scoped_pref_update.cc
index c04940e..b771ddd 100644
--- a/services/preferences/public/cpp/scoped_pref_update.cc
+++ b/services/preferences/public/cpp/scoped_pref_update.cc
@@ -23,8 +23,8 @@
 
 std::unique_ptr<DictionaryValueUpdate> ScopedDictionaryPrefUpdate::Get() {
   return std::make_unique<DictionaryValueUpdate>(
-      base::Bind(&ScopedDictionaryPrefUpdate::RecordPath,
-                 base::Unretained(this)),
+      base::BindRepeating(&ScopedDictionaryPrefUpdate::RecordPath,
+                          base::Unretained(this)),
       static_cast<base::DictionaryValue*>(
           service_->GetMutableUserPref(path_, base::Value::Type::DICTIONARY)),
       std::vector<std::string>());
diff --git a/services/preferences/tracked/pref_hash_filter.cc b/services/preferences/tracked/pref_hash_filter.cc
index c3ce65e8..5bcda230 100644
--- a/services/preferences/tracked/pref_hash_filter.cc
+++ b/services/preferences/tracked/pref_hash_filter.cc
@@ -314,8 +314,8 @@
 PrefFilter::OnWriteCallbackPair PrefHashFilter::GetOnWriteSynchronousCallbacks(
     base::DictionaryValue* pref_store_contents) {
   if (changed_paths_.empty() || !external_validation_hash_store_pair_) {
-    return std::make_pair(base::Closure(),
-                          base::Callback<void(bool success)>());
+    return std::make_pair(base::OnceClosure(),
+                          base::OnceCallback<void(bool success)>());
   }
 
   std::unique_ptr<base::DictionaryValue> changed_paths_macs =
@@ -362,8 +362,8 @@
   base::DictionaryValue* raw_changed_paths_macs = changed_paths_macs.get();
 
   return std::make_pair(
-      base::Bind(&ClearFromExternalStore, base::Unretained(raw_contents),
-                 base::Unretained(raw_changed_paths_macs)),
-      base::Bind(&FlushToExternalStore, base::Passed(&hash_store_contents_copy),
-                 base::Passed(&changed_paths_macs)));
+      base::BindOnce(&ClearFromExternalStore, base::Unretained(raw_contents),
+                     base::Unretained(raw_changed_paths_macs)),
+      base::BindOnce(&FlushToExternalStore, std::move(hash_store_contents_copy),
+                     std::move(changed_paths_macs)));
 }
diff --git a/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc b/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc
index b989071..aa807d58 100644
--- a/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc
+++ b/services/preferences/tracked/registry_hash_store_contents_win_unittest.cc
@@ -193,9 +193,8 @@
   std::unique_ptr<RegistryHashStoreContentsWin> contents =
       std::make_unique<RegistryHashStoreContentsWin>(
           registry_path, kStoreKey, std::move(temp_scoped_dir_cleaner));
-  base::OnceClosure other_thread_closure =
-      base::BindOnce(&OffThreadTempScopedDirDestructor, registry_path,
-                     base::Passed(contents->MakeCopy()));
+  base::OnceClosure other_thread_closure = base::BindOnce(
+      &OffThreadTempScopedDirDestructor, registry_path, contents->MakeCopy());
 
   contents->SetMac(kAtomicPrefPath, kTestStringA);
   contents.reset();
diff --git a/services/preferences/tracked/tracked_persistent_pref_store_factory.cc b/services/preferences/tracked/tracked_persistent_pref_store_factory.cc
index d2b15fa..65052cc1 100644
--- a/services/preferences/tracked/tracked_persistent_pref_store_factory.cc
+++ b/services/preferences/tracked/tracked_persistent_pref_store_factory.cc
@@ -133,12 +133,14 @@
 
   SetupTrackedPreferencesMigration(
       unprotected_pref_names, protected_pref_names,
-      base::Bind(&RemoveValueSilently, unprotected_pref_store->AsWeakPtr()),
-      base::Bind(&RemoveValueSilently, protected_pref_store->AsWeakPtr()),
-      base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply,
-                 unprotected_pref_store->AsWeakPtr()),
-      base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply,
-                 protected_pref_store->AsWeakPtr()),
+      base::BindRepeating(&RemoveValueSilently,
+                          unprotected_pref_store->AsWeakPtr()),
+      base::BindRepeating(&RemoveValueSilently,
+                          protected_pref_store->AsWeakPtr()),
+      base::BindRepeating(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply,
+                          unprotected_pref_store->AsWeakPtr()),
+      base::BindRepeating(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply,
+                          protected_pref_store->AsWeakPtr()),
       CreatePrefHashStore(*config, false), CreatePrefHashStore(*config, true),
       raw_unprotected_pref_hash_filter, raw_protected_pref_hash_filter);
 
diff --git a/services/preferences/tracked/tracked_preferences_migration.cc b/services/preferences/tracked/tracked_preferences_migration.cc
index 32a3bd3..70c6b43 100644
--- a/services/preferences/tracked/tracked_preferences_migration.cc
+++ b/services/preferences/tracked/tracked_preferences_migration.cc
@@ -28,13 +28,13 @@
   TrackedPreferencesMigrator(
       const std::set<std::string>& unprotected_pref_names,
       const std::set<std::string>& protected_pref_names,
-      const base::Callback<void(const std::string& key)>&
+      const base::RepeatingCallback<void(const std::string& key)>&
           unprotected_store_cleaner,
-      const base::Callback<void(const std::string& key)>&
+      const base::RepeatingCallback<void(const std::string& key)>&
           protected_store_cleaner,
-      const base::Callback<void(base::OnceClosure)>&
+      const base::RepeatingCallback<void(base::OnceClosure)>&
           register_on_successful_unprotected_store_write_callback,
-      const base::Callback<void(base::OnceClosure)>&
+      const base::RepeatingCallback<void(base::OnceClosure)>&
           register_on_successful_protected_store_write_callback,
       std::unique_ptr<PrefHashStore> unprotected_pref_hash_store,
       std::unique_ptr<PrefHashStore> protected_pref_hash_store,
@@ -61,11 +61,13 @@
   const std::set<std::string> unprotected_pref_names_;
   const std::set<std::string> protected_pref_names_;
 
-  const base::Callback<void(const std::string& key)> unprotected_store_cleaner_;
-  const base::Callback<void(const std::string& key)> protected_store_cleaner_;
-  const base::Callback<void(base::OnceClosure)>
+  const base::RepeatingCallback<void(const std::string& key)>
+      unprotected_store_cleaner_;
+  const base::RepeatingCallback<void(const std::string& key)>
+      protected_store_cleaner_;
+  const base::RepeatingCallback<void(base::OnceClosure)>
       register_on_successful_unprotected_store_write_callback_;
-  const base::Callback<void(base::OnceClosure)>
+  const base::RepeatingCallback<void(base::OnceClosure)>
       register_on_successful_protected_store_write_callback_;
 
   InterceptablePrefFilter::FinalizeFilterOnLoadCallback
@@ -84,7 +86,7 @@
 
 // Invokes |store_cleaner| for every |keys_to_clean|.
 void CleanupPrefStore(
-    const base::Callback<void(const std::string& key)>& store_cleaner,
+    const base::RepeatingCallback<void(const std::string& key)>& store_cleaner,
     const std::set<std::string>& keys_to_clean) {
   for (std::set<std::string>::const_iterator it = keys_to_clean.begin();
        it != keys_to_clean.end(); ++it) {
@@ -98,15 +100,16 @@
 // once the destination pref store they were migrated to was successfully
 // written to disk. Otherwise, executes the cleanup right away.
 void ScheduleSourcePrefStoreCleanup(
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_destination_store_write_callback,
-    const base::Callback<void(const std::string& key)>& source_store_cleaner,
+    const base::RepeatingCallback<void(const std::string& key)>&
+        source_store_cleaner,
     const std::set<std::string>& keys_to_clean,
     bool wait_for_commit_to_destination_store) {
   DCHECK(!keys_to_clean.empty());
   if (wait_for_commit_to_destination_store) {
     register_on_successful_destination_store_write_callback.Run(
-        base::Bind(&CleanupPrefStore, source_store_cleaner, keys_to_clean));
+        base::BindOnce(&CleanupPrefStore, source_store_cleaner, keys_to_clean));
   } else {
     CleanupPrefStore(source_store_cleaner, keys_to_clean);
   }
@@ -194,12 +197,13 @@
 TrackedPreferencesMigrator::TrackedPreferencesMigrator(
     const std::set<std::string>& unprotected_pref_names,
     const std::set<std::string>& protected_pref_names,
-    const base::Callback<void(const std::string& key)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
         unprotected_store_cleaner,
-    const base::Callback<void(const std::string& key)>& protected_store_cleaner,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
+        protected_store_cleaner,
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_unprotected_store_write_callback,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_protected_store_write_callback,
     std::unique_ptr<PrefHashStore> unprotected_pref_hash_store,
     std::unique_ptr<PrefHashStore> protected_pref_hash_store,
@@ -302,12 +306,13 @@
 void SetupTrackedPreferencesMigration(
     const std::set<std::string>& unprotected_pref_names,
     const std::set<std::string>& protected_pref_names,
-    const base::Callback<void(const std::string& key)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
         unprotected_store_cleaner,
-    const base::Callback<void(const std::string& key)>& protected_store_cleaner,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
+        protected_store_cleaner,
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_unprotected_store_write_callback,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_protected_store_write_callback,
     std::unique_ptr<PrefHashStore> unprotected_pref_hash_store,
     std::unique_ptr<PrefHashStore> protected_pref_hash_store,
diff --git a/services/preferences/tracked/tracked_preferences_migration.h b/services/preferences/tracked/tracked_preferences_migration.h
index 24f9c72..77e16d6 100644
--- a/services/preferences/tracked/tracked_preferences_migration.h
+++ b/services/preferences/tracked/tracked_preferences_migration.h
@@ -30,12 +30,13 @@
 void SetupTrackedPreferencesMigration(
     const std::set<std::string>& unprotected_pref_names,
     const std::set<std::string>& protected_pref_names,
-    const base::Callback<void(const std::string& key)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
         unprotected_store_cleaner,
-    const base::Callback<void(const std::string& key)>& protected_store_cleaner,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(const std::string& key)>&
+        protected_store_cleaner,
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_unprotected_store_write_callback,
-    const base::Callback<void(base::OnceClosure)>&
+    const base::RepeatingCallback<void(base::OnceClosure)>&
         register_on_successful_protected_store_write_callback,
     std::unique_ptr<PrefHashStore> unprotected_pref_hash_store,
     std::unique_ptr<PrefHashStore> protected_pref_hash_store,
diff --git a/services/preferences/tracked/tracked_preferences_migration_unittest.cc b/services/preferences/tracked/tracked_preferences_migration_unittest.cc
index 87500d7..8530289 100644
--- a/services/preferences/tracked/tracked_preferences_migration_unittest.cc
+++ b/services/preferences/tracked/tracked_preferences_migration_unittest.cc
@@ -49,8 +49,8 @@
   OnWriteCallbackPair FilterSerializeData(
       base::DictionaryValue* pref_store_contents) override {
     ADD_FAILURE();
-    return std::make_pair(base::Closure(),
-                          base::Callback<void(bool success)>());
+    return std::make_pair(base::OnceClosure(),
+                          base::OnceCallback<void(bool success)>());
   }
 
  private:
@@ -106,14 +106,16 @@
 
     SetupTrackedPreferencesMigration(
         unprotected_pref_names, protected_pref_names,
-        base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
-                   base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
-        base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
-                   base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
-        base::Bind(
+        base::BindRepeating(
+            &TrackedPreferencesMigrationTest::RemovePathFromStore,
+            base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
+        base::BindRepeating(
+            &TrackedPreferencesMigrationTest::RemovePathFromStore,
+            base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
+        base::BindRepeating(
             &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
             base::Unretained(this), MOCK_UNPROTECTED_PREF_STORE),
-        base::Bind(
+        base::BindRepeating(
             &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
             base::Unretained(this), MOCK_PROTECTED_PREF_STORE),
         std::unique_ptr<PrefHashStore>(
diff --git a/services/proxy_resolver/proxy_resolver_v8_tracing_unittest.cc b/services/proxy_resolver/proxy_resolver_v8_tracing_unittest.cc
index dc8e346..e5e257b 100644
--- a/services/proxy_resolver/proxy_resolver_v8_tracing_unittest.cc
+++ b/services/proxy_resolver/proxy_resolver_v8_tracing_unittest.cc
@@ -87,7 +87,7 @@
     waiter_.NotifyEvent(EVENT_ERROR);
     errors_.push_back(std::make_pair(line_number, base::UTF16ToASCII(error)));
     if (!error_callback_.is_null())
-      error_callback_.Run();
+      std::move(error_callback_).Run();
   }
 
   ProxyHostResolver* host_resolver() { return host_resolver_; }
@@ -96,8 +96,8 @@
 
   std::vector<std::pair<int, std::string>> GetErrors() { return errors_; }
 
-  void RunOnError(const base::Closure& callback) {
-    error_callback_ = callback;
+  void RunOnError(base::OnceClosure callback) {
+    error_callback_ = std::move(callback);
     waiter_.WaitForEvent(EVENT_ERROR);
   }
 
@@ -143,7 +143,7 @@
   std::vector<std::string> alerts_;
   std::vector<std::pair<int, std::string>> errors_;
   ProxyHostResolver* const host_resolver_;
-  base::Closure error_callback_;
+  base::OnceClosure error_callback_;
   net::EventWaiter<Event> waiter_;
 };
 
@@ -672,8 +672,8 @@
   // Cancel the first request, while it is running its completion task on
   // the origin thread. Reset deletes Request opject which cancels the request.
   mock_bindings.RunOnError(
-      base::Bind(&std::unique_ptr<net::ProxyResolver::Request>::reset,
-                 base::Unretained(&request1), nullptr));
+      base::BindOnce(&std::unique_ptr<net::ProxyResolver::Request>::reset,
+                     base::Unretained(&request1), nullptr));
 
   // Start another request, to make sure it is able to complete.
   resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
diff --git a/storage/browser/blob/blob_impl.cc b/storage/browser/blob/blob_impl.cc
index 2c5a34ef..f52eb8ac 100644
--- a/storage/browser/blob/blob_impl.cc
+++ b/storage/browser/blob/blob_impl.cc
@@ -88,6 +88,11 @@
       ->weak_ptr_factory_.GetWeakPtr();
 }
 
+void BlobImpl::UpdateHandle(std::unique_ptr<BlobDataHandle> new_handle) {
+  DCHECK_EQ(handle_->uuid(), new_handle->uuid());
+  handle_ = std::move(new_handle);
+}
+
 void BlobImpl::Clone(mojo::PendingReceiver<blink::mojom::Blob> receiver) {
   receivers_.Add(this, std::move(receiver));
 }
diff --git a/storage/browser/blob/blob_impl.h b/storage/browser/blob/blob_impl.h
index c000624..8243c0e 100644
--- a/storage/browser/blob/blob_impl.h
+++ b/storage/browser/blob/blob_impl.h
@@ -24,6 +24,12 @@
       std::unique_ptr<BlobDataHandle> handle,
       mojo::PendingReceiver<blink::mojom::Blob> receiver);
 
+  // Can be used to update the BlobDataHandle this BlobImpl refers to, for
+  // example to update it from one that doesn't have a valid size (when the
+  // BlobImpl was created) to one that has a valid size (after construction of
+  // the blob has completed). Both handles have to refer to the same blob.
+  void UpdateHandle(std::unique_ptr<BlobDataHandle> new_handle);
+
   // blink::mojom::Blob:
   void Clone(mojo::PendingReceiver<blink::mojom::Blob> receiver) override;
   void AsDataPipeGetter(
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc
index 1cc34f91..d08c28d 100644
--- a/storage/browser/blob/blob_registry_impl.cc
+++ b/storage/browser/blob/blob_registry_impl.cc
@@ -50,7 +50,7 @@
   // referenced by this new blob. This (and any further methods) could end up
   // deleting |this| by removing it from the blobs_under_construction_
   // collection in the blob service.
-  void StartTransportation();
+  void StartTransportation(base::WeakPtr<BlobImpl> blob_impl);
 
   ~BlobUnderConstruction() = default;
 
@@ -179,6 +179,9 @@
   // UUID of the blob being built.
   std::string uuid_;
 
+  // BlobImpl representing the blob being built.
+  base::WeakPtr<BlobImpl> blob_impl_;
+
   // BlobDataBuilder for the blob under construction. Is created in the
   // constructor, but not filled until all referenced blob UUIDs have been
   // resolved.
@@ -208,12 +211,15 @@
   DISALLOW_COPY_AND_ASSIGN(BlobUnderConstruction);
 };
 
-void BlobRegistryImpl::BlobUnderConstruction::StartTransportation() {
+void BlobRegistryImpl::BlobUnderConstruction::StartTransportation(
+    base::WeakPtr<BlobImpl> blob_impl) {
   if (!context()) {
     MarkAsFinishedAndDeleteSelf();
     return;
   }
 
+  blob_impl_ = std::move(blob_impl);
+
   size_t blob_count = 0;
   for (auto& entry : elements_) {
     const auto& element = entry.element;
@@ -391,21 +397,26 @@
       base::BindRepeating(&BlobUnderConstruction::OnReadyForTransport,
                           weak_ptr_factory_.GetWeakPtr());
 
+  auto blob_impl = std::move(blob_impl_);
+
   // OnReadyForTransport can be called synchronously, which can call
   // MarkAsFinishedAndDeleteSelf synchronously, so don't access any members
   // after this call.
   std::unique_ptr<BlobDataHandle> new_handle =
       context()->BuildPreregisteredBlob(std::move(builder_), callback);
 
-  // TODO(mek): Update BlobImpl with new BlobDataHandle. Although handles
-  // only differ in their size() attribute, which is currently not used by
-  // BlobImpl.
+  bool is_being_built = new_handle->IsBeingBuilt();
+  auto blob_status = new_handle->GetBlobStatus();
 
-  // BuildPreregisteredBlob might or might not have called the callback if it
-  // finished synchronously, so call the callback directly. If it was already
-  // called |this| would have been deleted making calling the callback a no-op.
-  if (!new_handle->IsBeingBuilt()) {
-    callback.Run(new_handle->GetBlobStatus(),
+  if (blob_impl)
+    blob_impl->UpdateHandle(std::move(new_handle));
+
+  // BuildPreregisteredBlob might or might not have called the callback if
+  // it finished synchronously, so call the callback directly. If it was
+  // already called |this| would have been deleted making calling the
+  // callback a no-op.
+  if (!is_being_built) {
+    callback.Run(blob_status,
                  std::vector<BlobMemoryController::FileCreationInfo>());
   }
 }
@@ -548,9 +559,9 @@
       uuid, content_type, content_disposition,
       base::BindOnce(&BlobRegistryImpl::BlobBuildAborted,
                      weak_ptr_factory_.GetWeakPtr(), uuid));
-  BlobImpl::Create(std::move(handle), std::move(blob));
+  auto blob_impl = BlobImpl::Create(std::move(handle), std::move(blob));
 
-  blobs_under_construction_[uuid]->StartTransportation();
+  blobs_under_construction_[uuid]->StartTransportation(std::move(blob_impl));
 
   std::move(callback).Run();
 }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index f7f2e1b..9c74e1a 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -9147,6 +9147,10 @@
     ]
   },
   "android-code-coverage-native": {
+    "additional_compile_targets": [
+      "monochrome_static_initializers",
+      "weblayer_shell"
+    ],
     "gtest_tests": [
       {
         "args": [
@@ -9804,6 +9808,52 @@
             "--bucket",
             "chromium-result-details",
             "--test-name",
+            "chrome_java_test_pagecontroller_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "chrome_java_test_pagecontroller_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
             "crypto_unittests"
           ],
           "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
@@ -10816,6 +10866,144 @@
             "--bucket",
             "chromium-result-details",
             "--test-name",
+            "monochrome_public_bundle_fake_modules_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "monochrome_public_bundle_fake_modules_smoke_test"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "monochrome_public_bundle_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "monochrome_public_bundle_smoke_test"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "monochrome_public_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "monochrome_public_smoke_test"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
             "net_unittests"
           ],
           "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
@@ -11139,6 +11327,52 @@
             "--bucket",
             "chromium-result-details",
             "--test-name",
+            "system_webview_shell_layout_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "system_webview_shell_layout_test_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
             "ui_android_unittests"
           ],
           "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
@@ -11369,6 +11603,196 @@
             "--bucket",
             "chromium-result-details",
             "--test-name",
+            "weblayer_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "weblayer_browsertests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "weblayer_instrumentation_test_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_cts_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "chromium/android_webview/tools/cts_archive",
+              "location": "android_webview/tools/cts_archive",
+              "revision": "4kDr36wBuZtvbfaEin4U4oeFD7oAuN0flkWDImKBts4C"
+            },
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 3
+        },
+        "test": "webview_cts_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_ui_test_app_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "webview_ui_test_app_test_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
             "wtf_unittests"
           ],
           "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
@@ -11404,6 +11828,102 @@
         },
         "test": "wtf_unittests"
       }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--gtest-benchmark-name=components_perftests"
+        ],
+        "isolate_coverage_data": true,
+        "isolate_name": "components_perftests",
+        "merge": {
+          "args": [
+            "--smoke-test-mode"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "components_perftests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "--platform=android"
+        ],
+        "isolate_coverage_data": true,
+        "isolate_name": "content_shell_crash_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "content_shell_crash_test",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "isolate_coverage_data": true,
+        "isolate_name": "monochrome_apk_checker",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "monochrome_apk_checker",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "isolate_coverage_data": true,
+        "isolate_name": "telemetry_perf_unittests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "telemetry_perf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "PQ3A.190801.002",
+              "device_os_flavor": "google",
+              "device_os_type": "userdebug",
+              "device_type": "walleye",
+              "os": "Android"
+            }
+          ],
+          "idempotent": false,
+          "shards": 12
+        }
+      }
     ]
   },
   "android-mojo-webview-rel": {
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json
index f31a810..673890c 100644
--- a/testing/buildbot/chromium.gpu.json
+++ b/testing/buildbot/chromium.gpu.json
@@ -247,6 +247,32 @@
       },
       {
         "args": [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.mobile",
+          "--browser=android-chromium"
+        ],
+        "experiment_percentage": 25,
+        "isolate_name": "rendering_representative_perf_tests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "MMB29Q",
+              "device_os_type": "userdebug",
+              "device_type": "bullhead",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
           "screenshot_sync",
           "--show-stdout",
           "--browser=android-chromium",
@@ -1903,6 +1929,29 @@
       },
       {
         "args": [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.desktop"
+        ],
+        "experiment_percentage": 25,
+        "isolate_name": "rendering_representative_perf_tests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "mac-intel-stable"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
           "screenshot_sync",
           "--show-stdout",
           "--browser=release",
@@ -2741,6 +2790,31 @@
       },
       {
         "args": [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.desktop"
+        ],
+        "experiment_percentage": 25,
+        "isolate_name": "rendering_representative_perf_tests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "mac-amd-stable",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
           "screenshot_sync",
           "--show-stdout",
           "--browser=release",
@@ -3768,6 +3842,40 @@
       },
       {
         "args": [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.desktop",
+          "--browser=release_x64"
+        ],
+        "experiment_percentage": 25,
+        "isolate_name": "rendering_representative_perf_tests",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "rendering_representative_perf_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-trigger-configs",
+            "[{\"gpu\": \"nvidia-quadro-p400-win10-stable\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
+        }
+      },
+      {
+        "args": [
           "screenshot_sync",
           "--show-stdout",
           "--browser=release_x64",
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index f127e45..f10d9d4 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -5610,13 +5610,11 @@
   },
   "fuchsia-arm64-cast": {
     "additional_compile_targets": [
-      "cast_shell",
       "cast_test_lists"
     ]
   },
   "fuchsia-x64-cast": {
     "additional_compile_targets": [
-      "cast_shell",
       "cast_test_lists"
     ]
   },
diff --git a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
index 82a612c..ddd3926 100644
--- a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
+++ b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
@@ -170,70 +170,6 @@
 -PlatformAppWithFileBrowserTest.*
 -PluginPowerSaverBrowserTest.*
 -PolicyTest.*
--PrefsFunctionalTest.*
--PrefsTabHelperBrowserTest.*
--PrerenderBrowserTest.*
--PresentationReceiverWindowViewBrowserTest.*
--PrintBrowserTest.*
--PrintPreviewDialogControllerBrowserTest.*
--PrintPreviewSettingsSectionsTest.*
--PrintPreviewUIBrowserTest.*
--ProcessManagerBrowserTest.*
--ProfileMainNetworkContext/NetworkContextConfigurationBrowserTest.*
--ProfileMenuViewExtensionsTest.*
--ProfileSigninConfirmationHelperBrowserTest.*
--PushMessagingBrowserTest.*
--RedirectTest.*
--ReferrerPolicyTest.*
--SBNavigationObserverBrowserTest.*
--SRC_ExternalClearKey/EncryptedMediaTest.*
--SSLUIMITMSoftwareEnabledTest.*
--SSLUITest.*
--SSLUITestWithExtendedReporting.*
--SSLUIWorkerFetchTest.*
--SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting/SafeBrowsingBlockingPageBrowserTest.*
--SafeBrowsingNetworkContext/NetworkContextConfigurationBrowserTest.*
--SafeBrowsingServiceJsRequestNoInterstitialTest.*
--SafeBrowsingServiceTest.*
--SaveCardBubbleViewsFullFormBrowserTest.*
--SavePageBrowserTest.*
--SaveType/SavePageOriginalVsSavedComparisonTest.*
--SearchEngineTabHelperBrowserTest.*
--SecurityStateTabHelperTest.*
--ServiceWorkerTestWithJSBindings/ServiceWorkerTest.*
--ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.*
--SessionRestorePageLoadMetricsBrowserTest.*
--SessionRestoreTest.*
--SettingsA11yPasswords.*
--SettingsA11ySignOut.*
--SettingsAccessibilityTest.*
--StartupBrowserCreatorFirstRunTest.*
--SubresourceFilterBrowserTest.*
--SubresourceFilterPopupBrowserTest.*
--SuperfishSSLUITest.*
--SyncFileSystemApiTest.*
--SystemNetworkContext/NetworkContextConfigurationBrowserTest.*
--TabManagerTestWithTwoTabs.*
--TabRestoreTest.*
--TaskManagerBrowserTest.*
--TestStatsDictionaryTest.*
--ThreatDOMDetailsTest.*
--TranslateHelperBrowserTest.*
--TranslateScriptBrowserTest.*
--UkmBrowserTest.*
--UnloadTest.*
--UpdateRecommendedDialogTest.*
--UsbChooserBrowserTest.*
--ViewSourceTest.*
--WebNavigationApiTest.*
--WebRtcBrowserTest.*
--WebUIBrowserAsyncGenTest.*
--WebUIBrowserAsyncTest.*
--WebUIResourceBrowserTest.*
--WebViewTest.*
--WebrtcLoggingPrivateApiTest.*
--WindowAppleScriptTest.*
--WindowOpenApiTest.*
 
 # Potential 10.13 killers.
 -DisableExtensionsExceptBrowserTest.*
@@ -244,24 +180,3 @@
 -PasswordManagerBrowserTest.*
 -PictureInPictureWindowControllerBrowserTest.*
 -UpdateServiceTest.*
-
-# More potential 10.13 killers. All from shard 4 of browser_tests.
--BookmarkBubbleSignInDelegateTest.*
--BrowserWindowTouchBarControllerTest.*
--CloudPrintProxyPolicyStartupTest.*
--ExtensionUninstallDialogViewBrowserTest.*
--IdentityGetProfileUserInfoFunctionTest.*
--MediaRouterDialogControllerWebUIBrowserTest.*
--MediaRouterWebUIBrowserTest.*
--PaymentMethodViewControllerTest.*
--PaymentRequestCanMakePaymentQueryTest.*
--PaymentRequestCompleteSuggestionsForEverythingTest.*
--PaymentRequestOrderSummaryViewControllerTest.*
--PaymentRequestPaymentResponseShippingAddressTest.*
--PaymentRequestWebContentsManagerTest.*
--PermissionsApiTest.*
--PrintPreviewBaseSettingsSectionTest.*
--PrintPreviewDestinationItemTest.*
--ProfileListDesktopBrowserTest.*
--SubresourceFilterWebSocketBrowserTest.*
--TabCaptureApiTest.*
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py
index aa51191..fffa6aa3 100755
--- a/testing/buildbot/generate_buildbot_json.py
+++ b/testing/buildbot/generate_buildbot_json.py
@@ -793,27 +793,27 @@
         raise BBGenErr('%s names may not duplicate basic test suite names '
                        '(error found while processsing %s)'
                        % (test_type, suite))
-      seen_tests = {}
+      seen_tests = {}  # Maps a test to a test definition.
       for sub_suite in suite_def:
         if sub_suite in other_test_suites or sub_suite in target_test_suites:
           raise BBGenErr('%s may not refer to other composition type test '
                          'suites (error found while processing %s)'
                          % (test_type, suite))
-        elif sub_suite not in basic_suites:
+        if sub_suite not in basic_suites:
           raise BBGenErr('Unable to find reference to %s while processing %s'
                          % (sub_suite, suite))
-        else:
-          # test name -> basic_suite that it came from
-          basic_tests = {k: sub_suite for k in basic_suites[sub_suite]}
-          for test_name, test_suite in basic_tests.iteritems():
-            if (test_name in seen_tests and
-                basic_suites[test_suite][test_name] !=
-                basic_suites[seen_tests[test_name]][test_name]):
-              raise BBGenErr('Conflicting test definitions for %s from %s '
-                             'and %s in %s (error found while processing %s)'
-                             % (test_name, seen_tests[test_name], test_suite,
-                             test_type, suite))
-          seen_tests.update(basic_tests)
+
+        # Ensure that if a test is reachable via multiple basic suites,
+        # all of them have an identical definition of the test.
+        for test_name in basic_suites[sub_suite]:
+          if (test_name in seen_tests and
+              basic_suites[sub_suite][test_name] !=
+              basic_suites[seen_tests[test_name]][test_name]):
+            raise BBGenErr('Conflicting test definitions for %s from %s '
+                           'and %s in %s (error found while processing %s)'
+                           % (test_name, seen_tests[test_name], sub_suite,
+                           test_type, suite))
+          seen_tests[test_name] = sub_suite
 
   def flatten_test_suites(self):
     new_test_suites = {}
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 55d6054..3fffc26 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1525,6 +1525,11 @@
           '--browser=release_x64',
         ],
       },
+      'Win10 x64 Release (NVIDIA)': {
+        'args': [
+          '--browser=release_x64',
+        ],
+      },
     },
   },
   'sandbox_linux_unittests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 0de8c2e..fe3fd21 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -473,7 +473,7 @@
       'jingle_unittests': {},
       'latency_unittests': {},
       'libcups_unittests': {
-	'experiment_percentage': 100,
+        'experiment_percentage': 100,
       },
       'media_unittests': {
         'args': [
@@ -4714,6 +4714,18 @@
       }
     },
 
+    'rendering_desktop_representative_perf_tests_isolated_scripts_experimental': {
+      'rendering_representative_perf_tests': {
+        'isolate_name': 'rendering_representative_perf_tests',
+        'args': [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.desktop",
+        ],
+        'swarming': {},
+        'experiment_percentage': 25,
+      }
+    },
+
     'rendering_mobile_representative_perf_tests_isolated_scripts': {
       'rendering_representative_perf_tests': {
         'isolate_name': 'rendering_representative_perf_tests',
@@ -4726,6 +4738,19 @@
       }
     },
 
+    'rendering_mobile_representative_perf_tests_isolated_scripts_experimental': {
+      'rendering_representative_perf_tests': {
+        'isolate_name': 'rendering_representative_perf_tests',
+        'args': [
+          "../../tools/perf/run_benchmark",
+          "--benchmarks=rendering.mobile",
+          "--browser=android-chromium"
+        ],
+        'swarming': {},
+        'experiment_percentage': 25,
+      }
+    },
+
     'site_isolation_android_fyi_gtests': {
       'site_per_process_components_browsertests': {
         'args': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index b9fedb6..6ba58b9 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -1641,9 +1641,15 @@
           'pie_fleet',
           'walleye',
         ],
+        'additional_compile_targets': [
+          'monochrome_static_initializers',
+          'weblayer_shell',
+        ],
         'test_suites': {
-          'gtest_tests': 'chromium_android_gtests',
+          'gtest_tests': 'android_pie_rel_gtests',
+          'isolated_scripts': 'marshmallow_pie_isolated_scripts_with_proguard',
         },
+        'use_swarming': True,
         'os_type': 'android',
       },
       'android-mojo-webview-rel': {
@@ -2272,6 +2278,7 @@
         ],
         'test_suites': {
           'gpu_telemetry_tests': 'gpu_common_telemetry_tests',
+          'isolated_scripts': 'rendering_mobile_representative_perf_tests_isolated_scripts_experimental',
         },
       },
       'GPU Linux Builder': {},
@@ -2320,6 +2327,7 @@
         'test_suites': {
           'gtest_tests': 'gpu_desktop_gtests',
           'gpu_telemetry_tests': 'gpu_common_telemetry_tests',
+          'isolated_scripts': 'rendering_desktop_representative_perf_tests_isolated_scripts_experimental',
         },
       },
       'Mac Retina Debug (AMD)': {
@@ -2342,6 +2350,7 @@
         'test_suites': {
           'gtest_tests': 'gpu_desktop_gtests',
           'gpu_telemetry_tests': 'gpu_common_telemetry_tests',
+          'isolated_scripts': 'rendering_desktop_representative_perf_tests_isolated_scripts_experimental',
         },
       },
       'Win10 x64 Debug (NVIDIA)': {
@@ -2364,6 +2373,7 @@
         'test_suites': {
           'gtest_tests': 'gpu_win_gtests',
           'gpu_telemetry_tests': 'gpu_common_win_and_linux_telemetry_tests',
+          'isolated_scripts': 'rendering_desktop_representative_perf_tests_isolated_scripts_experimental',
         },
         # We keep this value enabled to provide minimal regression testing.
         'use_multi_dimension_trigger_script': True,
@@ -3509,13 +3519,11 @@
       },
       'fuchsia-arm64-cast': {
         'additional_compile_targets': [
-          'cast_shell',
           'cast_test_lists',
         ],
       },
       'fuchsia-x64-cast': {
         'additional_compile_targets': [
-          'cast_shell',
           'cast_test_lists',
         ],
         'args': [
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn
index 5ff1bb7..f34287e4 100644
--- a/testing/libfuzzer/fuzzers/BUILD.gn
+++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -454,3 +454,13 @@
     "//third_party/libprotobuf-mutator",
   ]
 }
+
+fuzzer_test("libyuv_scale_fuzzer") {
+  sources = [
+    "libyuv_scale_fuzzer.cc",
+  ]
+
+  deps = [
+    "//third_party/libyuv",
+  ]
+}
diff --git a/testing/libfuzzer/fuzzers/libyuv_scale_fuzzer.cc b/testing/libfuzzer/fuzzers/libyuv_scale_fuzzer.cc
new file mode 100644
index 0000000..057086b
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/libyuv_scale_fuzzer.cc
@@ -0,0 +1,157 @@
+// 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 <fuzzer/FuzzedDataProvider.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <random>
+
+#include "third_party/libyuv/include/libyuv.h"
+
+void FillBufferWithRandomData(uint8_t* dst, size_t len, std::minstd_rand0 rng) {
+  size_t i;
+  for (i = 0; i + 3 < len; i += 4) {
+    *reinterpret_cast<uint32_t*>(dst) = rng();
+    dst += 4;
+  }
+  for (; i < len; ++i) {
+    *dst++ = rng();
+  }
+}
+
+static void Scale(bool is420,
+                  int src_width,
+                  int src_height,
+                  int dst_width,
+                  int dst_height,
+                  int filter_num,
+                  std::string seed_str) {
+  int src_width_uv, src_height_uv;
+  if (is420) {
+    src_width_uv = (std::abs(src_width) + 1) >> 1;
+    src_height_uv = (std::abs(src_height) + 1) >> 1;
+  } else {
+    src_width_uv = (std::abs(src_width));
+    src_height_uv = (std::abs(src_height));
+  }
+
+  size_t src_y_plane_size = (std::abs(src_width)) * (std::abs(src_height));
+  size_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
+
+  int src_stride_y = std::abs(src_width);
+  int src_stride_uv = src_width_uv;
+
+  uint8_t* src_y = reinterpret_cast<uint8_t*>(malloc(src_y_plane_size));
+  uint8_t* src_u = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
+  uint8_t* src_v = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
+
+  uint16_t* p_src_y_16 =
+      reinterpret_cast<uint16_t*>(malloc(src_y_plane_size * 2));
+  uint16_t* p_src_u_16 =
+      reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
+  uint16_t* p_src_v_16 =
+      reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
+
+  std::seed_seq seed(seed_str.begin(), seed_str.end());
+  std::minstd_rand0 rng(seed);
+
+  FillBufferWithRandomData(src_y, src_y_plane_size, rng);
+  FillBufferWithRandomData(src_u, src_uv_plane_size, rng);
+  FillBufferWithRandomData(src_v, src_uv_plane_size, rng);
+
+  for (size_t i = 0; i < src_y_plane_size; ++i) {
+    p_src_y_16[i] = src_y[i];
+  }
+  for (size_t i = 0; i < src_uv_plane_size; ++i) {
+    p_src_u_16[i] = src_u[i];
+    p_src_v_16[i] = src_v[i];
+  }
+
+  int dst_width_uv, dst_height_uv;
+  if (is420) {
+    dst_width_uv = (dst_width + 1) >> 1;
+    dst_height_uv = (dst_height + 1) >> 1;
+  } else {
+    dst_width_uv = dst_width;
+    dst_height_uv = dst_height;
+  }
+
+  size_t dst_y_plane_size = (dst_width) * (dst_height);
+  size_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
+
+  int dst_stride_y = dst_width;
+  int dst_stride_uv = dst_width_uv;
+
+  uint8_t* dst_y_c = reinterpret_cast<uint8_t*>(malloc(dst_y_plane_size));
+  uint8_t* dst_u_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
+  uint8_t* dst_v_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
+
+  uint16_t* p_dst_y_16 =
+      reinterpret_cast<uint16_t*>(malloc(dst_y_plane_size * 2));
+  uint16_t* p_dst_u_16 =
+      reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
+  uint16_t* p_dst_v_16 =
+      reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
+
+  if (is420) {
+    I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
+              src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
+              dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
+              static_cast<libyuv::FilterMode>(filter_num));
+
+    I420Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
+                 p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
+                 dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
+                 dst_stride_uv, dst_width, dst_height,
+                 static_cast<libyuv::FilterMode>(filter_num));
+  } else {
+    I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
+              src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
+              dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
+              static_cast<libyuv::FilterMode>(filter_num));
+
+    I444Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
+                 p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
+                 dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
+                 dst_stride_uv, dst_width, dst_height,
+                 static_cast<libyuv::FilterMode>(filter_num));
+  }
+
+  free(src_y);
+  free(src_u);
+  free(src_v);
+
+  free(p_src_y_16);
+  free(p_src_u_16);
+  free(p_src_v_16);
+
+  free(dst_y_c);
+  free(dst_u_c);
+  free(dst_v_c);
+
+  free(p_dst_y_16);
+  free(p_dst_u_16);
+  free(p_dst_v_16);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+
+  // Limit width and height for performance.
+  int src_width = provider.ConsumeIntegralInRange<int>(1, 256);
+  int src_height = provider.ConsumeIntegralInRange<int>(1, 256);
+
+  int filter_num =
+      provider.ConsumeIntegralInRange<int>(0, libyuv::FilterMode::kFilterBox);
+
+  int dst_width = provider.ConsumeIntegralInRange<int>(1, 256);
+  int dst_height = provider.ConsumeIntegralInRange<int>(1, 256);
+
+  std::string seed = provider.ConsumeRemainingBytesAsString();
+
+  Scale(true, src_width, src_height, dst_width, dst_height, filter_num, seed);
+  Scale(false, src_width, src_height, dst_width, dst_height, filter_num, seed);
+
+  return 0;
+}
diff --git a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
index bb2bd55..1d03011 100644
--- a/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
+++ b/testing/scripts/representative_perf_test_data/representatives_frame_times_upper_limit.json
@@ -1,156 +1,156 @@
 {
   "win": {
     "canvas_to_blob": {
-      "ci_095": 10.93,
-      "avg": 30.145
+      "ci_095": 10.269,
+      "avg": 29.744
     },
     "filter_terrain_svg": {
-      "ci_095": 0.307,
-      "avg": 30.065
+      "ci_095": 0.322,
+      "avg": 32.201
     },
     "web_animation_value_type_transform_complex": {
-      "ci_095": 1.574,
-      "avg": 48.422
+      "ci_095": 1.601,
+      "avg": 49.073
     },
     "runway_2019": {
-      "ci_095": 14.407,
-      "avg": 22.487
+      "ci_095": 7.487,
+      "avg": 19.62
     },
     "css_transitions_inline_style": {
-      "ci_095": 3.976,
-      "avg": 19.575
+      "ci_095": 3.907,
+      "avg": 19.523
+    },
+    "many_planets_deep": {
+      "ci_095": 0.105,
+      "avg": 16.678
     },
     "aquarium_20k": {
-      "ci_095": 3.731,
-      "avg": 129.946
+      "ci_095": 3.218,
+      "avg": 130.822
     },
     "balls_css_transition_2_properties": {
-      "ci_095": 18.826,
-      "avg": 83.677
+      "ci_095": 14.949,
+      "avg": 78.445
     },
     "cc_poster_circle": {
-      "ci_095": 0.064,
+      "ci_095": 0.066,
       "avg": 16.678
     },
     "js_poster_circle": {
-      "ci_095": 0.108,
-      "avg": 16.678
+      "ci_095": 0.105,
+      "avg": 16.681
     },
     "web_animations_staggered_triggering_page": {
-      "ci_095": 0.457,
-      "avg": 16.832
+      "ci_095": 0.52,
+      "avg": 16.804
     },
     "aquarium": {
-      "ci_095": 0.231,
+      "ci_095": 0.199,
+      "avg": 16.688
+    },
+    "main_30fps_impl_60fps": {
+      "ci_095": 0.121,
       "avg": 16.689
     },
     "css_value_type_shadow": {
-      "ci_095": 0.964,
-      "avg": 48.34
+      "ci_095": 1.306,
+      "avg": 48.886
     },
     "nvidia_vertex_buffer_object": {
-      "ci_095": 3.354,
-      "avg": 17.637
-    },
-    "many_planets_deep": {
-      "ci_095": 0.127,
-      "avg": 16.678
-    },
-    "main_30fps_impl_60fps": {
-      "ci_095": 0.1,
-      "avg": 16.7
+      "ci_095": 3.421,
+      "avg": 17.499
     }
   },
   "mac": {
     "twitch_2018": {
-      "ci_095": 13.965,
-      "avg": 28.108
+      "ci_095": 11.704,
+      "avg": 25.831
     },
     "balls_javascript_canvas": {
-      "ci_095": 1.283,
-      "avg": 43.473
+      "ci_095": 1.339,
+      "avg": 41.412
     },
     "transform_transitions_js_block": {
-      "ci_095": 0.402,
-      "avg": 16.758
+      "ci_095": 0.373,
+      "avg": 16.755
     },
     "web_animations_staggered_infinite_iterations": {
-      "ci_095": 0.285,
-      "avg": 16.691
+      "ci_095": 0.356,
+      "avg": 16.694
     },
     "fill_shapes": {
-      "ci_095": 1.427,
-      "avg": 36.335
+      "ci_095": 1.251,
+      "avg": 35.028
     },
     "css_value_type_shadow": {
-      "ci_095": 15.473,
-      "avg": 66.584
+      "ci_095": 15.062,
+      "avg": 65.105
     },
     "animometer_webgl_attrib_arrays": {
-      "ci_095": 0.544,
-      "avg": 16.936
+      "ci_095": 0.518,
+      "avg": 17.062
     },
     "canvas_05000_pixels_per_second": {
-      "ci_095": 0.324,
+      "ci_095": 0.307,
       "avg": 16.684
     },
+    "main_30fps_impl_60fps": {
+      "ci_095": 0.185,
+      "avg": 16.695
+    },
     "ie_chalkboard": {
-      "ci_095": 41.361,
-      "avg": 66.231
+      "ci_095": 43.55,
+      "avg": 66.078
     },
     "new_tilings": {
-      "ci_095": 0.776,
-      "avg": 19.943
+      "ci_095": 0.498,
+      "avg": 18.318
     },
     "chip_tune": {
-      "ci_095": 0.42,
-      "avg": 16.732
-    },
-    "main_30fps_impl_60fps": {
-      "ci_095": 0.2,
-      "avg": 16.7
+      "ci_095": 0.405,
+      "avg": 16.729
     }
   },
   "android": {
     "text_10000_pixels_per_second": {
-      "ci_095": 0.653,
-      "avg": 16.812
+      "ci_095": 0.662,
+      "avg": 16.808
     },
     "balls_javascript_canvas": {
-      "ci_095": 22.183,
-      "avg": 219.386
+      "ci_095": 20.431,
+      "avg": 209.728
     },
     "transform_transitions_js_block": {
-      "ci_095": 0.059,
-      "avg": 16.647
+      "ci_095": 0.064,
+      "avg": 16.646
     },
     "web_animations_staggered_infinite_iterations": {
-      "ci_095": 8.037,
-      "avg": 67.986
+      "ci_095": 6.482,
+      "avg": 57.344
     },
     "motion_mark_canvas_fill_shapes": {
-      "ci_095": 74.393,
-      "avg": 240.943
+      "ci_095": 55.463,
+      "avg": 192.341
     },
     "css_value_type_shadow": {
-      "ci_095": 33.919,
-      "avg": 382.617
+      "ci_095": 37.334,
+      "avg": 307.036
     },
     "canvas_05000_pixels_per_second": {
-      "ci_095": 0.4,
-      "avg": 16.77
-    },
-    "new_tilings": {
-      "ci_095": 1.657,
-      "avg": 22.073
-    },
-    "extra_large_texture_uploads": {
-      "ci_095": 48.798,
-      "avg": 352.437
+      "ci_095": 0.596,
+      "avg": 16.857
     },
     "main_30fps_impl_60fps": {
-      "ci_095": 1.0,
-      "avg": 16.9
+      "ci_095": 0.603,
+      "avg": 18.009
+    },
+    "new_tilings": {
+      "ci_095": 1.008,
+      "avg": 19.393
+    },
+    "extra_large_texture_uploads": {
+      "ci_095": 35.637,
+      "avg": 272.377
     }
   }
 }
\ No newline at end of file
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index c30bcc0..53d7288 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1571,26 +1571,6 @@
             ]
         }
     ],
-    "ChromeStart": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "start_surface_variation": "tasksonly",
-                        "tab_switcher_on_return_time_ms": "3600000"
-                    },
-                    "enable_features": [
-                        "StartSurfaceAndroid",
-                        "TabSwitcherOnReturn"
-                    ]
-                }
-            ]
-        }
-    ],
     "ChromeSuggestionsTuningForceTopSites": [
         {
             "platforms": [
@@ -2708,6 +2688,27 @@
             ]
         }
     ],
+    "FriendlySettingsRedesignTest": [
+        {
+            "platforms": [
+                "windows",
+                "mac",
+                "chromeos",
+                "linux",
+                "android",
+                "android_webview",
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "FriendlySettingRedesign"
+                    ]
+                }
+            ]
+        }
+    ],
     "FuzzyAppSearch": [
         {
             "platforms": [
@@ -4506,26 +4507,6 @@
             ]
         }
     ],
-    "PasswordLeakDetection": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "linux",
-                "mac",
-                "windows",
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PasswordLeakDetection"
-                    ]
-                }
-            ]
-        }
-    ],
     "PasswordManagerStickyBubble": [
         {
             "platforms": [
@@ -5596,7 +5577,6 @@
     "SafeBrowsingRealTimeUrlLookupEnabled": [
         {
             "platforms": [
-                "android",
                 "chromeos",
                 "linux",
                 "mac",
@@ -5612,6 +5592,24 @@
             ]
         }
     ],
+    "SafeBrowsingRealTimeUrlLookupEnabledAndroid": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "SafeBrowsingRealTimeUrlLookupMemoryThresholdMb": "4096"
+                    },
+                    "enable_features": [
+                        "SafeBrowsingRealTimeUrlLookupEnabled"
+                    ]
+                }
+            ]
+        }
+    ],
     "SafeBrowsingScoutTransitionStudy": [
         {
             "platforms": [
@@ -7791,6 +7789,21 @@
             ]
         }
     ],
+    "WebViewWakeMetricsService": [
+        {
+            "platforms": [
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "WebViewWakeMetricsService"
+                    ]
+                }
+            ]
+        }
+    ],
     "ZippedSystemLogsUpload": [
         {
             "platforms": [
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index 82c2dba..6fa736f5 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -49,7 +49,6 @@
     "indexeddb/indexeddb_metadata.cc",
     "loader/mime_sniffing_throttle.cc",
     "loader/mime_sniffing_url_loader.cc",
-    "loader/request_destination.cc",
     "loader/throttling_url_loader.cc",
     "loader/throttling_url_loader.h",
     "loader/url_loader_factory_bundle.cc",
diff --git a/third_party/blink/common/feature_policy/document_policy.cc b/third_party/blink/common/feature_policy/document_policy.cc
index ec40330..cbbf56a 100644
--- a/third_party/blink/common/feature_policy/document_policy.cc
+++ b/third_party/blink/common/feature_policy/document_policy.cc
@@ -300,8 +300,6 @@
   UpdateFeatureState(defaults);
 }
 
-DocumentPolicy::~DocumentPolicy() = default;
-
 // static
 std::unique_ptr<DocumentPolicy> DocumentPolicy::CreateWithRequiredPolicy(
     const FeatureState& required_policy,
diff --git a/third_party/blink/common/feature_policy/policy_value.cc b/third_party/blink/common/feature_policy/policy_value.cc
index 9eb0926..d0cef54 100644
--- a/third_party/blink/common/feature_policy/policy_value.cc
+++ b/third_party/blink/common/feature_policy/policy_value.cc
@@ -10,8 +10,6 @@
 
 PolicyValue::PolicyValue() : type_(mojom::PolicyValueType::kNull) {}
 
-PolicyValue::~PolicyValue() = default;
-
 PolicyValue::PolicyValue(mojom::PolicyValueType type) : type_(type) {
   DCHECK_EQ(type, mojom::PolicyValueType::kNull);
 }
diff --git a/third_party/blink/common/loader/request_destination.cc b/third_party/blink/common/loader/request_destination.cc
deleted file mode 100644
index b0232e85..0000000
--- a/third_party/blink/common/loader/request_destination.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/public/common/loader/request_destination.h"
-
-namespace blink {
-
-const char* GetRequestDestinationFromContext(
-    mojom::RequestContextType context) {
-  switch (context) {
-    case mojom::RequestContextType::UNSPECIFIED:
-    case mojom::RequestContextType::BEACON:
-    case mojom::RequestContextType::DOWNLOAD:
-    case mojom::RequestContextType::EVENT_SOURCE:
-    case mojom::RequestContextType::FETCH:
-    case mojom::RequestContextType::PING:
-    case mojom::RequestContextType::XML_HTTP_REQUEST:
-    case mojom::RequestContextType::SUBRESOURCE:
-    case mojom::RequestContextType::PREFETCH:
-      return "";
-    case mojom::RequestContextType::CSP_REPORT:
-      return "report";
-    case mojom::RequestContextType::AUDIO:
-      return "audio";
-    case mojom::RequestContextType::EMBED:
-      return "embed";
-    case mojom::RequestContextType::FONT:
-      return "font";
-    case mojom::RequestContextType::FRAME:
-      return "frame";
-    case mojom::RequestContextType::IFRAME:
-      return "iframe";
-    case mojom::RequestContextType::HYPERLINK:
-    case mojom::RequestContextType::LOCATION:
-    case mojom::RequestContextType::FORM:
-      return "document";
-    case mojom::RequestContextType::IMAGE:
-    case mojom::RequestContextType::FAVICON:
-    case mojom::RequestContextType::IMAGE_SET:
-      return "image";
-    case mojom::RequestContextType::MANIFEST:
-      return "manifest";
-    case mojom::RequestContextType::OBJECT:
-      return "object";
-    case mojom::RequestContextType::SCRIPT:
-      return "script";
-    case mojom::RequestContextType::SERVICE_WORKER:
-      return "serviceworker";
-    case mojom::RequestContextType::SHARED_WORKER:
-      return "sharedworker";
-    case mojom::RequestContextType::STYLE:
-      return "style";
-    case mojom::RequestContextType::TRACK:
-      return "track";
-    case mojom::RequestContextType::VIDEO:
-      return "video";
-    case mojom::RequestContextType::WORKER:
-      return "worker";
-    case mojom::RequestContextType::XSLT:
-      return "xslt";
-    case mojom::RequestContextType::IMPORT:
-    case mojom::RequestContextType::INTERNAL:
-      return "unknown";
-
-    // TODO(mkwst): We don't currently distinguish between plugin content loaded
-    // via `<embed>` or `<object>` as https://github.com/whatwg/fetch/pull/948
-    // asks us to do. See `content::PepperURLLoaderHost::InternalOnHostMsgOpen`
-    // for details.
-    case mojom::RequestContextType::PLUGIN:
-      return "embed";
-  }
-  NOTREACHED();
-  return "";
-}
-
-}  // namespace blink
diff --git a/third_party/blink/common/loader/throttling_url_loader.cc b/third_party/blink/common/loader/throttling_url_loader.cc
index 5c436a6a..c7b0b02 100644
--- a/third_party/blink/common/loader/throttling_url_loader.cc
+++ b/third_party/blink/common/loader/throttling_url_loader.cc
@@ -201,8 +201,6 @@
     int32_t in_intra_priority_value)
     : priority(in_priority), intra_priority_value(in_intra_priority_value) {}
 
-ThrottlingURLLoader::PriorityInfo::~PriorityInfo() = default;
-
 // static
 std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart(
     scoped_refptr<network::SharedURLLoaderFactory> factory,
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index 4356cb7..bfb9f22 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -84,7 +84,6 @@
     "loader/loading_behavior_flag.h",
     "loader/mime_sniffing_throttle.h",
     "loader/mime_sniffing_url_loader.h",
-    "loader/request_destination.h",
     "loader/url_loader_factory_bundle.h",
     "loader/url_loader_factory_bundle_mojom_traits.h",
     "loader/url_loader_throttle.h",
diff --git a/third_party/blink/public/common/feature_policy/document_policy.h b/third_party/blink/public/common/feature_policy/document_policy.h
index c8949ac..7e227c89 100644
--- a/third_party/blink/public/common/feature_policy/document_policy.h
+++ b/third_party/blink/public/common/feature_policy/document_policy.h
@@ -68,8 +68,6 @@
  public:
   using FeatureState = std::map<mojom::FeaturePolicyFeature, PolicyValue>;
 
-  ~DocumentPolicy();
-
   static std::unique_ptr<DocumentPolicy> CreateWithRequiredPolicy(
       const FeatureState& required_policy);
 
diff --git a/third_party/blink/public/common/feature_policy/policy_value.h b/third_party/blink/public/common/feature_policy/policy_value.h
index 81bc1799..7b745f6 100644
--- a/third_party/blink/public/common/feature_policy/policy_value.h
+++ b/third_party/blink/public/common/feature_policy/policy_value.h
@@ -20,7 +20,6 @@
 class BLINK_COMMON_EXPORT PolicyValue {
  public:
   PolicyValue();
-  ~PolicyValue();
 
   explicit PolicyValue(mojom::PolicyValueType);
 
diff --git a/third_party/blink/public/common/loader/request_destination.h b/third_party/blink/public/common/loader/request_destination.h
deleted file mode 100644
index 54f3af4..0000000
--- a/third_party/blink/public/common/loader/request_destination.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_REQUEST_DESTINATION_H_
-#define THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_REQUEST_DESTINATION_H_
-
-#include "third_party/blink/public/common/common_export.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
-
-namespace blink {
-
-// This function maps from Blink's internal "request context" concept to
-// Fetch's notion of a request's "destination":
-// https://fetch.spec.whatwg.org/#concept-request-destination.
-BLINK_COMMON_EXPORT const char* GetRequestDestinationFromContext(
-    mojom::RequestContextType context);
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_REQUEST_DESTINATION_H_
diff --git a/third_party/blink/public/common/loader/throttling_url_loader.h b/third_party/blink/public/common/loader/throttling_url_loader.h
index 62edbeb..a21d00bc 100644
--- a/third_party/blink/public/common/loader/throttling_url_loader.h
+++ b/third_party/blink/public/common/loader/throttling_url_loader.h
@@ -256,7 +256,6 @@
   struct PriorityInfo {
     PriorityInfo(net::RequestPriority in_priority,
                  int32_t in_intra_priority_value);
-    ~PriorityInfo();
 
     net::RequestPriority priority;
     int32_t intra_priority_value;
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
index 2b33a03..313369b 100644
--- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
+++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -20,9 +20,10 @@
 
 // Type of the context associated with a request.
 // https://fetch.spec.whatwg.org/#concept-request-destination.
-// TODO(crbug.com/889751): This is a deprecated spec concept, figure out
-// how to refactor this to match the new spec concepts, 'destination' and
-// 'initiator'.
+// TODO(https://crbug.com/889751): Fetch now defines this concept as a request's
+// "destination", represented as the enum
+// network::mojom::RequestDestination. We should use that enum rather
+// than this one.
 enum RequestContextType {
   UNSPECIFIED,
   AUDIO,
@@ -171,6 +172,7 @@
   network.mojom.RequestMode mode = network.mojom.RequestMode.kNoCors;
   bool is_main_resource_load = false;
   RequestContextType request_context_type = RequestContextType.UNSPECIFIED;
+  network.mojom.RequestDestination destination = network.mojom.RequestDestination.kEmpty;
   network.mojom.RequestContextFrameType frame_type =
     network.mojom.RequestContextFrameType.kNone;
   url.mojom.Url url;
diff --git a/third_party/blink/public/mojom/use_counter/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/css_property_id.mojom
index c2b8fe7..94bea29 100644
--- a/third_party/blink/public/mojom/use_counter/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/css_property_id.mojom
@@ -16,6 +16,36 @@
     // These internal properties exist but are mapped to 0 to ensure they don't get
     // reported in use counter.
     kInternalEffectiveZoom = 0,
+    kInternalUaBackgroundAttachment = 0,
+    kInternalUaBackgroundBlendMode = 0,
+    kInternalUaBackgroundClip = 0,
+    kInternalUaBackgroundColor = 0,
+    kInternalUaBackgroundImage = 0,
+    kInternalUaBackgroundOrigin = 0,
+    kInternalUaBackgroundPositionX = 0,
+    kInternalUaBackgroundPositionY = 0,
+    kInternalUaBackgroundSize = 0,
+    kInternalUaBorderBottomColor = 0,
+    kInternalUaBorderBottomLeftRadius = 0,
+    kInternalUaBorderBottomRightRadius = 0,
+    kInternalUaBorderBottomStyle = 0,
+    kInternalUaBorderBottomWidth = 0,
+    kInternalUaBorderImageOutset = 0,
+    kInternalUaBorderImageRepeat = 0,
+    kInternalUaBorderImageSlice = 0,
+    kInternalUaBorderImageSource = 0,
+    kInternalUaBorderImageWidth = 0,
+    kInternalUaBorderLeftColor = 0,
+    kInternalUaBorderLeftStyle = 0,
+    kInternalUaBorderLeftWidth = 0,
+    kInternalUaBorderRightColor = 0,
+    kInternalUaBorderRightStyle = 0,
+    kInternalUaBorderRightWidth = 0,
+    kInternalUaBorderTopColor = 0,
+    kInternalUaBorderTopLeftRadius = 0,
+    kInternalUaBorderTopRightRadius = 0,
+    kInternalUaBorderTopStyle = 0,
+    kInternalUaBorderTopWidth = 0,
     kInternalVisitedBackgroundColor = 0,
     kInternalVisitedBorderBlockEndColor = 0,
     kInternalVisitedBorderBlockStartColor = 0,
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index d016ef8..aecc653 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -606,7 +606,7 @@
   kFlexboxIntrinsicSizeAlgorithmIsDifferent = 939,
   // The above items are available in M46 branch.
 
-  kHTMLImportsHasStyleSheets = 940,
+  kHTMLImportsHasStyleSheets_Obsolete = 940,
   kNetInfoType = 946,
   kNetInfoDownlinkMax = 947,
   kNetInfoOnChange = 948,
@@ -2400,7 +2400,6 @@
   kCreateObjectBlob = 3028,
   kQuotaRead = 3029,  // available in M78 branch.
   kDelegateFocus = 3030,
-  kDelegateFocusNotFirstInFlatTree = 3031,
   kThirdPartySharedWorker = 3032,
   kThirdPartyBroadcastChannel = 3033,
   kMediaSourceGroupEndTimestampDecreaseWithinMediaSegment = 3034,
@@ -2490,6 +2489,11 @@
   kLongTaskBufferFull = 3118,
   kHTMLMetaElementMonetization = 3119,
   kHTMLLinkElementMonetization = 3120,
+  kInputTypeCheckboxRenderedNonSquare = 3121,
+  kInputTypeRadioRenderedNonSquare = 3122,
+  kWebkitBoxPackJustifyDoesSomething = 3123,
+  kWebkitBoxPackCenterDoesSomething = 3124,
+  kWebkitBoxPackEndDoesSomething = 3125,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_gesture_event.h b/third_party/blink/public/platform/web_gesture_event.h
index 52fbeb2..c93354e7 100644
--- a/third_party/blink/public/platform/web_gesture_event.h
+++ b/third_party/blink/public/platform/web_gesture_event.h
@@ -6,18 +6,15 @@
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_GESTURE_EVENT_H_
 
 #include "cc/paint/element_id.h"
-#include "third_party/blink/public/platform/web_float_size.h"
 #include "third_party/blink/public/platform/web_gesture_device.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/public/platform/web_pointer_properties.h"
 #include "third_party/blink/public/platform/web_scroll_types.h"
 #include "ui/events/types/scroll_types.h"
+#include "ui/gfx/geometry/size_f.h"
 
 namespace blink {
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebGestureEvent ---------------------------------------------------------
 
 class WebGestureEvent : public WebInputEvent {
@@ -178,10 +175,10 @@
   // Widget coordinate, which is relative to the bound of current RenderWidget
   // (e.g. a plugin or OOPIF inside a RenderView). Similar to viewport
   // coordinates but without DevTools emulation transform or overscroll applied.
-  WebFloatPoint position_in_widget_;
+  gfx::PointF position_in_widget_;
 
   // Screen coordinate
-  WebFloatPoint position_in_screen_;
+  gfx::PointF position_in_screen_;
 
   WebGestureDevice source_device_;
 
@@ -197,14 +194,14 @@
       : WebInputEvent(sizeof(WebGestureEvent)),
         source_device_(WebGestureDevice::kUninitialized) {}
 
-  const WebFloatPoint& PositionInWidget() const { return position_in_widget_; }
-  const WebFloatPoint& PositionInScreen() const { return position_in_screen_; }
+  const gfx::PointF& PositionInWidget() const { return position_in_widget_; }
+  const gfx::PointF& PositionInScreen() const { return position_in_screen_; }
 
-  void SetPositionInWidget(const WebFloatPoint& point) {
+  void SetPositionInWidget(const gfx::PointF& point) {
     position_in_widget_ = point;
   }
 
-  void SetPositionInScreen(const WebFloatPoint& point) {
+  void SetPositionInScreen(const gfx::PointF& point) {
     position_in_screen_ = point;
   }
 
@@ -215,18 +212,18 @@
   BLINK_PLATFORM_EXPORT float DeltaXInRootFrame() const;
   BLINK_PLATFORM_EXPORT float DeltaYInRootFrame() const;
   BLINK_PLATFORM_EXPORT ui::input_types::ScrollGranularity DeltaUnits() const;
-  BLINK_PLATFORM_EXPORT WebFloatPoint PositionInRootFrame() const;
+  BLINK_PLATFORM_EXPORT gfx::PointF PositionInRootFrame() const;
   BLINK_PLATFORM_EXPORT InertialPhaseState InertialPhase() const;
   BLINK_PLATFORM_EXPORT bool Synthetic() const;
 
   BLINK_PLATFORM_EXPORT float VelocityX() const;
   BLINK_PLATFORM_EXPORT float VelocityY() const;
 
-  BLINK_PLATFORM_EXPORT WebFloatSize TapAreaInRootFrame() const;
+  BLINK_PLATFORM_EXPORT gfx::SizeF TapAreaInRootFrame() const;
   BLINK_PLATFORM_EXPORT int TapCount() const;
 
   BLINK_PLATFORM_EXPORT void ApplyTouchAdjustment(
-      WebFloatPoint root_frame_coords);
+      const gfx::PointF& root_frame_coords);
 
   // Sets any scaled values to be their computed values and sets |frame_scale_|
   // back to 1 and |frame_translate_| X and Y coordinates back to 0.
@@ -318,8 +315,6 @@
   }
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_GESTURE_EVENT_H_
diff --git a/third_party/blink/public/platform/web_input_event.h b/third_party/blink/public/platform/web_input_event.h
index 732401f..4fcaccb3 100644
--- a/third_party/blink/public/platform/web_input_event.h
+++ b/third_party/blink/public/platform/web_input_event.h
@@ -34,25 +34,11 @@
 #include <string.h>
 
 #include "base/time/time.h"
-#include "third_party/blink/public/platform/web_float_point.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace blink {
 
-// The classes defined in this file are intended to be used with
-// WebWidget's HandleInputEvent method.  These event types are cross-
-// platform and correspond closely to WebCore's Platform*Event classes.
-//
-// WARNING! These classes must remain PODs (plain old data).  They are
-// intended to be "serializable" by copying their raw bytes, so they must
-// not contain any non-bit-copyable member variables!
-//
-// Furthermore, the class members need to be packed so they are aligned
-// properly and don't have paddings/gaps, otherwise memory check tools
-// like Valgrind will complain about uninitialized memory usage when
-// transferring these classes over the wire.
-
-#pragma pack(push, 4)
-
 // WebInputEvent --------------------------------------------------------------
 
 class WebInputEvent {
@@ -425,8 +411,8 @@
   float FrameScale() const { return frame_scale_; }
   void SetFrameScale(float scale) { frame_scale_ = scale; }
 
-  WebFloatPoint FrameTranslate() const { return frame_translate_; }
-  void SetFrameTranslate(WebFloatPoint translate) {
+  gfx::Vector2dF FrameTranslate() const { return frame_translate_; }
+  void SetFrameTranslate(gfx::Vector2dF translate) {
     frame_translate_ = translate;
   }
 
@@ -450,7 +436,7 @@
   float frame_scale_;
 
   // The root frame translation (applied post scale).
-  WebFloatPoint frame_translate_;
+  gfx::Vector2dF frame_translate_;
 
   WebInputEvent(unsigned size,
                 Type type,
@@ -496,8 +482,6 @@
   int modifiers_;
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/public/platform/web_keyboard_event.h b/third_party/blink/public/platform/web_keyboard_event.h
index 4518dc7d..59c20e6 100644
--- a/third_party/blink/public/platform/web_keyboard_event.h
+++ b/third_party/blink/public/platform/web_keyboard_event.h
@@ -5,13 +5,11 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_KEYBOARD_EVENT_H_
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_KEYBOARD_EVENT_H_
 
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 
 namespace blink {
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebKeyboardEvent -----------------------------------------------------------
 
 class WebKeyboardEvent : public WebInputEvent {
@@ -84,8 +82,6 @@
   }
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_KEYBOARD_EVENT_H_
diff --git a/third_party/blink/public/platform/web_mouse_event.h b/third_party/blink/public/platform/web_mouse_event.h
index 4c93146..2436505 100644
--- a/third_party/blink/public/platform/web_mouse_event.h
+++ b/third_party/blink/public/platform/web_mouse_event.h
@@ -13,9 +13,6 @@
 
 class WebGestureEvent;
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebMouseEvent --------------------------------------------------------------
 
 class WebMouseEvent : public WebInputEvent, public WebPointerProperties {
@@ -28,8 +25,8 @@
   WebMenuSourceType menu_source_type;
 
   WebMouseEvent(Type type_param,
-                WebFloatPoint position,
-                WebFloatPoint global_position,
+                gfx::PointF position,
+                gfx::PointF global_position,
                 Button button_param,
                 int click_count_param,
                 int modifiers_param,
@@ -76,7 +73,7 @@
                                       base::TimeTicks time_stamp_param,
                                       PointerId id_param = kMousePointerId);
 
-  BLINK_PLATFORM_EXPORT WebFloatPoint PositionInRootFrame() const;
+  BLINK_PLATFORM_EXPORT gfx::PointF PositionInRootFrame() const;
 
   // Sets any scaled values to be their computed values and sets |frame_scale_|
   // back to 1 and |frame_translate_| X and Y coordinates back to 0.
@@ -101,8 +98,6 @@
   void SetMenuSourceType(WebInputEvent::Type);
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MOUSE_EVENT_H_
diff --git a/third_party/blink/public/platform/web_mouse_wheel_event.h b/third_party/blink/public/platform/web_mouse_wheel_event.h
index d694d03..d135536 100644
--- a/third_party/blink/public/platform/web_mouse_wheel_event.h
+++ b/third_party/blink/public/platform/web_mouse_wheel_event.h
@@ -10,9 +10,6 @@
 
 namespace blink {
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebMouseWheelEvent ---------------------------------------------------------
 
 class WebMouseWheelEvent : public WebMouseEvent {
@@ -139,8 +136,6 @@
   return !(a == b);
 }
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MOUSE_WHEEL_EVENT_H_
diff --git a/third_party/blink/public/platform/web_pointer_event.h b/third_party/blink/public/platform/web_pointer_event.h
index 4d9b3ced..ce9184d 100644
--- a/third_party/blink/public/platform/web_pointer_event.h
+++ b/third_party/blink/public/platform/web_pointer_event.h
@@ -12,9 +12,6 @@
 
 namespace blink {
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebPointerEvent
 // This is a WIP and currently used only in Blink and only for touch.
 // TODO(nzolghadr): We should unify the fields in this class into
@@ -89,8 +86,6 @@
 #endif
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // WebMouseEvent_h
diff --git a/third_party/blink/public/platform/web_pointer_properties.h b/third_party/blink/public/platform/web_pointer_properties.h
index ea414bb..eb48841 100644
--- a/third_party/blink/public/platform/web_pointer_properties.h
+++ b/third_party/blink/public/platform/web_pointer_properties.h
@@ -7,7 +7,7 @@
 
 #include "third_party/blink/public/platform/pointer_id.h"
 #include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_float_point.h"
+#include "ui/gfx/geometry/point_f.h"
 
 #include <limits>
 
@@ -55,8 +55,8 @@
       PointerId id_param,
       PointerType pointer_type_param = PointerType::kUnknown,
       Button button_param = Button::kNoButton,
-      WebFloatPoint position_in_widget = WebFloatPoint(),
-      WebFloatPoint position_in_screen = WebFloatPoint(),
+      gfx::PointF position_in_widget = gfx::PointF(),
+      gfx::PointF position_in_screen = gfx::PointF(),
       int movement_x = 0,
       int movement_y = 0)
       : id(id_param),
@@ -73,22 +73,22 @@
         position_in_widget_(position_in_widget),
         position_in_screen_(position_in_screen) {}
 
-  WebFloatPoint PositionInWidget() const { return position_in_widget_; }
-  WebFloatPoint PositionInScreen() const { return position_in_screen_; }
+  const gfx::PointF& PositionInWidget() const { return position_in_widget_; }
+  const gfx::PointF& PositionInScreen() const { return position_in_screen_; }
 
   void SetPositionInWidget(float x, float y) {
-    position_in_widget_ = WebFloatPoint(x, y);
+    position_in_widget_ = gfx::PointF(x, y);
   }
 
   void SetPositionInScreen(float x, float y) {
-    position_in_screen_ = WebFloatPoint(x, y);
+    position_in_screen_ = gfx::PointF(x, y);
   }
 
-  void SetPositionInWidget(const WebFloatPoint& point) {
+  void SetPositionInWidget(const gfx::PointF& point) {
     position_in_widget_ = point;
   }
 
-  void SetPositionInScreen(const WebFloatPoint& point) {
+  void SetPositionInScreen(const gfx::PointF& point) {
     position_in_screen_ = point;
   }
 
@@ -134,10 +134,10 @@
   // Widget coordinate, which is relative to the bound of current RenderWidget
   // (e.g. a plugin or OOPIF inside a RenderView). Similar to viewport
   // coordinates but without DevTools emulation transform or overscroll applied.
-  WebFloatPoint position_in_widget_;
+  gfx::PointF position_in_widget_;
 
   // Screen coordinate
-  WebFloatPoint position_in_screen_;
+  gfx::PointF position_in_screen_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/public/platform/web_touch_event.h b/third_party/blink/public/platform/web_touch_event.h
index 6412873..d9ef00e 100644
--- a/third_party/blink/public/platform/web_touch_event.h
+++ b/third_party/blink/public/platform/web_touch_event.h
@@ -10,9 +10,6 @@
 
 namespace blink {
 
-// See web_input_event.h for details why this pack is here.
-#pragma pack(push, 4)
-
 // WebTouchEvent --------------------------------------------------------------
 
 // TODO(e_hakkinen): Replace with WebPointerEvent. crbug.com/508283
@@ -68,8 +65,6 @@
 #endif
 };
 
-#pragma pack(pop)
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_TOUCH_EVENT_H_
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h
index f181d40..a96f4ab4 100644
--- a/third_party/blink/public/platform/web_url_request.h
+++ b/third_party/blink/public/platform/web_url_request.h
@@ -47,6 +47,7 @@
 enum class ReferrerPolicy : int32_t;
 enum class RequestMode : int32_t;
 enum class RequestContextFrameType : int32_t;
+enum class RequestDestination : int32_t;
 }  // namespace mojom
 }  // namespace network
 
@@ -209,11 +210,9 @@
 
   BLINK_PLATFORM_EXPORT WebString HttpHeaderField(const WebString& name) const;
   // It's not possible to set the referrer header using this method. Use
-  // SetHttpReferrer instead.
+  // SetReferrerString instead.
   BLINK_PLATFORM_EXPORT void SetHttpHeaderField(const WebString& name,
                                                 const WebString& value);
-  BLINK_PLATFORM_EXPORT void SetHttpReferrer(const WebString& referrer,
-                                             network::mojom::ReferrerPolicy);
   BLINK_PLATFORM_EXPORT void AddHttpHeaderField(const WebString& name,
                                                 const WebString& value);
   BLINK_PLATFORM_EXPORT void ClearHttpHeaderField(const WebString& name);
@@ -238,6 +237,16 @@
   BLINK_PLATFORM_EXPORT mojom::RequestContextType GetRequestContext() const;
   BLINK_PLATFORM_EXPORT void SetRequestContext(mojom::RequestContextType);
 
+  BLINK_PLATFORM_EXPORT network::mojom::RequestDestination
+  GetRequestDestination() const;
+  BLINK_PLATFORM_EXPORT void SetRequestDestination(
+      network::mojom::RequestDestination);
+
+  BLINK_PLATFORM_EXPORT void SetReferrerString(const WebString& referrer);
+  BLINK_PLATFORM_EXPORT void SetReferrerPolicy(
+      network::mojom::ReferrerPolicy referrer_policy);
+
+  BLINK_PLATFORM_EXPORT WebString ReferrerString() const;
   BLINK_PLATFORM_EXPORT network::mojom::ReferrerPolicy GetReferrerPolicy()
       const;
 
diff --git a/third_party/blink/public/public_features.gni b/third_party/blink/public/public_features.gni
index f9775696..7d7a335 100644
--- a/third_party/blink/public/public_features.gni
+++ b/third_party/blink/public/public_features.gni
@@ -10,6 +10,13 @@
   # resources.pak. It is still possible to load JS files from disk by passing
   # --debug-devtools cmdline switch.
   debug_devtools = false
+
+  # If enable_additional_blink_object_names is set to true, then blink provides
+  # additional debug names of blink-internal (i.e. oilpan) object names at the
+  # cost of additional memory. Many of these objects only show up in heap
+  # snapshots if the parameter `treatGlobalObjectsAsRoots` of `takeHeapSnapshot`
+  # is set.
+  enable_additional_blink_object_names = false
 }
 
 # Unhandled Tap enable means Contextual Search aka Tap to Search.
diff --git a/third_party/blink/public/strings/translations/blink_strings_eu.xtb b/third_party/blink/public/strings/translations/blink_strings_eu.xtb
index bc24f64..e6ac27a 100644
--- a/third_party/blink/public/strings/translations/blink_strings_eu.xtb
+++ b/third_party/blink/public/strings/translations/blink_strings_eu.xtb
@@ -114,6 +114,7 @@
 <translation id="4812940957355064477">Idatzi zenbaki bat.</translation>
 <translation id="4912536737030637138">bibliografia-sarrera</translation>
 <translation id="492244087561876220">iruzkina</translation>
+<translation id="4971739861736909480"><ph name="ACCNAME" /> hautatuta</translation>
 <translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> hautatuta</translation>
 <translation id="4992066212339426712">Aktibatu audioa</translation>
 <translation id="49969490063480558">Idatzi testua "<ph name="ATSIGN" />" ikurraren ondoren. "<ph name="INVALIDADDRESS" />" ez dago osorik.</translation>
@@ -218,6 +219,7 @@
 <translation id="7888071071722539607">Sartu "<ph name="ATSIGN" />" ikurra helbide elektronikoan. "<ph name="INVALIDADDRESS" />" helbideari "<ph name="ATSIGN" />" ikurra falta zaio.</translation>
 <translation id="7891486169920085145">banatzailea</translation>
 <translation id="795667975304826397">Ez da fitxategirik aukeratu</translation>
+<translation id="7962328325860248200"><ph name="ACCNAME" /> hautatu gabe</translation>
 <translation id="8034303206267677282">garrantzitsua</translation>
 <translation id="8053789581856978548">testua bilatzeko eremua</translation>
 <translation id="8057695513531652401">oharra</translation>
diff --git a/third_party/blink/public/strings/translations/blink_strings_km.xtb b/third_party/blink/public/strings/translations/blink_strings_km.xtb
index fcd5385..f5f56ad 100644
--- a/third_party/blink/public/strings/translations/blink_strings_km.xtb
+++ b/third_party/blink/public/strings/translations/blink_strings_km.xtb
@@ -114,6 +114,7 @@
 <translation id="4812940957355064477">សូមបញ្ចូលលេខ។</translation>
 <translation id="4912536737030637138">ធាតុគន្ថនិទ្ទេស</translation>
 <translation id="492244087561876220">មតិ</translation>
+<translation id="4971739861736909480">បាន​ជ្រើសរើស <ph name="ACCNAME" /></translation>
 <translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> បានជ្រើសរើស</translation>
 <translation id="4992066212339426712">បើកសម្លេង</translation>
 <translation id="49969490063480558">សូមបញ្ចូលផ្នែកមួយនៅខាងក្រោយ '<ph name="ATSIGN" />'។ '<ph name="INVALIDADDRESS" />' មិនពេញលេញទេ។</translation>
@@ -218,6 +219,7 @@
 <translation id="7888071071722539607">សូមបញ្ចូល '<ph name="ATSIGN" />' នៅក្នុងអាសយដ្ឋានអ៊ីម៉ែល។ '<ph name="INVALIDADDRESS" />' បាត់បង់ '<ph name="ATSIGN" />'។</translation>
 <translation id="7891486169920085145">អង្គបំបែក</translation>
 <translation id="795667975304826397">មិនមានឯកសារត្រូវបានជ្រើសរើសទេ</translation>
+<translation id="7962328325860248200">មិនបាន​ជ្រើសរើស <ph name="ACCNAME" /> ទេ</translation>
 <translation id="8034303206267677282">ខ្លាំង</translation>
 <translation id="8053789581856978548">ប្រអប់អត្ថបទស្វែងរក</translation>
 <translation id="8057695513531652401">ការជូន​ដំណឹង</translation>
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h
index 9b31878..291ce510 100644
--- a/third_party/blink/public/web/web_ax_object.h
+++ b/third_party/blink/public/web/web_ax_object.h
@@ -148,6 +148,7 @@
   BLINK_EXPORT bool IsVisible() const;
   BLINK_EXPORT bool IsVisited() const;
 
+  BLINK_EXPORT bool HasAriaAttribute() const;
   BLINK_EXPORT WebString AccessKey() const;
   BLINK_EXPORT unsigned BackgroundColor() const;
   BLINK_EXPORT bool CanPress() const;
diff --git a/third_party/blink/public/web/web_input_method_controller.h b/third_party/blink/public/web/web_input_method_controller.h
index 8afa51d..f06ec0b 100644
--- a/third_party/blink/public/web/web_input_method_controller.h
+++ b/third_party/blink/public/web/web_input_method_controller.h
@@ -82,10 +82,15 @@
   }
 
   // Populate |control_bounds| and |selection_bounds| with the bounds fetched
-  // from the active EditContext
-  virtual void GetLayoutBounds(WebRect& control_bounds,
-                               WebRect& selection_bounds) = 0;
-  // Returns true if there is an active EditContext
+  // from the active EditContext. If there isn't any active |EditContext|, then
+  // these bounds are empty.
+  virtual void GetLayoutBounds(WebRect* control_bounds,
+                               WebRect* selection_bounds) = 0;
+  // Returns true if the inputPanelPolicy flag is set as manual in
+  // |EditContext|, which indicates that the software input panel(Virtual
+  // Keyboard) shouldn't come up on focus of the EditControl.
+  virtual bool IsInputPanelPolicyManual() const = 0;
+  // Returns true if there is an active |EditContext|.
   virtual bool IsEditContextActive() const = 0;
 };
 
diff --git a/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
index 2acb851a..9419844 100644
--- a/third_party/blink/renderer/bindings/core/v8/BUILD.gn
+++ b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -162,6 +162,8 @@
   "$bindings_core_v8_output_dir/v8_idle_request_callback.h",
   "$bindings_core_v8_output_dir/v8_intersection_observer_callback.cc",
   "$bindings_core_v8_output_dir/v8_intersection_observer_callback.h",
+  "$bindings_core_v8_output_dir/v8_intrinsic_sizes_callback.cc",
+  "$bindings_core_v8_output_dir/v8_intrinsic_sizes_callback.h",
   "$bindings_core_v8_output_dir/v8_layout_callback.cc",
   "$bindings_core_v8_output_dir/v8_layout_callback.h",
   "$bindings_core_v8_output_dir/v8_mojo_watch_callback.cc",
diff --git a/third_party/blink/renderer/build/scripts/core/css/css_properties.py b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
index 13889329..928e6b0c 100755
--- a/third_party/blink/renderer/build/scripts/core/css/css_properties.py
+++ b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
@@ -67,9 +67,7 @@
         # in the various generators for ComputedStyle.
         self._field_alias_expander = FieldAliasExpander(file_paths[1])
 
-        # CSSPropertyValueMetadata assumes that there are at most 1024
-        # properties + aliases.
-        self._alias_offset = 512
+        self._alias_offset = 1024
         # 0: CSSPropertyID::kInvalid
         # 1: CSSPropertyID::kVariable
         self._first_enum_value = 2
@@ -121,6 +119,8 @@
             self.expand_visited(property_)
             property_['in_origin_trial'] = False
             self.expand_origin_trials(property_, origin_trial_features)
+            self.expand_ua(property_)
+            self.expand_slots(property_)
 
         self._aliases = [
             property_ for property_ in properties if property_['alias_for']]
@@ -189,6 +189,31 @@
             'A property may not have multiple visited properties'
         unvisited_property['visited_property'] = property_
 
+    def expand_slots(self, property_):
+        if not property_['slots']:
+            return
+        assert not property_['is_slot'], \
+            'A slot (is_slot:true) may not reference slots'
+        # Verify that referenced slots have is_slot==True.
+        for slot in property_['slots']:
+            assert slot in self._properties_by_name, \
+                'Slots must name a property'
+            assert self._properties_by_name[slot]['is_slot'], \
+                'Referenced slot is not marked as a slot'
+        # Upgrade 'slots' to property references.
+        property_['slots'] = [self._properties_by_name[s] for s in property_['slots']]
+
+    def expand_ua(self, ua_property_):
+        if not ua_property_['ua_property_for']:
+            return
+        ua_property_for = ua_property_['ua_property_for']
+        author_property = self._properties_by_name[ua_property_for]
+        ua_property_['ua'] = True
+        ua_property_['author_property'] = author_property
+        assert 'ua_property' not in author_property, \
+            'A property may not have multiple ua properties'
+        author_property['ua_property'] = ua_property_
+
     def expand_aliases(self):
         for i, alias in enumerate(self._aliases):
             assert not alias['runtime_flag'], \
diff --git a/third_party/blink/renderer/build/scripts/core/css/make_style_cascade_slots.py b/third_party/blink/renderer/build/scripts/core/css/make_style_cascade_slots.py
new file mode 100755
index 0000000..a8077c6
--- /dev/null
+++ b/third_party/blink/renderer/build/scripts/core/css/make_style_cascade_slots.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json5_generator
+import template_expander
+
+from core.css import css_properties
+
+
+class StyleCascadeSlotsWriter(json5_generator.Writer):
+    def __init__(self, json5_file_paths, output_dir):
+        super(StyleCascadeSlotsWriter, self).__init__([], output_dir)
+
+        json_properties = css_properties.CSSProperties(json5_file_paths)
+
+        self._properties = json_properties.longhands
+        self._outputs = {
+            'style_cascade_slots.h': self.generate_header,
+            'style_cascade_slots.cc': self.generate_impl,
+        }
+
+    @template_expander.use_jinja('core/css/templates/style_cascade_slots.h.tmpl')
+    def generate_header(self):
+        return {'properties': self._properties}
+
+    @template_expander.use_jinja('core/css/templates/style_cascade_slots.cc.tmpl')
+    def generate_impl(self):
+        return {'properties': self._properties}
+
+if __name__ == '__main__':
+    json5_generator.Maker(StyleCascadeSlotsWriter).main()
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
index 655d148..91d9eb3 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
@@ -81,6 +81,11 @@
   return &Get{{property.unvisited_property.property_id}}();
 }
   {% endif %}
+  {% if property.ua_property %}
+const CSSProperty* {{class_name}}::GetUAProperty() const {
+  return &Get{{property.ua_property.property_id}}();
+}
+  {% endif %}
 
   {% if property.direction_aware_options %}
     {% set options = property.direction_aware_options %}
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
index a8ddca7..02df45d 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
@@ -40,6 +40,7 @@
   (property.visited and 'kVisited' or ''),
   (property.is_internal and 'kInternal' or ''),
   (property.affected_by_forced_colors and 'kIsAffectedByForcedColors' or ''),
+  (property.ua and 'kUA' or ''),
 ] | reject('==', '') | join(' | ') %}
 {% set ctor_args = (not is_alias and [property_id, flags, separator] or []) %}
 // {{property.name}}
@@ -69,6 +70,9 @@
   {% if property.unvisited_property %}
   const CSSProperty* GetUnvisitedProperty() const override;
   {% endif %}
+  {% if property.ua_property %}
+  const CSSProperty* GetUAProperty() const override;
+  {% endif %}
   {% for property_method in property.property_methods %}
   {{property_method.return_type}} {{property_method.name}}{{property_method.parameters}} const override;
   {% endfor %}
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
index 9c9142d..40c02fe0 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -37,6 +37,8 @@
 state.Style()->AccessSVGStyle().{{property.setter}}
   {%- elif property.font %}
 state.GetFontBuilder().{{property.setter}}
+  {%- elif property.ua %}
+state.EnsureUAStyle()->{{property.setter}}
   {%- else %}
 state.Style()->{{property.setter}}
   {%- endif %}
@@ -136,10 +138,11 @@
   {% elif property.style_builder_template in ['border_image', 'mask_box'] %}
     {% set is_mask_box = property.style_builder_template == 'mask_box' %}
     {% set modifier_type = property.style_builder_template_args['modifier_type'] %}
+    {% set target = 'state.EnsureUAStyle()' if property.ua else 'state.Style()'%}
     {% set getter = 'MaskBoxImage' if is_mask_box else 'BorderImage' %}
     {% set setter = 'Set' + getter %}
     {% call(property) apply_initial(property) %}
-  const NinePieceImage& current_image = state.Style()->{{getter}}();
+  const NinePieceImage& current_image = {{target}}->{{getter}}();
   {# Check for equality in case we can bail out before creating a new NinePieceImage. #}
       {% if modifier_type == 'Outset' %}
   if (style_building_utils::BorderImageLengthMatchesAllSides(current_image.Outset(),
@@ -185,10 +188,10 @@
       {% elif modifier_type == 'Width' %}
   image.SetBorderSlices({{ 'Length::Auto()' if is_mask_box else '1.0' }});
       {% endif %}
-  state.Style()->{{setter}}(image);
+  {{target}}->{{setter}}(image);
     {% endcall %}
     {% call(property) apply_inherit(property) %}
-  NinePieceImage image(state.Style()->{{getter}}());
+  NinePieceImage image({{target}}->{{getter}}());
       {% if modifier_type == 'Outset' %}
   image.CopyOutsetFrom(state.ParentStyle()->{{getter}}());
       {% elif modifier_type == 'Repeat' %}
@@ -198,10 +201,10 @@
       {% elif modifier_type == 'Width' %}
   image.CopyBorderSlicesFrom(state.ParentStyle()->{{getter}}());
       {% endif %}
-  state.Style()->{{setter}}(image);
+  {{target}}->{{setter}}(image);
     {% endcall %}
     {% call(property) apply_value(property) %}
-  NinePieceImage image(state.Style()->{{getter}}());
+  NinePieceImage image({{target}}->{{getter}}());
       {% if modifier_type == 'Outset' %}
   image.SetOutset(CSSToStyleMap::MapNinePieceImageQuad(state, value));
       {% elif modifier_type == 'Repeat' %}
@@ -211,7 +214,7 @@
       {% elif modifier_type == 'Width' %}
   image.SetBorderSlices(CSSToStyleMap::MapNinePieceImageQuad(state, value));
       {% endif %}
-  state.Style()->{{setter}}(image);
+  {{target}}->{{setter}}(image);
     {% endcall %}
   {% elif property.style_builder_template in ['animation', 'transition'] %}
     {% set attribute = property.style_builder_template_args['attribute'] %}
@@ -241,15 +244,16 @@
     {% set layer_type = 'Background' if property.style_builder_template == 'background_layer' else 'Mask' %}
     {% set fill_type = property.style_builder_template_args['fill_type'] %}
     {% set fill_type_getter = property.style_builder_template_args['fill_type_getter'] or fill_type %}
+    {% set target = 'state.EnsureUAStyle()' if property.ua else 'state.Style()' %}
     {% call(property) apply_initial(property) %}
-  FillLayer* curr_child = &state.Style()->Access{{layer_type}}Layers();
+  FillLayer* curr_child = &{{target}}->Access{{layer_type}}Layers();
   curr_child->Set{{fill_type}}(FillLayer::InitialFill{{fill_type}}(EFillLayerType::k{{layer_type}}));
   for (curr_child = curr_child->Next(); curr_child; curr_child = curr_child->Next())
     curr_child->Clear{{fill_type}}();
     {% endcall %}
 
     {% call(property) apply_inherit(property) %}
-  FillLayer* curr_child = &state.Style()->Access{{layer_type}}Layers();
+  FillLayer* curr_child = &{{target}}->Access{{layer_type}}Layers();
   FillLayer* prev_child = 0;
   const FillLayer* curr_parent = &state.ParentStyle()->{{layer_type}}Layers();
   while (curr_parent && curr_parent->Is{{fill_type}}Set()) {
@@ -277,7 +281,7 @@
     {% endcall %}
 
     {% call(property) apply_value(property) %}
-  FillLayer* curr_child = &state.Style()->Access{{layer_type}}Layers();
+  FillLayer* curr_child = &{{target}}->Access{{layer_type}}Layers();
   FillLayer* prev_child = 0;
   const auto* value_list = DynamicTo<CSSValueList>(value);
   if (value_list && !value.IsImageSetValue()) {
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.cc.tmpl
new file mode 100644
index 0000000..3375624a
--- /dev/null
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.cc.tmpl
@@ -0,0 +1,69 @@
+{% from 'templates/macros.tmpl' import license %}
+{{license()}}
+
+#include "third_party/blink/renderer/core/css/style_cascade_slots.h"
+
+#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+namespace {
+
+const CSSProperty& ResolveDirectionAware(
+    const CSSProperty& property,
+    const StyleResolverState& state) {
+  const CSSProperty& resolved = property.ResolveDirectionAwareProperty(
+      state.Style()->Direction(), state.Style()->GetWritingMode());
+  DCHECK_NE(&property, &resolved);
+  return resolved;
+}
+
+}  // anonymous namespace
+
+bool StyleCascadeSlots::Set(const CSSProperty& property,
+                            Priority priority,
+                            const StyleResolverState& state,
+                            AllowDefault allow_default) {
+  switch (property.PropertyID()) {
+    // Slots:
+{% for property in properties %}
+  {% if property.is_slot %}
+    case CSSPropertyID::{{property.enum_key}}:
+      if (priority < {{property.name.to_class_data_member()}})
+        return false;
+      {{property.name.to_class_data_member()}} = priority;
+      return true;
+  {% endif %}
+{% endfor %}
+    // Properties which use slots:
+{% for property in properties %}
+  {% if property.slots %}
+    case CSSPropertyID::{{property.enum_key}}:
+    {% for slot in property.slots %}
+      if (priority < {{slot.name.to_class_data_member()}})
+        return false;
+    {% endfor %}
+    {% for slot in property.slots %}
+      {{slot.name.to_class_data_member()}} = priority;
+    {% endfor %}
+      return true;
+  {% endif %}
+{% endfor %}
+    // Direction-aware properties:
+{% for property in properties %}
+  {% if property.direction_aware_options %}
+    case CSSPropertyID::{{property.enum_key}}:
+  {% endif %}
+{% endfor %}
+      return Set(ResolveDirectionAware(property, state),
+          priority, state, AllowDefault::kNo);
+    default:
+      // If you hit this DCHECK, you may need to mark the properties resolved
+      // to by css-logical properties as 'is_slot:true' in css_properties.json5.
+      DCHECK_EQ(allow_default, AllowDefault::kYes);
+      return true;
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.h.tmpl
new file mode 100644
index 0000000..ea356e3
--- /dev/null
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/style_cascade_slots.h.tmpl
@@ -0,0 +1,42 @@
+{% from 'templates/macros.tmpl' import license %}
+{{license()}}
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_CASCADE_SLOTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_CASCADE_SLOTS_H_
+
+#include "third_party/blink/renderer/core/css/resolver/style_cascade.h"
+
+namespace blink {
+
+class CSSProperty;
+class StyleResolverState;
+
+class CORE_EXPORT StyleCascadeSlots {
+  STACK_ALLOCATED();
+  using Priority = StyleCascade::Priority;
+ public:
+  // The default behavior for Set is to do nothing and return 'true'.
+  // By using AllowDefault::kNo, we'll instead hit a DCHECK if the default
+  // behavior is used, which is useful for direction-aware properties.
+  enum class AllowDefault { kNo, kYes };
+
+  // Attempt to set the slots associated with the given property to the given
+  // priority. If the incoming priority is higher or equal to the priority
+  // in each associated slot, the Set will succeed. Otheriwse, it will fail.
+  //
+  // If there are no slots for the given property, Set will succeed.
+  bool Set(const CSSProperty&,
+           Priority,
+           const StyleResolverState&,
+           AllowDefault allow_default = AllowDefault::kYes);
+ private:
+{% for property in properties %}
+  {% if property.is_slot %}
+  Priority {{property.name.to_class_data_member()}};
+  {% endif %}
+{% endfor %}
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_CASCADE_SLOTS_H_
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_initial_values.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_initial_values.h.tmpl
index 8bf3e6e..b7a19673 100644
--- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_initial_values.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_initial_values.h.tmpl
@@ -45,6 +45,7 @@
   }
   static StyleImage* InitialBorderImageSource() { return nullptr; }
   static float InitialBorderWidth() { return 3; }
+  static StyleColor InitialBorderColor() { return StyleColor(); }
   static uint16_t InitialColumnRuleWidth() {
     return 3;
   }
diff --git a/third_party/blink/renderer/build/scripts/rule_bison.py b/third_party/blink/renderer/build/scripts/rule_bison.py
index b623516..1974cb4 100755
--- a/third_party/blink/renderer/build/scripts/rule_bison.py
+++ b/third_party/blink/renderer/build/scripts/rule_bison.py
@@ -33,7 +33,7 @@
 # found in the LICENSE file.
 
 # usage: rule_bison.py INPUT_FILE OUTPUT_DIR BISON_EXE
-# INPUT_FILE is a path to either xpath_grammar.y.
+# INPUT_FILE is a path to *.y such as xpath_grammar.y.
 # OUTPUT_DIR is where the bison-generated .cc and .h files should be placed.
 
 import errno
@@ -73,8 +73,6 @@
         os.environ['PATH'] = path_to_bison + os.pathsep + os.environ['PATH']
 
     input_name = os.path.basename(input_file)
-    assert input_name == 'xpath_grammar.y'
-    prefix = {'xpath_grammar.y': 'xpathyy'}[input_name]
 
     # Output name without directory and extension.
     output_basename = os.path.splitext(input_name)[0] + '_generated'
@@ -84,7 +82,7 @@
     original_output_h = os.path.join(output_dir,
                                      output_basename + BISON_HEADER_EXT)
 
-    return_code = subprocess.call([bison_exe, '-d', '-p', prefix, input_file,
+    return_code = subprocess.call([bison_exe, '-d', input_file,
                                    '-o', output_cc])
     assert return_code == 0
     # If the file doesn't exist, this raise an OSError.
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 99c9377a..fbdf332d 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -549,6 +549,19 @@
   ]
 }
 
+css_properties("make_core_generated_style_cascade_slots") {
+  script = "../build/scripts/core/css/make_style_cascade_slots.py"
+  in_files = []
+  other_inputs = [
+    "../build/scripts/core/css/templates/style_cascade_slots.h.tmpl",
+    "../build/scripts/core/css/templates/style_cascade_slots.cc.tmpl",
+  ]
+  outputs = [
+    "$blink_core_output_dir/css/style_cascade_slots.h",
+    "$blink_core_output_dir/css/style_cascade_slots.cc",
+  ]
+}
+
 code_generator("make_core_generated_atrule_names") {
   script = "../build/scripts/core/css/parser/make_atrule_names.py"
   json_inputs = [ "css/parser/at_rule_names.json5" ]
@@ -976,6 +989,7 @@
   ":make_core_generated_media_type_names",
   ":make_core_generated_origin_trials",
   ":make_core_generated_performance_entry_names",
+  ":make_core_generated_style_cascade_slots",
   ":make_core_generated_style_property_shorthand",
   ":make_core_generated_svg_element_type_helpers",
   ":make_core_generated_svg_names",
@@ -1446,6 +1460,7 @@
     "page/scrolling/snap_coordinator_test.cc",
     "page/scrolling/text_fragment_anchor_metrics_test.cc",
     "page/scrolling/text_fragment_anchor_test.cc",
+    "page/scrolling/text_fragment_selector_test.cc",
     "page/slot_scoped_traversal_test.cc",
     "page/spatial_navigation_test.cc",
     "page/touch_adjustment_test.cc",
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS
index f1fdd4fa..5c38eb42 100644
--- a/third_party/blink/renderer/core/DEPS
+++ b/third_party/blink/renderer/core/DEPS
@@ -64,6 +64,7 @@
     "+services/network/public/cpp/cors/cors_error_status.h",
     "+services/network/public/cpp/features.h",
     "+services/network/public/cpp/request_mode.h",
+    "+services/network/public/cpp/request_destination.h",
     "+services/network/public/cpp/shared_url_loader_factory.h",
     "+services/resource_coordinator/public/mojom/coordination_unit.mojom-blink.h",
     "+services/service_manager/public",
diff --git a/third_party/blink/renderer/core/animation/animatable.cc b/third_party/blink/renderer/core/animation/animatable.cc
index fa61cb15..75f86c2 100644
--- a/third_party/blink/renderer/core/animation/animatable.cc
+++ b/third_party/blink/renderer/core/animation/animatable.cc
@@ -99,7 +99,8 @@
   for (const auto& animation :
        element->GetDocument().Timeline().getAnimations()) {
     DCHECK(animation->effect());
-    Element* target = To<KeyframeEffect>(animation->effect())->target();
+    // TODO(gtsteel) make this use the idl properties
+    Element* target = To<KeyframeEffect>(animation->effect())->EffectTarget();
     if (element == target || (use_subtree && element->contains(target))) {
       // DocumentTimeline::getAnimations should only give us animations that are
       // either current or in effect.
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
index 51b8322..6ca9633 100644
--- a/third_party/blink/renderer/core/animation/animation.cc
+++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -627,7 +627,7 @@
   if (!effect)
     return false;
 
-  return (effect->target() == &element) &&
+  return (effect->EffectTarget() == &element) &&
          effect->Affects(PropertyHandle(property));
 }
 
@@ -2051,7 +2051,7 @@
   if (!keyframe_effect)
     return;
 
-  Element* target = keyframe_effect->target();
+  Element* target = keyframe_effect->EffectTarget();
 
   // TODO(alancutter): Remove dependency of this function on CSSAnimations.
   // This function makes the incorrect assumption that the animation uses
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc
index f0969e51..440f70d4 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -102,7 +102,7 @@
                                        ExceptionState& exception_state) {
   Timing new_timing = source->SpecifiedTiming();
   KeyframeEffectModelBase* model = source->Model()->Clone();
-  return MakeGarbageCollected<KeyframeEffect>(source->target(), model,
+  return MakeGarbageCollected<KeyframeEffect>(source->EffectTarget(), model,
                                               new_timing, source->GetPriority(),
                                               source->GetEventDelegate());
 }
@@ -113,7 +113,7 @@
                                Priority priority,
                                EventDelegate* event_delegate)
     : AnimationEffect(timing, event_delegate),
-      target_(target),
+      effect_target_(target),
       model_(model),
       sampled_effect_(nullptr),
       priority_(priority) {
@@ -123,11 +123,11 @@
 KeyframeEffect::~KeyframeEffect() = default;
 
 void KeyframeEffect::setTarget(Element* target) {
-  if (target_ == target)
+  if (effect_target_ == target)
     return;
 
   DetachTarget(GetAnimation());
-  target_ = target;
+  effect_target_ = target;
   AttachTarget(GetAnimation());
 
   InvalidateAndNotifyOwner();
@@ -226,10 +226,11 @@
 
   // There would be no reason to composite an effect that has no target; it has
   // no visual result.
-  if (!target_) {
+  if (!effect_target_) {
     reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
   } else {
-    if (target_->GetComputedStyle() && target_->GetComputedStyle()->HasOffset())
+    if (effect_target_->GetComputedStyle() &&
+        effect_target_->GetComputedStyle()->HasOffset())
       reasons |= CompositorAnimations::kTargetHasCSSOffset;
 
     // Do not put transforms on compositor if more than one of them are defined
@@ -238,7 +239,7 @@
       reasons |= CompositorAnimations::kTargetHasMultipleTransformProperties;
 
     reasons |= CompositorAnimations::CheckCanStartAnimationOnCompositor(
-        SpecifiedTiming(), *target_, GetAnimation(), *Model(),
+        SpecifiedTiming(), *effect_target_, GetAnimation(), *Model(),
         paint_artifact_compositor, animation_playback_rate);
   }
 
@@ -259,11 +260,11 @@
     compositor_animation = GetAnimation()->GetCompositorAnimation();
 
   DCHECK(compositor_animation);
-  DCHECK(target_);
+  DCHECK(effect_target_);
   DCHECK(Model());
 
   CompositorAnimations::StartAnimationOnCompositor(
-      *target_, group, start_time, current_time, SpecifiedTiming(),
+      *effect_target_, group, start_time, current_time, SpecifiedTiming(),
       GetAnimation(), *compositor_animation, *Model(),
       compositor_keyframe_model_ids_, animation_playback_rate);
   DCHECK(!compositor_keyframe_model_ids_.IsEmpty());
@@ -282,41 +283,42 @@
     CompositorAnimation* compositor_animation) {
   if (!HasActiveAnimationsOnCompositor())
     return false;
-  if (!target_ || !target_->GetLayoutObject())
+  if (!effect_target_ || !effect_target_->GetLayoutObject())
     return false;
   for (const auto& compositor_keyframe_model_id :
        compositor_keyframe_model_ids_) {
     CompositorAnimations::CancelAnimationOnCompositor(
-        *target_, compositor_animation, compositor_keyframe_model_id);
+        *effect_target_, compositor_animation, compositor_keyframe_model_id);
   }
   compositor_keyframe_model_ids_.clear();
   return true;
 }
 
 void KeyframeEffect::CancelIncompatibleAnimationsOnCompositor() {
-  if (target_ && GetAnimation() && model_->HasFrames()) {
+  if (effect_target_ && GetAnimation() && model_->HasFrames()) {
     CompositorAnimations::CancelIncompatibleAnimationsOnCompositor(
-        *target_, *GetAnimation(), *Model());
+        *effect_target_, *GetAnimation(), *Model());
   }
 }
 
 void KeyframeEffect::PauseAnimationForTestingOnCompositor(double pause_time) {
   DCHECK(HasActiveAnimationsOnCompositor());
-  if (!target_ || !target_->GetLayoutObject())
+  if (!effect_target_ || !effect_target_->GetLayoutObject())
     return;
   DCHECK(GetAnimation());
   for (const auto& compositor_keyframe_model_id :
        compositor_keyframe_model_ids_) {
     CompositorAnimations::PauseAnimationForTestingOnCompositor(
-        *target_, *GetAnimation(), compositor_keyframe_model_id, pause_time);
+        *effect_target_, *GetAnimation(), compositor_keyframe_model_id,
+        pause_time);
   }
 }
 
 void KeyframeEffect::AttachCompositedLayers() {
-  DCHECK(target_);
+  DCHECK(effect_target_);
   DCHECK(GetAnimation());
   CompositorAnimations::AttachCompositedLayers(
-      *target_, GetAnimation()->GetCompositorAnimation());
+      *effect_target_, GetAnimation()->GetCompositorAnimation());
 }
 
 bool KeyframeEffect::HasAnimation() const {
@@ -328,7 +330,7 @@
 }
 
 void KeyframeEffect::Trace(blink::Visitor* visitor) {
-  visitor->Trace(target_);
+  visitor->Trace(effect_target_);
   visitor->Trace(model_);
   visitor->Trace(sampled_effect_);
   AnimationEffect::Trace(visitor);
@@ -381,7 +383,7 @@
 
 void KeyframeEffect::ApplyEffects() {
   DCHECK(IsInEffect());
-  if (!target_ || !model_->HasFrames())
+  if (!effect_target_ || !model_->HasFrames())
     return;
 
   if (GetAnimation() && HasIncompatibleStyle()) {
@@ -406,7 +408,8 @@
           MakeGarbageCollected<SampledEffect>(this, owner_->SequenceNumber());
       sampled_effect->MutableInterpolations().swap(interpolations);
       sampled_effect_ = sampled_effect;
-      target_->EnsureElementAnimations().GetEffectStack().Add(sampled_effect);
+      effect_target_->EnsureElementAnimations().GetEffectStack().Add(
+          sampled_effect);
       changed = true;
     } else {
       return;
@@ -414,8 +417,8 @@
   }
 
   if (changed) {
-    target_->SetNeedsAnimationStyleRecalc();
-    auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+    effect_target_->SetNeedsAnimationStyleRecalc();
+    auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
     if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
       svg_element->SetWebAnimationsPending();
   }
@@ -428,8 +431,8 @@
   sampled_effect_ = nullptr;
   if (GetAnimation())
     GetAnimation()->RestartAnimationOnCompositor();
-  target_->SetNeedsAnimationStyleRecalc();
-  auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+  effect_target_->SetNeedsAnimationStyleRecalc();
+  auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
   if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
     svg_element->ClearWebAnimatedAttributes();
   Invalidate();
@@ -456,18 +459,18 @@
 }
 
 void KeyframeEffect::AttachTarget(Animation* animation) {
-  if (!target_ || !animation)
+  if (!effect_target_ || !animation)
     return;
-  target_->EnsureElementAnimations().Animations().insert(animation);
-  target_->SetNeedsAnimationStyleRecalc();
-  auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+  effect_target_->EnsureElementAnimations().Animations().insert(animation);
+  effect_target_->SetNeedsAnimationStyleRecalc();
+  auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
   if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
     svg_element->SetWebAnimationsPending();
 }
 
 void KeyframeEffect::DetachTarget(Animation* animation) {
-  if (target_ && animation)
-    target_->GetElementAnimations()->Animations().erase(animation);
+  if (effect_target_ && animation)
+    effect_target_->GetElementAnimations()->Animations().erase(animation);
   // If we have sampled this effect previously, we need to purge that state.
   // ClearEffects takes care of clearing the cached sampled effect, informing
   // the target that it needs to refresh its style, and doing any necessary
@@ -528,11 +531,11 @@
 // and a motion path or other transform properties
 // has been introduced on the element
 bool KeyframeEffect::HasIncompatibleStyle() const {
-  if (!target_->GetComputedStyle())
+  if (!effect_target_->GetComputedStyle())
     return false;
 
   if (HasActiveAnimationsOnCompositor()) {
-    if (target_->GetComputedStyle()->HasOffset()) {
+    if (effect_target_->GetComputedStyle()->HasOffset()) {
       static const auto** properties = TransformProperties();
       for (size_t i = 0; i < num_transform_properties; i++) {
         if (Affects(PropertyHandle(*properties[i])))
@@ -546,17 +549,17 @@
 }
 
 bool KeyframeEffect::HasMultipleTransformProperties() const {
-  if (!target_->GetComputedStyle())
+  if (!effect_target_->GetComputedStyle())
     return false;
 
   unsigned transform_property_count = 0;
-  if (target_->GetComputedStyle()->HasTransformOperations())
+  if (effect_target_->GetComputedStyle()->HasTransformOperations())
     transform_property_count++;
-  if (target_->GetComputedStyle()->Rotate())
+  if (effect_target_->GetComputedStyle()->Rotate())
     transform_property_count++;
-  if (target_->GetComputedStyle()->Scale())
+  if (effect_target_->GetComputedStyle()->Scale())
     transform_property_count++;
-  if (target_->GetComputedStyle()->Translate())
+  if (effect_target_->GetComputedStyle()->Translate())
     transform_property_count++;
   return transform_property_count > 1;
 }
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.h b/third_party/blink/renderer/core/animation/keyframe_effect.h
index 423807b0..aac0325d 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -77,7 +77,7 @@
   bool IsKeyframeEffect() const override { return true; }
 
   // IDL implementation.
-  Element* target() const { return target_; }
+  Element* target() const { return effect_target_; }
   void setTarget(Element*);
   String composite() const;
   void setComposite(String);
@@ -86,6 +86,9 @@
                     const ScriptValue& keyframes,
                     ExceptionState&);
 
+  // Returns blink's representation of the effect target.
+  // This can be a blink::PseudoElement which should not be web-exposed.
+  Element* EffectTarget() const { return effect_target_; }
   void SetKeyframes(StringKeyframeVector keyframes);
 
   bool Affects(const PropertyHandle&) const;
@@ -144,7 +147,7 @@
 
   bool AnimationsPreserveAxisAlignment(const PropertyHandle&) const;
 
-  Member<Element> target_;
+  Member<Element> effect_target_;
   Member<KeyframeEffectModelBase> model_;
   Member<SampledEffect> sampled_effect_;
 
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
index da28ff97..8b00f3d 100644
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -311,6 +311,7 @@
                     "intersection_observer/intersection_observer.idl",
                     "intersection_observer/intersection_observer_entry.idl",
                     "invisible_dom/activate_invisible_event.idl",
+                    "layout/ng/custom/intrinsic_sizes.idl",
                     "layout/ng/custom/layout_constraints.idl",
                     "layout/ng/custom/layout_edges.idl",
                     "layout/ng/custom/layout_fragment.idl",
@@ -686,6 +687,7 @@
                     "intersection_observer/intersection_observer_init.idl",
                     "layout/ng/custom/custom_layout_constraints_options.idl",
                     "layout/ng/custom/fragment_result_options.idl",
+                    "layout/ng/custom/intrinsic_sizes_result_options.idl",
                     "messaging/post_message_options.idl",
                     "mojo/mojo_create_data_pipe_options.idl",
                     "mojo/mojo_create_data_pipe_result.idl",
diff --git a/third_party/blink/renderer/core/css/css_content_distribution_value.cc b/third_party/blink/renderer/core/css/css_content_distribution_value.cc
index ec16589d..e0c21b8 100644
--- a/third_party/blink/renderer/core/css/css_content_distribution_value.cc
+++ b/third_party/blink/renderer/core/css/css_content_distribution_value.cc
@@ -19,8 +19,6 @@
       position_(position),
       overflow_(overflow) {}
 
-CSSContentDistributionValue::~CSSContentDistributionValue() = default;
-
 String CSSContentDistributionValue::CustomCSSText() const {
   CSSValueList* list = CSSValueList::CreateSpaceSeparated();
 
diff --git a/third_party/blink/renderer/core/css/css_content_distribution_value.h b/third_party/blink/renderer/core/css/css_content_distribution_value.h
index 5254d95..ce32858 100644
--- a/third_party/blink/renderer/core/css/css_content_distribution_value.h
+++ b/third_party/blink/renderer/core/css/css_content_distribution_value.h
@@ -19,7 +19,6 @@
   CSSContentDistributionValue(CSSValueID distribution,
                               CSSValueID position,
                               CSSValueID overflow);
-  ~CSSContentDistributionValue();
 
   CSSValueID Distribution() const { return distribution_; }
 
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.cc b/third_party/blink/renderer/core/css/css_cursor_image_value.cc
index fd8abed8..226ba48c 100644
--- a/third_party/blink/renderer/core/css/css_cursor_image_value.cc
+++ b/third_party/blink/renderer/core/css/css_cursor_image_value.cc
@@ -38,8 +38,6 @@
   DCHECK(image_value.IsImageValue() || image_value.IsImageSetValue());
 }
 
-CSSCursorImageValue::~CSSCursorImageValue() = default;
-
 String CSSCursorImageValue::CustomCSSText() const {
   StringBuilder result;
   result.Append(image_value_->CssText());
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.h b/third_party/blink/renderer/core/css/css_cursor_image_value.h
index 14b3979..75107dcb 100644
--- a/third_party/blink/renderer/core/css/css_cursor_image_value.h
+++ b/third_party/blink/renderer/core/css/css_cursor_image_value.h
@@ -34,7 +34,6 @@
   CSSCursorImageValue(const CSSValue& image_value,
                       bool hot_spot_specified,
                       const IntPoint& hot_spot);
-  ~CSSCursorImageValue();
 
   bool HotSpotSpecified() const { return hot_spot_specified_; }
   const IntPoint& HotSpot() const { return hot_spot_; }
diff --git a/third_party/blink/renderer/core/css/css_font_face_src_value.cc b/third_party/blink/renderer/core/css/css_font_face_src_value.cc
index f63019f..9e54ebb 100644
--- a/third_party/blink/renderer/core/css/css_font_face_src_value.cc
+++ b/third_party/blink/renderer/core/css/css_font_face_src_value.cc
@@ -137,7 +137,9 @@
             fetched_->GetResource()->Options().content_security_policy_option);
   context->Fetcher()->EmulateLoadStartedForInspector(
       fetched_->GetResource(), KURL(resource_url),
-      mojom::RequestContextType::FONT, fetch_initiator_type_names::kCSS);
+      mojom::RequestContextType::FONT,
+      network::mojom::RequestDestination::kFont,
+      fetch_initiator_type_names::kCSS);
 }
 
 bool CSSFontFaceSrcValue::Equals(const CSSFontFaceSrcValue& other) const {
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc
index 2ecac6e..9df4ac3 100644
--- a/third_party/blink/renderer/core/css/css_gradient_value.cc
+++ b/third_party/blink/renderer/core/css/css_gradient_value.cc
@@ -1004,12 +1004,15 @@
 }
 
 bool CSSLinearGradientValue::Equals(const CSSLinearGradientValue& other) const {
-  if (gradient_type_ == kCSSDeprecatedLinearGradient)
-    return other.gradient_type_ == gradient_type_ &&
-           DataEquivalent(first_x_, other.first_x_) &&
+  if (gradient_type_ != other.gradient_type_)
+    return false;
+
+  if (gradient_type_ == kCSSDeprecatedLinearGradient) {
+    return DataEquivalent(first_x_, other.first_x_) &&
            DataEquivalent(first_y_, other.first_y_) &&
            DataEquivalent(second_x_, other.second_x_) &&
            DataEquivalent(second_y_, other.second_y_) && stops_ == other.stops_;
+  }
 
   if (repeating_ != other.repeating_)
     return false;
diff --git a/third_party/blink/renderer/core/css/css_layout_function_value.cc b/third_party/blink/renderer/core/css/css_layout_function_value.cc
index 4bebf888..3bc61f11 100644
--- a/third_party/blink/renderer/core/css/css_layout_function_value.cc
+++ b/third_party/blink/renderer/core/css/css_layout_function_value.cc
@@ -14,8 +14,6 @@
                                                bool is_inline)
     : CSSValue(kLayoutFunctionClass), name_(name), is_inline_(is_inline) {}
 
-CSSLayoutFunctionValue::~CSSLayoutFunctionValue() = default;
-
 String CSSLayoutFunctionValue::CustomCSSText() const {
   StringBuilder result;
   if (is_inline_)
diff --git a/third_party/blink/renderer/core/css/css_layout_function_value.h b/third_party/blink/renderer/core/css/css_layout_function_value.h
index e3dc3760..13f55aae 100644
--- a/third_party/blink/renderer/core/css/css_layout_function_value.h
+++ b/third_party/blink/renderer/core/css/css_layout_function_value.h
@@ -19,7 +19,6 @@
 class CSSLayoutFunctionValue : public CSSValue {
  public:
   CSSLayoutFunctionValue(CSSCustomIdentValue* name, bool is_inline);
-  ~CSSLayoutFunctionValue();
 
   String CustomCSSText() const;
   AtomicString GetName() const;
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 184d63ed..9beb4c6 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -360,6 +360,33 @@
       }
     },
 
+    // - is_slot: true
+    //
+    // "Slots" are used to resolve properties which cascade separately, but
+    // use the same storage on ComputedStyle. In other words, properties that
+    // are slots, have some other property (or properties) that map to them.
+    // For example, -webkit-writing-mode maps to writing-mode, and inline-size
+    // maps to either width or height.
+    //
+    // See StyleCascade::Resolver::SetSlot
+    is_slot: {
+      default: false,
+      valid_type: "bool",
+    },
+
+    // - slots: ["other-property1", "other-property2", ...]
+    //
+    // Lists the properties mapped to during StyleCascade::Apply. Note that
+    // for properties that use direction_aware_options, 'slots' should not be
+    // listed, as the mapping is determined at run-time (depending og e.g.
+    // 'direction').
+    //
+    // See also 'is_slot' flag, and StyleCascade::Resolver::SetSlot
+    slots: {
+      default: [],
+      valid_type: "list",
+    },
+
     // - priority: "High"
     // The priority level for computing the property. Valid values are
     // "Animation" (highest), "High" and "Low". Properties with the same
@@ -404,6 +431,18 @@
       default: false,
       valid_type: "bool",
     },
+
+    // - ua_property_for: "other-property"
+    //
+    // UA properties represent the style a given property would have had if
+    // no user/author styles had been applied. This is needed to theme form
+    // elements correctly.
+    //
+    // See also UAStyle.
+    ua_property_for: {
+      valid_type: "str",
+    },
+
   },
 
   // Members in the data objects should appear in the same order as in the
@@ -848,6 +887,7 @@
       name: "writing-mode",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       inherited: true,
+      is_slot: true,
       field_template: "keyword",
       include_paths: ["third_party/blink/renderer/platform/text/writing_mode.h"],
       keywords: ["horizontal-tb", "vertical-rl", "vertical-lr"],
@@ -864,6 +904,7 @@
       type_name: "WritingMode",
       style_builder_custom_functions: ["value"],
       priority: "High",
+      slots: ["writing-mode"],
     },
     {
       name: "text-rendering",
@@ -879,6 +920,7 @@
       name: "zoom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       is_descriptor: true,
+      is_slot: true,
       field_group: "visual",
       field_template: "primitive",
       default_value: "1.0",
@@ -1085,6 +1127,7 @@
     {
       name: "border-bottom-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1125,6 +1168,7 @@
     {
       name: "border-bottom-style",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "surround",
       field_template: "keyword",
       keywords: [
@@ -1138,6 +1182,7 @@
     {
       name: "border-bottom-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1162,6 +1207,7 @@
     {
       name: "border-image-outset",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+      is_slot: true,
       interpolable: true,
       typedom_types: ["Length", "Number"],
       style_builder_template: "border_image",
@@ -1172,6 +1218,7 @@
     {
       name: "border-image-repeat",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+      is_slot: true,
       keywords: ["stretch", "repeat", "round", "space"],
       typedom_types: ["Keyword"],
       style_builder_template: "border_image",
@@ -1182,6 +1229,7 @@
     {
       name: "border-image-slice",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+      is_slot: true,
       interpolable: true,
       typedom_types: ["Number", "Percentage"],
       style_builder_template: "border_image",
@@ -1192,6 +1240,7 @@
     {
       name: "border-image-source",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+      is_slot: true,
       interpolable: true,
       keywords: ["none"],
       typedom_types: ["Keyword", "Image"],
@@ -1200,6 +1249,7 @@
     {
       name: "border-image-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
+      is_slot: true,
       interpolable: true,
       keywords: ["auto"],
       typedom_types: ["Keyword", "Length", "Percentage", "Number"],
@@ -1211,6 +1261,7 @@
     {
       name: "border-left-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1227,6 +1278,7 @@
     {
       name: "border-left-style",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "surround",
       field_template: "keyword",
       keywords: [
@@ -1240,6 +1292,7 @@
     {
       name: "border-left-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1254,6 +1307,7 @@
     {
       name: "border-right-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1270,6 +1324,7 @@
     {
       name: "border-right-style",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "surround",
       field_template: "keyword",
       keywords: [
@@ -1283,6 +1338,7 @@
     {
       name: "border-right-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1297,6 +1353,7 @@
     {
       name: "border-top-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1337,6 +1394,7 @@
     {
       name: "border-top-style",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "surround",
       field_template: "keyword",
       keywords: [
@@ -1350,6 +1408,7 @@
     {
       name: "border-top-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "surround",
       field_template: "external",
@@ -1364,6 +1423,7 @@
     {
       name: "bottom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -1935,6 +1995,7 @@
       name: "height",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       is_descriptor: true,
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "box",
@@ -1992,6 +2053,7 @@
     {
       name: "intrinsic-height",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "box",
       field_template: "external",
@@ -2014,6 +2076,7 @@
     {
       name: "intrinsic-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       field_group: "box",
       field_template: "external",
@@ -2066,6 +2129,7 @@
     {
       name: "left",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2169,6 +2233,7 @@
     {
       name: "margin-bottom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2182,6 +2247,7 @@
     {
       name: "margin-left",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2195,6 +2261,7 @@
     {
       name: "margin-right",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2208,6 +2275,7 @@
     {
       name: "margin-top",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2274,6 +2342,7 @@
     {
       name: "max-height",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       is_descriptor: true,
       interpolable: true,
       field_group: "box",
@@ -2286,6 +2355,7 @@
     {
       name: "max-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       is_descriptor: true,
       interpolable: true,
       field_group: "box",
@@ -2298,6 +2368,7 @@
     {
       name: "min-height",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       is_descriptor: true,
       interpolable: true,
       field_group: "box",
@@ -2309,6 +2380,7 @@
     {
       name: "min-width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       is_descriptor: true,
       interpolable: true,
       field_group: "box",
@@ -2551,6 +2623,7 @@
     {
       name: "overflow-x",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_template: "keyword",
       keywords: [
         "visible", "hidden", "scroll", "auto", "overlay"
@@ -2562,6 +2635,7 @@
     {
       name: "overflow-y",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_template: "keyword",
       keywords: [
         "visible", "hidden", "scroll", "auto", "overlay",
@@ -2587,6 +2661,7 @@
     {
       name: "overscroll-behavior-x",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_template: "keyword",
       keywords: ["auto", "contain", "none"],
       default_value: "auto",
@@ -2596,6 +2671,7 @@
     {
       name: "overscroll-behavior-y",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_template: "keyword",
       keywords: ["auto", "contain", "none"],
       default_value: "auto",
@@ -2605,6 +2681,7 @@
     {
       name: "padding-bottom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2617,6 +2694,7 @@
     {
       name: "padding-left",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2629,6 +2707,7 @@
     {
       name: "padding-right",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2641,6 +2720,7 @@
     {
       name: "padding-top",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2751,6 +2831,7 @@
     {
       name: "right",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -2830,6 +2911,7 @@
     {
       name: "scroll-margin-bottom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "primitive",
       default_value: "0.0f",
@@ -2858,6 +2940,7 @@
     {
       name: "scroll-margin-left",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "primitive",
       default_value: "0.0f",
@@ -2868,6 +2951,7 @@
     {
       name: "scroll-margin-right",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "primitive",
       default_value: "0.0f",
@@ -2878,6 +2962,7 @@
     {
       name: "scroll-margin-top",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "primitive",
       default_value: "0.0f",
@@ -2914,6 +2999,7 @@
     {
       name: "scroll-padding-bottom",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "<length>",
       default_value: "Length()",
@@ -2950,6 +3036,7 @@
     {
       name: "scroll-padding-left",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "<length>",
       default_value: "Length()",
@@ -2960,6 +3047,7 @@
     {
       name: "scroll-padding-right",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "<length>",
       default_value: "Length()",
@@ -2970,6 +3058,7 @@
     {
       name: "scroll-padding-top",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       field_group: "*",
       field_template: "<length>",
       default_value: "Length()",
@@ -3377,6 +3466,7 @@
     {
       name: "top",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "surround",
@@ -3580,6 +3670,8 @@
       name: "-webkit-border-image",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       style_builder_custom_functions: ["value"],
+      slots: ["border-image-outset", "border-image-repeat", "border-image-slice",
+              "border-image-source", "border-image-width"]
     },
     {
       name: "-webkit-border-vertical-spacing",
@@ -4146,6 +4238,7 @@
       name: "width",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       is_descriptor: true,
+      is_slot: true,
       interpolable: true,
       layout_dependent: true,
       field_group: "box",
@@ -5237,6 +5330,7 @@
       computed_style_custom_functions: ["getter", "setter"],
       style_builder_custom_functions: ["initial", "inherit", "value"],
       priority: "High",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-caret-color",
@@ -5267,6 +5361,7 @@
       computed_style_custom_functions: ["getter","setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-background-color",
@@ -5283,11 +5378,13 @@
       style_builder_template_args: {
         initial_color: "ComputedStyleInitialValues::InitialBackgroundColor",
       },
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-border-left-color",
       visited_property_for: "border-left-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
+      is_slot: true,
       field_group: "*",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
@@ -5296,11 +5393,13 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-border-right-color",
       visited_property_for: "border-right-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
+      is_slot: true,
       field_group: "*",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
@@ -5309,11 +5408,13 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-border-top-color",
       visited_property_for: "border-top-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
+      is_slot: true,
       field_group: "*",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
@@ -5322,11 +5423,13 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-border-bottom-color",
       visited_property_for: "border-bottom-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
+      is_slot: true,
       field_group: "*",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
@@ -5335,6 +5438,7 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-border-inline-start-color",
@@ -5382,6 +5486,7 @@
       setter: "SetInternalVisitedFillPaint",
       getter: "FillPaint",
       converter: "ConvertSVGPaint",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-outline-color",
@@ -5395,6 +5500,7 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-stroke",
@@ -5406,6 +5512,7 @@
       setter: "SetInternalVisitedStrokePaint",
       getter: "StrokePaint",
       converter: "ConvertSVGPaint",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-text-decoration-color",
@@ -5419,6 +5526,7 @@
       computed_style_custom_functions: ["getter", "setter"],
       converter: "ConvertStyleColor",
       style_builder_template: "visited_color",
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-text-emphasis-color",
@@ -5436,6 +5544,7 @@
       style_builder_template_args: {
         initial_color: "StyleColor::CurrentColor",
       },
+      affected_by_forced_colors: true,
     },
     {
       name: "-internal-visited-text-fill-color",
@@ -5481,6 +5590,231 @@
       field_group: "*",
       priority: "High",
       style_builder_custom_functions: ["initial", "inherit", "value"],
+      slots: ["zoom"],
+    },
+
+    // Internal UA
+
+    {
+      name: "-internal-ua-background-attachment",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "Attachment",
+      },
+      ua_property_for: "background-attachment",
+    },
+    {
+      name: "-internal-ua-background-blend-mode",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "BlendMode",
+        fill_type_getter: "GetBlendMode",
+      },
+      ua_property_for: "background-blend-mode",
+    },
+    {
+      name: "-internal-ua-background-clip",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "Clip",
+      },
+      ua_property_for: "background-clip",
+    },
+    {
+      name: "-internal-ua-background-color",
+      name_for_methods: "BackgroundColor",
+      converter: "ConvertStyleColor",
+      style_builder_template: "color",
+      style_builder_template_args: {
+        initial_color: "ComputedStyleInitialValues::InitialBackgroundColor",
+      },
+      ua_property_for: "background-color",
+      affected_by_forced_colors: true,
+    },
+    {
+      name: "-internal-ua-background-image",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "Image",
+        fill_type_getter: "GetImage",
+      },
+      ua_property_for: "background-image",
+    },
+    {
+      name: "-internal-ua-background-origin",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "Origin",
+      },
+      ua_property_for: "background-origin",
+    },
+    {
+      name: "-internal-ua-background-position-x",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "PositionX",
+      },
+      ua_property_for: "background-position-x",
+    },
+    {
+      name: "-internal-ua-background-position-y",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "PositionY",
+      },
+      ua_property_for: "background-position-y",
+    },
+    {
+      name: "-internal-ua-background-size",
+      style_builder_template: "background_layer",
+      style_builder_template_args: {
+        fill_type: "Size",
+      },
+      ua_property_for: "background-size",
+    },
+    {
+      name: "-internal-ua-border-bottom-color",
+      name_for_methods: "BorderBottomColor",
+      converter: "ConvertStyleColor",
+      style_builder_template: "color",
+      ua_property_for: "border-bottom-color",
+      affected_by_forced_colors: true,
+    },
+    {
+      name: "-internal-ua-border-left-color",
+      name_for_methods: "BorderLeftColor",
+      converter: "ConvertStyleColor",
+      style_builder_template: "color",
+      ua_property_for: "border-left-color",
+      affected_by_forced_colors: true,
+    },
+    {
+      name: "-internal-ua-border-right-color",
+      name_for_methods: "BorderRightColor",
+      converter: "ConvertStyleColor",
+      style_builder_template: "color",
+      ua_property_for: "border-right-color",
+      affected_by_forced_colors: true,
+    },
+    {
+      name: "-internal-ua-border-top-color",
+      name_for_methods: "BorderTopColor",
+      converter: "ConvertStyleColor",
+      style_builder_template: "color",
+      ua_property_for: "border-top-color",
+      affected_by_forced_colors: true,
+    },
+    {
+      name: "-internal-ua-border-bottom-style",
+      name_for_methods: "BorderBottomStyle",
+      type_name: "EBorderStyle",
+      ua_property_for: "border-bottom-style",
+    },
+    {
+      name: "-internal-ua-border-left-style",
+      name_for_methods: "BorderLeftStyle",
+      type_name: "EBorderStyle",
+      ua_property_for: "border-left-style",
+    },
+    {
+      name: "-internal-ua-border-right-style",
+      name_for_methods: "BorderRightStyle",
+      type_name: "EBorderStyle",
+      ua_property_for: "border-right-style",
+    },
+    {
+      name: "-internal-ua-border-top-style",
+      name_for_methods: "BorderTopStyle",
+      type_name: "EBorderStyle",
+      ua_property_for: "border-top-style",
+    },
+    {
+      name: "-internal-ua-border-bottom-width",
+      name_for_methods: "BorderBottomWidth",
+      converter: "ConvertBorderWidth",
+      ua_property_for: "border-bottom-width",
+    },
+    {
+      name: "-internal-ua-border-left-width",
+      name_for_methods: "BorderLeftWidth",
+      converter: "ConvertBorderWidth",
+      ua_property_for: "border-left-width",
+    },
+    {
+      name: "-internal-ua-border-right-width",
+      name_for_methods: "BorderRightWidth",
+      converter: "ConvertBorderWidth",
+      ua_property_for: "border-right-width",
+    },
+    {
+      name: "-internal-ua-border-top-width",
+      name_for_methods: "BorderTopWidth",
+      converter: "ConvertBorderWidth",
+      ua_property_for: "border-top-width",
+    },
+    {
+      name: "-internal-ua-border-top-left-radius",
+      name_for_methods: "BorderTopLeftRadius",
+      converter: "ConvertRadius",
+      ua_property_for: "border-top-left-radius",
+    },
+    {
+      name: "-internal-ua-border-top-right-radius",
+      name_for_methods: "BorderTopRightRadius",
+      converter: "ConvertRadius",
+      ua_property_for: "border-top-right-radius",
+    },
+    {
+      name: "-internal-ua-border-bottom-left-radius",
+      name_for_methods: "BorderBottomLeftRadius",
+      converter: "ConvertRadius",
+      ua_property_for: "border-bottom-left-radius",
+    },
+    {
+      name: "-internal-ua-border-bottom-right-radius",
+      name_for_methods: "BorderBottomRightRadius",
+      converter: "ConvertRadius",
+      ua_property_for: "border-bottom-right-radius",
+    },
+    {
+      name: "-internal-ua-border-image-outset",
+      style_builder_template: "border_image",
+      style_builder_template_args: {
+        modifier_type: "Outset",
+      },
+      ua_property_for: "border-image-outset",
+    },
+    {
+      name: "-internal-ua-border-image-repeat",
+      style_builder_template: "border_image",
+      style_builder_template_args: {
+        modifier_type: "Repeat",
+      },
+      ua_property_for: "border-image-repeat",
+    },
+    {
+      name: "-internal-ua-border-image-slice",
+      style_builder_template: "border_image",
+      style_builder_template_args: {
+        modifier_type: "Slice",
+      },
+      ua_property_for: "border-image-slice",
+    },
+    {
+      name: "-internal-ua-border-image-source",
+      style_builder_template: "border_image",
+      style_builder_template_args: {
+        modifier_type: "Source",
+      },
+      ua_property_for: "border-image-source",
+    },
+    {
+      name: "-internal-ua-border-image-width",
+      style_builder_template: "border_image",
+      style_builder_template_args: {
+        modifier_type: "Width",
+      },
+      ua_property_for: "border-image-width",
     },
 
     // Aliases; these map to the same CSSPropertyID
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index 2b5940e..3eaea9b0 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -105,8 +105,6 @@
   }
 }
 
-ImmutableCSSPropertyValueSet::~ImmutableCSSPropertyValueSet() = default;
-
 // Convert property into an uint16_t for comparison with metadata's property id
 // to avoid the compiler converting it to an int multiple times in a loop.
 static uint16_t GetConvertedCSSPropertyID(CSSPropertyID property_id) {
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h
index a16b05b..1ff28a5 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.h
+++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -182,7 +182,6 @@
   ImmutableCSSPropertyValueSet(const CSSPropertyValue*,
                                unsigned count,
                                CSSParserMode);
-  ~ImmutableCSSPropertyValueSet();
 
   static ImmutableCSSPropertyValueSet*
   Create(const CSSPropertyValue* properties, unsigned count, CSSParserMode);
diff --git a/third_party/blink/renderer/core/css/document_style_sheet_collector.cc b/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
index 089bc33..3028abd 100644
--- a/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
+++ b/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
@@ -43,8 +43,6 @@
       style_sheets_for_style_sheet_list_(sheets_for_list),
       visited_documents_(visited_documents) {}
 
-DocumentStyleSheetCollector::~DocumentStyleSheetCollector() = default;
-
 void DocumentStyleSheetCollector::AppendActiveStyleSheet(
     const ActiveStyleSheet& sheet) {
   DCHECK(collection_);
diff --git a/third_party/blink/renderer/core/css/document_style_sheet_collector.h b/third_party/blink/renderer/core/css/document_style_sheet_collector.h
index 7bd33f73..6bc8e30 100644
--- a/third_party/blink/renderer/core/css/document_style_sheet_collector.h
+++ b/third_party/blink/renderer/core/css/document_style_sheet_collector.h
@@ -50,7 +50,6 @@
   DocumentStyleSheetCollector(StyleSheetCollection*,
                               HeapVector<Member<StyleSheet>>*,
                               HeapHashSet<Member<Document>>*);
-  ~DocumentStyleSheetCollector();
 
   void AppendActiveStyleSheet(const ActiveStyleSheet&);
   void AppendSheetForList(StyleSheet*);
diff --git a/third_party/blink/renderer/core/css/properties/css_property.h b/third_party/blink/renderer/core/css/properties/css_property.h
index bb1cf89f5..c91d2ee 100644
--- a/third_party/blink/renderer/core/css/properties/css_property.h
+++ b/third_party/blink/renderer/core/css/properties/css_property.h
@@ -85,6 +85,9 @@
   }
   virtual const CSSProperty* GetVisitedProperty() const { return nullptr; }
   virtual const CSSProperty* GetUnvisitedProperty() const { return nullptr; }
+
+  virtual const CSSProperty* GetUAProperty() const { return nullptr; }
+
   static void FilterWebExposedCSSPropertiesIntoVector(
       const CSSPropertyID*,
       size_t length,
@@ -104,7 +107,12 @@
     // seen by CSSOM, which is represented by the unvisited property).
     kVisited = 1 << 7,
     kInternal = 1 << 8,
-    kIsAffectedByForcedColors = 1 << 9
+    kIsAffectedByForcedColors = 1 << 9,
+    // A UA property represents a property as styled by the user-agent.
+    // For example, -internal-ua-background-color contains the value
+    // 'background-color' would have had without any user or author
+    // declarations.
+    kUA = 1 << 10,
   };
 
   constexpr CSSProperty(CSSPropertyID property_id,
diff --git a/third_party/blink/renderer/core/css/resolver/match_result.cc b/third_party/blink/renderer/core/css/resolver/match_result.cc
index 4391044..6ef3dd5 100644
--- a/third_party/blink/renderer/core/css/resolver/match_result.cc
+++ b/third_party/blink/renderer/core/css/resolver/match_result.cc
@@ -43,8 +43,6 @@
   memset(&types_, 0, sizeof(types_));
 }
 
-MatchedProperties::~MatchedProperties() = default;
-
 void MatchedProperties::Trace(blink::Visitor* visitor) {
   visitor->Trace(properties);
 }
diff --git a/third_party/blink/renderer/core/css/resolver/match_result.h b/third_party/blink/renderer/core/css/resolver/match_result.h
index 2a6f8ad..b7e93c1 100644
--- a/third_party/blink/renderer/core/css/resolver/match_result.h
+++ b/third_party/blink/renderer/core/css/resolver/match_result.h
@@ -40,7 +40,6 @@
 
  public:
   MatchedProperties();
-  ~MatchedProperties();
 
   void Trace(blink::Visitor*);
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
index fa4726bf..2ae6f19 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/css/resolver/css_property_priority.h"
 #include "third_party/blink/renderer/core/css/resolver/style_builder.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/css/style_cascade_slots.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
@@ -119,12 +120,27 @@
 }
 
 void StyleCascade::Apply(Animator& animator) {
-  Resolver resolver(animator, excluder_);
+  StyleCascadeSlots slots;
+  Resolver resolver(animator, excluder_, slots);
+
+  // The computed value of -webkit-appearance decides whether we need to
+  // apply -internal-ua properties or not.
+  ApplyAppearance(resolver);
 
   // Affects the computed value of 'color', hence needs to happen before
   // high-priority properties.
   Apply(GetCSSPropertyColorScheme(), resolver);
 
+  // -webkit-border-image is a longhand that maps to the same slots used by
+  // border-image (shorthand). By applying -webkit-border-image first, we
+  // avoid having to "partially" apply -webkit-border-image depending on the
+  // border-image-* longhands that have already been applied.
+  Apply(GetCSSPropertyWebkitBorderImage(), resolver);
+
+  // -webkit-mask-image needs to be applied before -webkit-mask-composite,
+  // otherwise -webkit-mask-composite has no effect.
+  Apply(GetCSSPropertyWebkitMaskImage(), resolver);
+
   // TODO(crbug.com/985031): Set bits ::Add-time to know if we need to do this.
   ApplyHighPriority(resolver);
 
@@ -199,9 +215,16 @@
   state_.SetConversionZoom(state_.Style()->EffectiveZoom());
 }
 
+void StyleCascade::ApplyAppearance(Resolver& resolver) {
+  Apply(GetCSSPropertyWebkitAppearance(), resolver);
+  if (!state_.Style()->HasAppearance())
+    Exclude(CSSProperty::kUA, true);
+}
+
 void StyleCascade::Apply(const CSSPropertyName& name) {
   NullAnimator animator;
-  Resolver resolver(animator, excluder_);
+  StyleCascadeSlots slots;
+  Resolver resolver(animator, excluder_, slots);
   Apply(name, resolver);
 }
 
@@ -236,7 +259,7 @@
   DCHECK(!value->IsPendingSubstitutionValue());
   DCHECK(!value->IsPendingInterpolationValue());
 
-  if (!resolver.filter_.Add(property, cascaded))
+  if (!resolver.SetSlot(property, cascaded, state_))
     return;
 
   StyleBuilder::ApplyProperty(property, state_, *value);
@@ -599,32 +622,6 @@
   state_.GetDocument().GetPropertyRegistry()->MarkReferenced(name);
 }
 
-bool StyleCascade::Filter::Add(const CSSProperty& property,
-                               const Value& value) {
-  Priority& slot = GetSlot(property);
-  if (value.GetPriority() >= slot) {
-    slot = value.GetPriority();
-    return true;
-  }
-  return false;
-}
-
-StyleCascade::Priority& StyleCascade::Filter::GetSlot(
-    const CSSProperty& property) {
-  // TODO(crbug.com/985043): Ribbonize?
-  switch (property.PropertyID()) {
-    case CSSPropertyID::kWritingMode:
-    case CSSPropertyID::kWebkitWritingMode:
-      return writing_mode_;
-    case CSSPropertyID::kZoom:
-    case CSSPropertyID::kInternalEffectiveZoom:
-      return zoom_;
-    default:
-      none_ = Priority();
-      return none_;
-  }
-}
-
 bool StyleCascade::Resolver::IsLocked(const CSSProperty& property) const {
   return IsLocked(property.GetCSSPropertyName());
 }
@@ -644,6 +641,12 @@
   return true;
 }
 
+bool StyleCascade::Resolver::SetSlot(const CSSProperty& property,
+                                     const Value& value,
+                                     StyleResolverState& state) {
+  return slots_.Set(property, value.GetPriority(), state);
+}
+
 bool StyleCascade::Resolver::DetectCycle(const CSSProperty& property) {
   wtf_size_t index = stack_.Find(property.GetCSSPropertyName());
   if (index == kNotFound)
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.h b/third_party/blink/renderer/core/css/resolver/style_cascade.h
index 3e1a43d..032ad35f 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade.h
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -22,6 +22,7 @@
 class CSSVariableData;
 class CSSVariableReferenceValue;
 class CustomProperty;
+class StyleCascadeSlots;
 class StyleResolverState;
 
 namespace cssvalue {
@@ -111,10 +112,15 @@
 
     Origin GetOrigin() const;
     bool HasOrigin() const { return GetOrigin() != Origin::kNone; }
+    bool HasUAOrigin() const {
+      return GetOrigin() == Origin::kUserAgent ||
+             GetOrigin() == Origin::kImportantUserAgent;
+    }
 
     // This function is used to determine if an incoming Value should win
     // over the Value which already exists in the cascade.
     bool operator>=(const Priority&) const;
+    bool operator<(const Priority& p) const { return !(*this >= p); }
 
     // Returns a copy of this Priority, except that the non-important origin
     // has been converted to its important counterpart.
@@ -242,55 +248,6 @@
   // TODO(crbug.com/985010): Improve with non-destructive Apply.
   void RemoveAnimationPriority();
 
-  // The Filter class is responsible for resolving situations where
-  // we have multiple (non-alias) properties in the cascade that mutates the
-  // same fields on ComputedStyle.
-  //
-  // An example of this is writing-mode and -webkit-writing-mode, which
-  // both result in ComputedStyle::SetWritingMode calls.
-  //
-  // When applying the cascade (applying each property/value pair to the
-  // ComputedStyle), the order of the application is in the general case
-  // not defined. (It is determined by the iteration order of the HashMap).
-  // This means that if both writing-mode and -webkit-writing-mode exist in
-  // the cascade, we would get non-deterministic behavior: the application order
-  // would not be defined. To fix this, all Values pass through this Filter
-  // before being applied.
-
-  // The Filter stores the Priority of the Value that was previously applied
-  // for a certain 'group' of properties (writing_mode_ is one such group).
-  // When we're about to apply a Value, we only actually do so if the call  to
-  // Filter::Add succeeds. If the call to Filter::Add does not succeed, it means
-  // that we  have previously added a Value with higher Priority, and that the
-  // current  Value must be ignored.
-
-  // A key difference between discarding Values in the Filter, vs. discarding
-  // them cascade-time (StyleCascade::Add), is that we are taking the cascade
-  // order into account. This means that, if everything else is equal (origin,
-  // tree order), the Value that entered the cascade last wins. This is crucial
-  // to resolve situations like writing-mode and -webkit-writing-mode.
-
-  // The Filter is also expected to resolve similar difficulties with
-  // direction-aware properties in the future, although this is not yet
-  // implemented.
-  class CORE_EXPORT Filter {
-    STACK_ALLOCATED();
-
-   public:
-    // Attempts to add a given property/value to the Filter. If this returns
-    // true, the Value may be applied to the ComputedStyle. If not, it means
-    // that we have previously applied a Value with higher Priority, and the
-    // current Value must be discarded.
-    bool Add(const CSSProperty& property, const Value&);
-
-   private:
-    Priority& GetSlot(const CSSProperty&);
-
-    Priority none_;
-    Priority writing_mode_;
-    Priority zoom_;
-  };
-
   // Resolver is an object passed on a stack during Apply. Its most important
   // job is to detect cycles during Apply (in general, keep track of which
   // properties we're currently applying).
@@ -313,13 +270,42 @@
     // https://drafts.csswg.org/css-variables/#animation-tainted
     bool AllowSubstitution(CSSVariableData*) const;
 
+    // SetSlot/StyleCascadeSlots is responsible for resolving situations where
+    // we have multiple (non-alias) properties in the cascade that mutates the
+    // same fields on ComputedStyle.
+    //
+    // An example of this is writing-mode and -webkit-writing-mode, which
+    // both result in ComputedStyle::SetWritingMode calls.
+    //
+    // When applying the cascade (applying each property/value pair to the
+    // ComputedStyle), the order of the application is in the general case
+    // not defined. (It is determined by the iteration order of the HashMap).
+    // This means that if both writing-mode and -webkit-writing-mode exist in
+    // the cascade, we would get non-deterministic behavior: the application
+    // order would not be defined. SetSlot/StyleCascadeSlots fixes this.
+    //
+    // StyleCascadeSlots stores the Priority of the value that was previously
+    // applied for a certain 'group' of properties (e.g. writing-mode and
+    // -webkit-writing-mode is one such group). When we're about to apply a
+    // value, we only actually do so if the call to SetSlot succeeds. If the
+    // call to SetSlot does not succeed, it means that we have previously added
+    // a value with higher priority, and that the current value must be ignored.
+    //
+    // A key difference between discarding Values as a result of SetSlot, vs.
+    // discarding them cascade-time (StyleCascade::Add), is that we are taking
+    // the cascade order into account. This means that, if everything else is
+    // equal (origin, tree order), the value that entered the cascade last wins.
+    // This is crucial to resolve situations like writing-mode and
+    // -webkit-writing-mode.
+    bool SetSlot(const CSSProperty&, const Value&, StyleResolverState&);
+
    private:
     friend class AutoLock;
     friend class StyleCascade;
     friend class TestCascadeResolver;
 
-    Resolver(Animator& animator, const Excluder& excluder)
-        : animator_(animator), excluder_(excluder) {}
+    Resolver(Animator& animator, Excluder& excluder, StyleCascadeSlots& slots)
+        : animator_(animator), excluder_(excluder), slots_(slots) {}
     // If the given property is already being applied, returns true.
     // The return value is the same value you would get from InCycle(), and
     // is just returned for convenience.
@@ -338,8 +324,8 @@
     NameStack stack_;
     Animator& animator_;
     wtf_size_t cycle_depth_ = kNotFound;
-    Filter filter_;
     const Excluder& excluder_;
+    StyleCascadeSlots& slots_;
   };
 
   // Automatically locks and unlocks the given property. (See
@@ -410,6 +396,10 @@
   // we apply font-affecting properties (among others) before all the others.
   void ApplyHighPriority(Resolver&);
 
+  // Applies -webkit-appearance, and excludes -internal-ua-* properties if
+  // we don't have an appearance.
+  void ApplyAppearance(Resolver&);
+
   // Apply a single property (including any dependencies).
   void Apply(const CSSPropertyName&);
   void Apply(const CSSPropertyName&, Resolver&);
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
index dbaef75..db2c9d0 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h"
 #include "third_party/blink/renderer/core/css/resolver/style_animator.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
+#include "third_party/blink/renderer/core/css/style_cascade_slots.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
@@ -97,6 +98,11 @@
            Priority priority = Origin::kAuthor) {
     DCHECK(CSSPropertyRef(name, GetDocument()).GetProperty().IsLonghand());
     cascade_.Add(name, value, priority);
+    if (priority.HasUAOrigin()) {
+      const CSSProperty* ua = CSSProperty::Get(name.Id()).GetUAProperty();
+      if (ua)
+        cascade_.Add(ua->GetCSSPropertyName(), value, priority);
+    }
   }
 
   void Apply(const CSSPropertyName& name) { cascade_.Apply(name); }
@@ -243,7 +249,7 @@
 
  public:
   TestCascadeResolver(Document& document, StyleAnimator& animator)
-      : document_(&document), resolver_(animator, excluder_) {}
+      : document_(&document), resolver_(animator, excluder_, slots_) {}
   bool InCycle() const { return resolver_.InCycle(); }
   bool DetectCycle(String name) {
     CSSPropertyRef ref(name, *document_);
@@ -257,6 +263,7 @@
   friend class TestCascadeAutoLock;
 
   Member<Document> document_;
+  StyleCascadeSlots slots_;
   StyleCascade::Excluder excluder_;
   StyleCascade::Resolver resolver_;
 };
@@ -1905,6 +1912,130 @@
   EXPECT_EQ("vertical-lr", cascade.ComputedValue("-webkit-writing-mode"));
 }
 
+TEST_F(StyleCascadeTest, WebkitBorderImageCascadeOrder) {
+  String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
+  String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
+
+  TestCascade cascade(GetDocument());
+  cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+              Origin::kAuthor);
+  cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+  cascade.Add("border-image-slice", "20", Origin::kAuthor);
+  cascade.Add("border-image-width", "6px", Origin::kAuthor);
+  cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+  cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+  cascade.Apply();
+
+  EXPECT_EQ(gradient2, cascade.ComputedValue("border-image-source"));
+  EXPECT_EQ("20", cascade.ComputedValue("border-image-slice"));
+  EXPECT_EQ("6px", cascade.ComputedValue("border-image-width"));
+  EXPECT_EQ("4px", cascade.ComputedValue("border-image-outset"));
+  EXPECT_EQ("space", cascade.ComputedValue("border-image-repeat"));
+}
+
+TEST_F(StyleCascadeTest, WebkitBorderImageReverseCascadeOrder) {
+  String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
+  String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
+
+  TestCascade cascade(GetDocument());
+  cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+  cascade.Add("border-image-slice", "20", Origin::kAuthor);
+  cascade.Add("border-image-width", "6px", Origin::kAuthor);
+  cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+  cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+  cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+              Origin::kAuthor);
+  cascade.Apply();
+
+  EXPECT_EQ(gradient1, cascade.ComputedValue("border-image-source"));
+  EXPECT_EQ("40 fill", cascade.ComputedValue("border-image-slice"));
+  EXPECT_EQ("10px", cascade.ComputedValue("border-image-width"));
+  EXPECT_EQ("20px", cascade.ComputedValue("border-image-outset"));
+  EXPECT_EQ("round", cascade.ComputedValue("border-image-repeat"));
+}
+
+TEST_F(StyleCascadeTest, WebkitBorderImageMixedOrder) {
+  String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
+  String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
+
+  TestCascade cascade(GetDocument());
+  cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+  cascade.Add("border-image-width", "6px", Origin::kAuthor);
+  cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+              Origin::kAuthor);
+  cascade.Add("border-image-slice", "20", Origin::kAuthor);
+  cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+  cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+  cascade.Apply();
+
+  EXPECT_EQ(gradient1, cascade.ComputedValue("border-image-source"));
+  EXPECT_EQ("20", cascade.ComputedValue("border-image-slice"));
+  EXPECT_EQ("10px", cascade.ComputedValue("border-image-width"));
+  EXPECT_EQ("4px", cascade.ComputedValue("border-image-outset"));
+  EXPECT_EQ("space", cascade.ComputedValue("border-image-repeat"));
+}
+
+TEST_F(StyleCascadeTest, AllLogicalPropertiesSlot) {
+  using Origin = StyleCascade::Origin;
+
+  TestCascade cascade(GetDocument());
+
+  static const TextDirection directions[] = {TextDirection::kLtr,
+                                             TextDirection::kRtl};
+
+  static const WritingMode modes[] = {WritingMode::kHorizontalTb,
+                                      WritingMode::kVerticalRl,
+                                      WritingMode::kVerticalLr};
+
+  for (CSSPropertyID id : CSSPropertyIDList()) {
+    const CSSProperty& property = CSSProperty::Get(id);
+
+    if (!property.IsLonghand())
+      continue;
+
+    for (TextDirection direction : directions) {
+      for (WritingMode mode : modes) {
+        const CSSProperty& physical =
+            property.ResolveDirectionAwareProperty(direction, mode);
+        if (&property == &physical)
+          continue;
+
+        auto& state = cascade.State();
+        state.Style()->SetDirection(direction);
+        state.Style()->SetWritingMode(mode);
+
+        // Set logical first.
+        {
+          StyleCascadeSlots slots;
+          EXPECT_TRUE(slots.Set(property, Origin::kAuthor, state));
+          EXPECT_FALSE(slots.Set(physical, Origin::kUserAgent, state));
+        }
+
+        // Set physical first.
+        {
+          StyleCascadeSlots slots;
+          EXPECT_TRUE(slots.Set(physical, Origin::kAuthor, state));
+          EXPECT_FALSE(slots.Set(property, Origin::kUserAgent, state));
+        }
+
+        // Set logical twice.
+        {
+          StyleCascadeSlots slots;
+          EXPECT_TRUE(slots.Set(property, Origin::kAuthor, state));
+          EXPECT_FALSE(slots.Set(property, Origin::kUserAgent, state));
+        }
+
+        // Set physical twice.
+        {
+          StyleCascadeSlots slots;
+          EXPECT_TRUE(slots.Set(physical, Origin::kAuthor, state));
+          EXPECT_FALSE(slots.Set(physical, Origin::kUserAgent, state));
+        }
+      }
+    }
+  }
+}
+
 TEST_F(StyleCascadeTest, MarkReferenced) {
   RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
   RegisterProperty(GetDocument(), "--y", "<length>", "0px", false);
@@ -2073,4 +2204,384 @@
   EXPECT_EQ("block", cascade.ComputedValue("display"));
 }
 
+TEST_F(StyleCascadeTest, UAStyleAbsentWithoutAppearance) {
+  TestCascade cascade(GetDocument());
+  cascade.Add("background-color", "red", Origin::kUserAgent);
+  cascade.Add("border-right-color", "red", Origin::kUserAgent);
+  cascade.Apply();
+  EXPECT_FALSE(cascade.State().GetUAStyle());
+}
+
+TEST_F(StyleCascadeTest, UAStylePresentWithAppearance) {
+  TestCascade cascade(GetDocument());
+  cascade.Add("-webkit-appearance", "button");
+  cascade.Add("background-color", "red", Origin::kUserAgent);
+  cascade.Apply();
+  EXPECT_TRUE(cascade.State().GetUAStyle());
+}
+
+TEST_F(StyleCascadeTest, UAStyleNoDiffBackground) {
+  TestCascade cascade(GetDocument());
+  cascade.Add("-webkit-appearance", "button");
+  cascade.Add("background-attachment", "fixed", Origin::kUserAgent);
+  cascade.Add("background-blend-mode", "darken", Origin::kUserAgent);
+  cascade.Add("background-clip", "padding-box", Origin::kUserAgent);
+  cascade.Add("background-image", "none", Origin::kUserAgent);
+  cascade.Add("background-origin", "content-box", Origin::kUserAgent);
+  cascade.Add("background-position-x", "10px", Origin::kUserAgent);
+  cascade.Add("background-position-y", "10px", Origin::kUserAgent);
+  cascade.Add("background-size", "contain", Origin::kUserAgent);
+  cascade.Apply();
+  ASSERT_TRUE(cascade.State().GetUAStyle());
+  EXPECT_FALSE(cascade.State().GetUAStyle()->HasDifferentBackground(
+      cascade.State().StyleRef()));
+}
+
+TEST_F(StyleCascadeTest, UAStyleDiffBackground) {
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(red, green)",
+                Origin::kUserAgent);
+    cascade.Add("background-attachment", "fixed", Origin::kUserAgent);
+    cascade.Add("background-attachment", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(red, green)",
+                Origin::kUserAgent);
+    cascade.Add("background-blend-mode", "darken", Origin::kUserAgent);
+    cascade.Add("background-blend-mode", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(red, green)",
+                Origin::kUserAgent);
+    cascade.Add("background-clip", "padding-box", Origin::kUserAgent);
+    cascade.Add("background-clip", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(green, red)",
+                Origin::kUserAgent);
+    cascade.Add("background-image", "linear-gradient(red, green)",
+                Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(green, red)",
+                Origin::kUserAgent);
+    cascade.Add("background-origin", "content-box", Origin::kUserAgent);
+    cascade.Add("background-origin", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(green, red)",
+                Origin::kUserAgent);
+    cascade.Add("background-position-x", "10px", Origin::kUserAgent);
+    cascade.Add("background-position-x", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(green, red)",
+                Origin::kUserAgent);
+    cascade.Add("background-position-y", "10px", Origin::kUserAgent);
+    cascade.Add("background-position-y", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("background-image", "linear-gradient(green, red)",
+                Origin::kUserAgent);
+    cascade.Add("background-size", "contain", Origin::kUserAgent);
+    cascade.Add("background-size", "unset", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBackground(
+        cascade.State().StyleRef()));
+  }
+}
+
+TEST_F(StyleCascadeTest, UAStyleBorderNoDifference) {
+  TestCascade cascade(GetDocument());
+  cascade.Add("-webkit-appearance", "button");
+  cascade.Add("border-top-color", "red", Origin::kUserAgent);
+  cascade.Add("border-right-color", "red", Origin::kUserAgent);
+  cascade.Add("border-bottom-color", "red", Origin::kUserAgent);
+  cascade.Add("border-left-color", "red", Origin::kUserAgent);
+  cascade.Add("border-top-style", "dashed", Origin::kUserAgent);
+  cascade.Add("border-right-style", "dashed", Origin::kUserAgent);
+  cascade.Add("border-bottom-style", "dashed", Origin::kUserAgent);
+  cascade.Add("border-left-style", "dashed", Origin::kUserAgent);
+  cascade.Add("border-top-width", "5px", Origin::kUserAgent);
+  cascade.Add("border-right-width", "5px", Origin::kUserAgent);
+  cascade.Add("border-bottom-width", "5px", Origin::kUserAgent);
+  cascade.Add("border-left-width", "5px", Origin::kUserAgent);
+  cascade.Add("border-top-left-radius", "5px", Origin::kUserAgent);
+  cascade.Add("border-top-right-radius", "5px", Origin::kUserAgent);
+  cascade.Add("border-bottom-left-radius", "5px", Origin::kUserAgent);
+  cascade.Add("border-bottom-right-radius", "5px", Origin::kUserAgent);
+  cascade.Add("border-image-source", "none", Origin::kUserAgent);
+  cascade.Add("border-image-slice", "30", Origin::kUserAgent);
+  cascade.Add("border-image-width", "10px", Origin::kUserAgent);
+  cascade.Add("border-image-outset", "15px", Origin::kUserAgent);
+  cascade.Add("border-image-repeat", "round", Origin::kUserAgent);
+  cascade.Apply();
+  ASSERT_TRUE(cascade.State().GetUAStyle());
+  EXPECT_FALSE(cascade.State().GetUAStyle()->HasDifferentBorder(
+      cascade.State().StyleRef()));
+}
+
+TEST_F(StyleCascadeTest, UAStyleBorderDifference) {
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-top-color", "red", Origin::kUserAgent);
+    cascade.Add("border-top-color", "green", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-right-color", "red", Origin::kUserAgent);
+    cascade.Add("border-right-color", "green", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-bottom-color", "red", Origin::kUserAgent);
+    cascade.Add("border-bottom-color", "green", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-left-color", "red", Origin::kUserAgent);
+    cascade.Add("border-left-color", "green", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-top-style", "dashed", Origin::kUserAgent);
+    cascade.Add("border-top-style", "solid", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-right-style", "dashed", Origin::kUserAgent);
+    cascade.Add("border-right-style", "solid", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-bottom-style", "dashed", Origin::kUserAgent);
+    cascade.Add("border-bottom-style", "solid", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-left-style", "dashed", Origin::kUserAgent);
+    cascade.Add("border-left-style", "solid", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-top-style", "solid", Origin::kUserAgent);
+    cascade.Add("border-top-width", "10px", Origin::kUserAgent);
+    cascade.Add("border-top-width", "9px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-right-style", "solid", Origin::kUserAgent);
+    cascade.Add("border-right-width", "10px", Origin::kUserAgent);
+    cascade.Add("border-right-width", "9px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-bottom-style", "solid", Origin::kUserAgent);
+    cascade.Add("border-bottom-width", "10px", Origin::kUserAgent);
+    cascade.Add("border-bottom-width", "9px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-left-style", "solid", Origin::kUserAgent);
+    cascade.Add("border-left-width", "10px", Origin::kUserAgent);
+    cascade.Add("border-left-width", "9px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-top-left-radius", "5px", Origin::kUserAgent);
+    cascade.Add("border-top-left-radius", "2px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-top-right-radius", "5px", Origin::kUserAgent);
+    cascade.Add("border-top-right-radius", "2px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-bottom-left-radius", "5px", Origin::kUserAgent);
+    cascade.Add("border-bottom-left-radius", "2px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-bottom-right-radius", "5px", Origin::kUserAgent);
+    cascade.Add("border-bottom-right-radius", "2px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-image-source", "none", Origin::kUserAgent);
+    cascade.Add("border-image-source", "linear-gradient(red, green)",
+                Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-image-slice", "30", Origin::kUserAgent);
+    cascade.Add("border-image-slice", "10", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-image-width", "10px", Origin::kUserAgent);
+    cascade.Add("border-image-width", "15px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-image-outset", "10px", Origin::kUserAgent);
+    cascade.Add("border-image-outset", "15px", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+  {
+    TestCascade cascade(GetDocument());
+    cascade.Add("-webkit-appearance", "button");
+    cascade.Add("border-image-repeat", "round", Origin::kUserAgent);
+    cascade.Add("border-image-repeat", "stretch", Origin::kAuthor);
+    cascade.Apply();
+    ASSERT_TRUE(cascade.State().GetUAStyle());
+    EXPECT_TRUE(cascade.State().GetUAStyle()->HasDifferentBorder(
+        cascade.State().StyleRef()));
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 149f2df95..ce5c4dc7 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -981,9 +981,18 @@
     // but that would use a slow universal element selector. So instead we apply
     // the styles here as an optimization.
     if (pseudo_style_request.pseudo_id == kPseudoIdMarker) {
+      // Set 'unicode-bidi: isolate'
       state.Style()->SetUnicodeBidi(UnicodeBidi::kIsolate);
-      state.Style()->SetFontVariantNumericSpacing(
-          FontVariantNumeric::kTabularNums);
+
+      // Set 'font-variant-numeric: tabular-nums'
+      FontVariantNumeric variant_numeric;
+      variant_numeric.SetNumericSpacing(FontVariantNumeric::kTabularNums);
+      state.GetFontBuilder().SetVariantNumeric(variant_numeric);
+      UpdateFont(state);
+
+      // Don't bother matching rules if there is no style for ::marker
+      if (!state.ParentStyle()->HasPseudoElementStyle(kPseudoIdMarker))
+        return true;
     }
 
     MatchUARules(collector);
@@ -1262,6 +1271,8 @@
     StyleAnimator animator(state, cascade);
     CascadeInterpolations(cascade, animations_map, Origin::kAnimation);
     CascadeInterpolations(cascade, transitions_map, Origin::kTransition);
+    if (IsForcedColorsModeEnabled(state))
+      cascade.Exclude(CSSProperty::kIsAffectedByForcedColors, true);
     cascade.Apply(animator);
   } else {
     ApplyAnimatedStandardProperties<kHighPropertyPriority>(state,
@@ -1900,6 +1911,21 @@
                       cache_hash, cached_matched_properties);
 }
 
+void StyleResolver::MaybeAddToMatchedPropertiesCache(
+    StyleResolverState& state,
+    const CacheSuccess& cache_success,
+    const MatchResult& match_result) {
+  if (!state.IsAnimatingCustomProperties() &&
+      !cache_success.cached_matched_properties && cache_success.cache_hash &&
+      MatchedPropertiesCache::IsCacheable(state)) {
+    INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
+                                  matched_property_cache_added, 1);
+    matched_properties_cache_.Add(*state.Style(), *state.ParentStyle(),
+                                  cache_success.cache_hash,
+                                  match_result.GetMatchedProperties());
+  }
+}
+
 void StyleResolver::ApplyCustomProperties(StyleResolverState& state,
                                           const MatchResult& match_result,
                                           const CacheSuccess& cache_success,
@@ -2072,16 +2098,7 @@
   }
 
   LoadPendingResources(state);
-
-  if (!state.IsAnimatingCustomProperties() &&
-      !cache_success.cached_matched_properties && cache_success.cache_hash &&
-      MatchedPropertiesCache::IsCacheable(state)) {
-    INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
-                                  matched_property_cache_added, 1);
-    matched_properties_cache_.Add(*state.Style(), *state.ParentStyle(),
-                                  cache_success.cache_hash,
-                                  match_result.GetMatchedProperties());
-  }
+  MaybeAddToMatchedPropertiesCache(state, cache_success, match_result);
 
   DCHECK(!state.GetFontBuilder().FontDirty());
 }
@@ -2174,23 +2191,27 @@
     }
   }
 
+  // TODO(crbug.com/985025): We only support full cache hits for now.
+  //
+  // The matched properties cache supports partial hits (see
+  // CacheSuccess::ShouldApplyInheritedOnly), but the StyleCascade path does
+  // not support this yet.
   if (cache_success.IsFullCacheHit())
     return;
 
-  // TODO(crbug.com/985025): We only support full cache hits for now.
-  bool apply_inherited_only = false;
+  CascadeAndApplyForcedColors(state, match_result);
 
-  // TODO(crbug.com/985027): Cascade kLowPropertyPriority.
-  //
-  // Ultimately NeedsApplyPass will be removed, so we don't bother fixing
-  // that for this codepath. For now, just always go through the low-priority
-  // properties.
-  const bool important = true;
-  NeedsApplyPass needs_apply_pass;
-  needs_apply_pass.Set(kLowPropertyPriority, important);
-  needs_apply_pass.Set(kLowPropertyPriority, !important);
-  ApplyMatchedLowPriorityProperties(state, match_result, cache_success,
-                                    apply_inherited_only, needs_apply_pass);
+  if (const UAStyle* ua_style = state.GetUAStyle()) {
+    state.Style()->SetHasAuthorBackground(
+        ua_style->HasDifferentBackground(state.StyleRef()));
+    state.Style()->SetHasAuthorBorder(
+        ua_style->HasDifferentBorder(state.StyleRef()));
+  }
+
+  LoadPendingResources(state);
+  MaybeAddToMatchedPropertiesCache(state, cache_success, match_result);
+
+  DCHECK(!state.GetFontBuilder().FontDirty());
 }
 
 static void CascadeDeclaration(StyleCascade& cascade,
@@ -2206,6 +2227,10 @@
     if (visited)
       cascade.Add(visited->GetCSSPropertyName(), &value, priority);
   }
+  if (priority.HasUAOrigin()) {
+    if (const CSSProperty* ua = CSSProperty::Get(name.Id()).GetUAProperty())
+      cascade.Add(ua->GetCSSPropertyName(), &value, priority);
+  }
 }
 
 // https://drafts.csswg.org/css-cascade/#all-shorthand
@@ -2216,10 +2241,6 @@
                        ValidPropertyFilter filter,
                        const CSSValue& value) {
   for (CSSPropertyID property_id : CSSPropertyIDList()) {
-    using LowPrioData = CSSPropertyPriorityData<kLowPropertyPriority>;
-    if (LowPrioData::PropertyHasPriority(property_id))
-      continue;
-
     const CSSProperty& property = CSSProperty::Get(property_id);
 
     if (property.IsShorthand())
@@ -2278,10 +2299,6 @@
         continue;
       }
 
-      using LowPrioData = CSSPropertyPriorityData<kLowPropertyPriority>;
-      if (LowPrioData::PropertyHasPriority(property_id))
-        continue;
-
       if (!PassesPropertyFilter(filter, property_id, state.GetDocument()))
         continue;
 
@@ -2321,6 +2338,58 @@
   }
 }
 
+void StyleResolver::CascadeAndApplyForcedColors(StyleResolverState& state,
+                                                const MatchResult& result) {
+  if (!IsForcedColorsModeEnabled())
+    return;
+  if (state.Style()->ForcedColorAdjust() == EForcedColorAdjust::kNone)
+    return;
+
+  unsigned apply_mask = kApplyMaskRegular | kApplyMaskVisited;
+  const CSSValue* unset = cssvalue::CSSUnsetValue::Create();
+  auto origin = StyleCascade::Origin::kUserAgent;
+
+  static const CSSProperty* properties[] = {
+      &GetCSSPropertyColor(),
+      &GetCSSPropertyBorderBottomColor(),
+      &GetCSSPropertyBorderLeftColor(),
+      &GetCSSPropertyBorderRightColor(),
+      &GetCSSPropertyBorderTopColor(),
+      &GetCSSPropertyBoxShadow(),
+      &GetCSSPropertyColumnRuleColor(),
+      &GetCSSPropertyFill(),
+      &GetCSSPropertyOutlineColor(),
+      &GetCSSPropertyStroke(),
+      &GetCSSPropertyTextDecorationColor(),
+      &GetCSSPropertyTextShadow(),
+      &GetCSSPropertyWebkitTapHighlightColor(),
+      &GetCSSPropertyWebkitTextEmphasisColor(),
+  };
+
+  StyleCascade cascade(state);
+
+  for (const CSSProperty* property : properties) {
+    CascadeDeclaration(cascade, property->GetCSSPropertyName(), *unset, origin,
+                       apply_mask);
+  }
+
+  const CSSValue* window = CSSIdentifierValue::Create(CSSValueID::kWindow);
+  CascadeDeclaration(cascade,
+                     GetCSSPropertyBackgroundColor().GetCSSPropertyName(),
+                     *window, origin, apply_mask);
+
+  Color prev_bg_color = state.Style()->BackgroundColor().GetColor();
+
+  CascadeRange(state, cascade, result.UaRules(), origin);
+  cascade.Exclude(CSSProperty::kIsAffectedByForcedColors, false);
+  cascade.Apply();
+
+  Color current_bg_color = state.Style()->BackgroundColor().GetColor();
+  Color bg_color(current_bg_color.Red(), current_bg_color.Green(),
+                 current_bg_color.Blue(), prev_bg_color.Alpha());
+  state.Style()->SetBackgroundColor(bg_color);
+}
+
 bool StyleResolver::HasAuthorBackground(const StyleResolverState& state) {
   const CachedUAStyle* cached_ua_style = state.GetCachedUAStyle();
   if (!cached_ua_style)
@@ -2420,6 +2489,12 @@
   return GetDocument().InForcedColorsMode();
 }
 
+bool StyleResolver::IsForcedColorsModeEnabled(
+    const StyleResolverState& state) const {
+  return IsForcedColorsModeEnabled() &&
+         state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone;
+}
+
 void StyleResolver::ApplyCascadedColorValue(StyleResolverState& state) {
   if (RuntimeEnabledFeatures::CSSCascadeEnabled())
     return;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h
index 452b8a7..b62783a5 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -221,6 +221,10 @@
   };
 
   CacheSuccess ApplyMatchedCache(StyleResolverState&, const MatchResult&);
+  void MaybeAddToMatchedPropertiesCache(StyleResolverState&,
+                                        const CacheSuccess&,
+                                        const MatchResult&);
+
   void ApplyCustomProperties(StyleResolverState&,
                              const MatchResult&,
                              const CacheSuccess&,
@@ -250,6 +254,7 @@
                            const MatchResult& match_result,
                            bool apply_inherited_only,
                            NeedsApplyPass& needs_apply_pass);
+  void CascadeAndApplyForcedColors(StyleResolverState&, const MatchResult&);
 
   void CascadeAndApplyMatchedProperties(StyleResolverState&,
                                         const MatchResult&);
@@ -311,6 +316,7 @@
   bool WasViewportResized() const { return was_viewport_resized_; }
 
   bool IsForcedColorsModeEnabled() const;
+  bool IsForcedColorsModeEnabled(const StyleResolverState&) const;
 
   MatchedPropertiesCache matched_properties_cache_;
   Member<Document> document_;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
index 9bdbdd1..0c10c7d 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -152,6 +152,12 @@
   cached_ua_style_ = std::make_unique<CachedUAStyle>(Style());
 }
 
+UAStyle* StyleResolverState::EnsureUAStyle() {
+  if (!ua_style_)
+    ua_style_ = std::make_unique<UAStyle>();
+  return ua_style_.get();
+}
+
 void StyleResolverState::LoadPendingResources() {
   element_style_resources_.LoadPendingResources(Style());
 }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
index b452c084..96ccbbe 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/style/cached_ua_style.h"
+#include "third_party/blink/renderer/core/style/ua_style.h"
 
 namespace blink {
 
@@ -144,6 +145,10 @@
     return cached_ua_style_.get();
   }
 
+  const UAStyle* GetUAStyle() const { return ua_style_.get(); }
+
+  UAStyle* EnsureUAStyle();
+
   ElementStyleResources& GetElementStyleResources() {
     return element_style_resources_;
   }
@@ -233,6 +238,7 @@
   FontBuilder font_builder_;
 
   std::unique_ptr<CachedUAStyle> cached_ua_style_;
+  std::unique_ptr<UAStyle> ua_style_;
 
   ElementStyleResources element_style_resources_;
   Member<Element> pseudo_element_;
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc
index 4a99e20..7736b31b 100644
--- a/third_party/blink/renderer/core/css/style_rule.cc
+++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -345,8 +345,6 @@
     : StyleRuleBase(font_face_rule),
       properties_(font_face_rule.properties_->MutableCopy()) {}
 
-StyleRuleFontFace::~StyleRuleFontFace() = default;
-
 MutableCSSPropertyValueSet& StyleRuleFontFace::MutableProperties() {
   if (!properties_->IsMutable())
     properties_ = properties_->MutableCopy();
@@ -429,8 +427,6 @@
     : StyleRuleBase(viewport_rule),
       properties_(viewport_rule.properties_->MutableCopy()) {}
 
-StyleRuleViewport::~StyleRuleViewport() = default;
-
 MutableCSSPropertyValueSet& StyleRuleViewport::MutableProperties() {
   if (!properties_->IsMutable())
     properties_ = properties_->MutableCopy();
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h
index 491ae5ac..b72a76b 100644
--- a/third_party/blink/renderer/core/css/style_rule.h
+++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -147,7 +147,6 @@
  public:
   StyleRuleFontFace(CSSPropertyValueSet*);
   StyleRuleFontFace(const StyleRuleFontFace&);
-  ~StyleRuleFontFace();
 
   const CSSPropertyValueSet& Properties() const { return *properties_; }
   MutableCSSPropertyValueSet& MutableProperties();
@@ -287,7 +286,6 @@
  public:
   explicit StyleRuleViewport(CSSPropertyValueSet*);
   explicit StyleRuleViewport(const StyleRuleViewport&);
-  ~StyleRuleViewport();
 
   const CSSPropertyValueSet& Properties() const { return *properties_; }
   MutableCSSPropertyValueSet& MutableProperties();
diff --git a/third_party/blink/renderer/core/css/style_rule_import.cc b/third_party/blink/renderer/core/css/style_rule_import.cc
index 3764ea8f..8493e49 100644
--- a/third_party/blink/renderer/core/css/style_rule_import.cc
+++ b/third_party/blink/renderer/core/css/style_rule_import.cc
@@ -110,7 +110,8 @@
 
   Document* document_for_origin = document;
   if (base::FeatureList::IsEnabled(
-          features::kHtmlImportsRequestInitiatorLock)) {
+          features::kHtmlImportsRequestInitiatorLock) &&
+      document->ImportsController()) {
     // For @imports from HTML imported Documents, we use the
     // context document for getting origin and ResourceFetcher to use the main
     // Document's origin, while using the element document for CompleteURL() to
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index c0be43b..8ea85e7 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2038,7 +2038,7 @@
 }
 
 String Document::SuggestedMIMEType() const {
-  if (IsXMLDocument()) {
+  if (IsA<XMLDocument>(this)) {
     if (IsXHTMLDocument())
       return "application/xhtml+xml";
     if (IsSVGDocument())
@@ -5157,7 +5157,7 @@
                           .WithContextDocument(ContextDocument())
                           .WithOwnerDocument(const_cast<Document*>(this))
                           .WithURL(Url());
-  if (IsXMLDocument()) {
+  if (IsA<XMLDocument>(this)) {
     if (IsXHTMLDocument())
       return XMLDocument::CreateXHTML(
           init.WithRegistrationContext(RegistrationContext()));
diff --git a/third_party/blink/renderer/core/dom/document_lifecycle.cc b/third_party/blink/renderer/core/dom/document_lifecycle.cc
index 2a1c3b4..55238c1e 100644
--- a/third_party/blink/renderer/core/dom/document_lifecycle.cc
+++ b/third_party/blink/renderer/core/dom/document_lifecycle.cc
@@ -91,8 +91,6 @@
       disallow_transition_count_(0),
       check_no_transition_(false) {}
 
-DocumentLifecycle::~DocumentLifecycle() = default;
-
 #if DCHECK_IS_ON()
 
 bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
diff --git a/third_party/blink/renderer/core/dom/document_lifecycle.h b/third_party/blink/renderer/core/dom/document_lifecycle.h
index 5327f5c..661eb4af 100644
--- a/third_party/blink/renderer/core/dom/document_lifecycle.h
+++ b/third_party/blink/renderer/core/dom/document_lifecycle.h
@@ -213,7 +213,6 @@
   };
 
   DocumentLifecycle();
-  ~DocumentLifecycle();
 
   bool IsActive() const { return state_ > kInactive && state_ < kStopping; }
   LifecycleState GetState() const { return state_; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 82fb8df..4154138 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1925,13 +1925,13 @@
   Vector<FloatQuad> quads;
   ClientQuads(quads);
   if (quads.IsEmpty())
-    return DOMRectList::Create();
+    return MakeGarbageCollected<DOMRectList>();
 
   LayoutObject* element_layout_object = GetLayoutObject();
   DCHECK(element_layout_object);
   GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom(
       quads, *element_layout_object);
-  return DOMRectList::Create(quads);
+  return MakeGarbageCollected<DOMRectList>(quads);
 }
 
 DOMRect* Element::getBoundingClientRect() {
@@ -4127,14 +4127,7 @@
     return focused_element;
 
   // Slide the focus to its inner node.
-  // TODO(crbug.com/1014094): We should pick the first focusable element in
-  // the flat tree.
-  Element* found =
-      doc.GetPage()->GetFocusController().FindFocusableElementInShadowHost(
-          *this);
-  if (found && IsShadowIncludingInclusiveAncestorOf(*found))
-    return found;
-  return nullptr;
+  return FocusController::FindFocusableElementInShadowHost(*this);
 }
 
 void Element::focus(const FocusOptions* options) {
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc
index c7e29dd..e3bc739 100644
--- a/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -138,7 +138,8 @@
     // can hang off some parent sheet.
     if (is_xsl_ && RuntimeEnabledFeatures::XSLTEnabled()) {
       KURL final_url(local_href_);
-      sheet_ = XSLStyleSheet::CreateEmbedded(this, final_url);
+      sheet_ = MakeGarbageCollected<XSLStyleSheet>(this, final_url.GetString(),
+                                                   final_url, true);
       loading_ = false;
     }
     return;
@@ -195,8 +196,8 @@
       is_xsl_ ? std::make_unique<IncrementLoadEventDelayCount>(GetDocument())
               : nullptr;
   if (is_xsl_) {
-    sheet_ = XSLStyleSheet::Create(this, resource->Url(),
-                                   resource->GetResponse().ResponseUrl());
+    sheet_ = MakeGarbageCollected<XSLStyleSheet>(
+        this, resource->Url(), resource->GetResponse().ResponseUrl(), false);
     ToXSLStyleSheet(sheet_.Get())
         ->ParseString(ToXSLStyleSheetResource(resource)->Sheet());
   } else {
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
index 44c86ad3..a44ba06 100644
--- a/third_party/blink/renderer/core/dom/range.cc
+++ b/third_party/blink/renderer/core/dom/range.cc
@@ -1631,7 +1631,7 @@
   Vector<FloatQuad> quads;
   GetBorderAndTextQuads(quads);
 
-  return DOMRectList::Create(quads);
+  return MakeGarbageCollected<DOMRectList>(quads);
 }
 
 DOMRect* Range::getBoundingClientRect() const {
diff --git a/third_party/blink/renderer/core/dom/user_action_element_set.cc b/third_party/blink/renderer/core/dom/user_action_element_set.cc
index b298555..1f19a82 100644
--- a/third_party/blink/renderer/core/dom/user_action_element_set.cc
+++ b/third_party/blink/renderer/core/dom/user_action_element_set.cc
@@ -33,8 +33,6 @@
 
 UserActionElementSet::UserActionElementSet() = default;
 
-UserActionElementSet::~UserActionElementSet() = default;
-
 void UserActionElementSet::DidDetach(Element& element) {
   DCHECK(element.IsUserActionElement());
   ClearFlags(&element, kIsActiveFlag | kInActiveChainFlag | kIsHoveredFlag |
diff --git a/third_party/blink/renderer/core/dom/user_action_element_set.h b/third_party/blink/renderer/core/dom/user_action_element_set.h
index 408825e..23181da 100644
--- a/third_party/blink/renderer/core/dom/user_action_element_set.h
+++ b/third_party/blink/renderer/core/dom/user_action_element_set.h
@@ -69,7 +69,6 @@
   }
 
   UserActionElementSet();
-  ~UserActionElementSet();
 
   void DidDetach(Element&);
 
diff --git a/third_party/blink/renderer/core/dom/xml_document.h b/third_party/blink/renderer/core/dom/xml_document.h
index 95828e8..858e7f6 100644
--- a/third_party/blink/renderer/core/dom/xml_document.h
+++ b/third_party/blink/renderer/core/dom/xml_document.h
@@ -50,7 +50,12 @@
               DocumentClassFlags document_classes = kXMLDocumentClass);
 };
 
-DEFINE_DOCUMENT_TYPE_CASTS(XMLDocument);
+template <>
+struct DowncastTraits<XMLDocument> {
+  static bool AllowFrom(const Document& document) {
+    return document.IsXMLDocument();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/editing/commands/editing_state.cc b/third_party/blink/renderer/core/editing/commands/editing_state.cc
index 8c20b9f..3b3d854 100644
--- a/third_party/blink/renderer/core/editing/commands/editing_state.cc
+++ b/third_party/blink/renderer/core/editing/commands/editing_state.cc
@@ -8,8 +8,6 @@
 
 EditingState::EditingState() = default;
 
-EditingState::~EditingState() = default;
-
 void EditingState::Abort() {
   DCHECK(!is_aborted_);
   is_aborted_ = true;
diff --git a/third_party/blink/renderer/core/editing/commands/editing_state.h b/third_party/blink/renderer/core/editing/commands/editing_state.h
index f5b63ac..2ae504f 100644
--- a/third_party/blink/renderer/core/editing/commands/editing_state.h
+++ b/third_party/blink/renderer/core/editing/commands/editing_state.h
@@ -27,7 +27,6 @@
 
  public:
   EditingState();
-  ~EditingState();
 
   void Abort();
   bool IsAborted() const { return is_aborted_; }
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index ad3e029..a777c6b7 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -674,8 +674,6 @@
       scoping_in_progress_(false),
       find_match_rects_are_valid_(false) {}
 
-TextFinder::~TextFinder() = default;
-
 bool TextFinder::SetMarkerActive(Range* range, bool active) {
   if (!range || range->collapsed())
     return false;
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.h b/third_party/blink/renderer/core/editing/finder/text_finder.h
index c025a32..e8ede1d8 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.h
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -119,7 +119,6 @@
                      bool finished_whole_request);
 
   explicit TextFinder(WebLocalFrameImpl& owner_frame);
-  ~TextFinder();
 
   class FindMatch {
     DISALLOW_NEW();
diff --git a/third_party/blink/renderer/core/editing/ime/edit_context.cc b/third_party/blink/renderer/core/editing/ime/edit_context.cc
index 6f19a2a..fb3a15b 100644
--- a/third_party/blink/renderer/core/editing/ime/edit_context.cc
+++ b/third_party/blink/renderer/core/editing/ime/edit_context.cc
@@ -69,6 +69,16 @@
   return ContextLifecycleObserver::GetFrame()->GetInputMethodController();
 }
 
+bool EditContext::IsEditContextActive() const {
+  return true;
+}
+
+bool EditContext::IsInputPanelPolicyManual() const {
+  return GetInputMethodController()
+             .GetActiveEditContext()
+             ->inputPanelPolicy() == "manual";
+}
+
 void EditContext::DispatchCompositionEndEvent(const String& text) {
   auto* event = MakeGarbageCollected<CompositionEvent>(
       event_type_names::kCompositionend,
@@ -153,7 +163,7 @@
 void EditContext::blur() {
   if (GetInputMethodController().GetActiveEditContext() != this)
     return;
-  // Clean up the state of the |this| EditContext
+  // Clean up the state of the |this| EditContext.
   FinishComposingText(ConfirmCompositionBehavior::kKeepSelection);
   GetInputMethodController().SetActiveEditContext(this);
 }
@@ -179,7 +189,7 @@
     return;
 
   // There is an active composition so need to set the range of the
-  // composition too so that we can commit the string properly
+  // composition too so that we can commit the string properly.
   if (composition_range_start_ == 0 && composition_range_end_ == 0) {
     composition_range_start_ = selection_start_;
     composition_range_end_ = selection_end_;
@@ -261,7 +271,7 @@
 }
 
 void EditContext::setInputMode(const String& input_mode) {
-  // inputMode password is not supported by browsers yet
+  // inputMode password is not supported by browsers yet:
   // https://github.com/whatwg/html/issues/4875
 
   if (input_mode == "text")
@@ -299,7 +309,7 @@
     case WebTextInputMode::kWebTextInputModeUrl:
       return "url";
     default:
-      return "none";  // defaulting to none
+      return "none";  // Defaulting to none.
   }
 }
 
@@ -339,15 +349,15 @@
     case ui::TextInputAction::kSend:
       return "send";
     default:
-      // defaulting to enter
+      // Defaulting to enter.
       return "enter";
   }
 }
 
-void EditContext::GetLayoutBounds(WebRect& web_control_bounds,
-                                  WebRect& web_selection_bounds) {
-  web_control_bounds = control_bounds_;
-  web_selection_bounds = selection_bounds_;
+void EditContext::GetLayoutBounds(WebRect* web_control_bounds,
+                                  WebRect* web_selection_bounds) {
+  *web_control_bounds = control_bounds_;
+  *web_selection_bounds = selection_bounds_;
 }
 
 bool EditContext::SetComposition(
@@ -368,7 +378,7 @@
     composition_range_start_ = selection_start_;
     composition_range_end_ = selection_end_;
   }
-  // Update the selection and buffer if the composition range has changed
+  // Update the selection and buffer if the composition range has changed.
   String update_text(text);
   if (composition_range_start_ != selection_start_ &&
       composition_range_end_ != selection_end_) {
@@ -378,11 +388,11 @@
   text_ = text_.Substring(0, selection_start_) + update_text +
           text_.Substring(selection_end_);
 
-  // Fire textupdate and textformatupdate events to JS
+  // Fire textupdate and textformatupdate events to JS.
   const uint32_t update_range_start = composition_range_start_;
   const uint32_t update_range_end = composition_range_end_;
   if (has_composition_) {
-    // Replace the existing composition with empty string
+    // Replace the existing composition with empty string.
     composition_range_start_ = selection_start_;
     composition_range_end_ = selection_end_;
   }
@@ -422,7 +432,7 @@
                           composition_range_end_, composition_start,
                           composition_start);
   DispatchTextFormatEvent(ime_text_spans);
-  // Update the selection range
+  // Update the selection range.
   selection_start_ = composition_start;
   selection_end_ = composition_start;
   return true;
@@ -432,10 +442,10 @@
                              const WebVector<WebImeTextSpan>& ime_text_spans,
                              const WebRange& replacement_range,
                              int relative_caret_position) {
-  // Fire textupdate and textformatupdate events to JS
+  // Fire textupdate and textformatupdate events to JS.
   // ime_text_spans can have multiple format updates so loop through and fire
-  // events accordingly
-  // Update the cached selection too
+  // events accordingly.
+  // Update the cached selection too.
   String update_text(text);
   uint32_t update_range_start;
   uint32_t update_range_end;
@@ -462,7 +472,7 @@
   composition_range_end_ = 0;
   DispatchTextUpdateEvent(update_text, update_range_start, update_range_end,
                           new_selection_start, new_selection_end);
-  // Fire composition end event
+  // Fire composition end event.
   if (!text.IsEmpty() && has_composition_)
     DispatchCompositionEndEvent(text);
 
@@ -475,7 +485,7 @@
   WebString text;
   if (has_composition_) {
     text = text_.Substring(composition_range_start_, composition_range_end_);
-    // Fire composition end event
+    // Fire composition end event.
     DispatchCompositionEndEvent(text);
   } else {
     text = text_.Substring(selection_start_, selection_end_);
@@ -536,7 +546,7 @@
 
 WebTextInputInfo EditContext::TextInputInfo() {
   WebTextInputInfo info;
-  // Fetch all the text input info from edit context
+  // Fetch all the text input info from edit context.
   info.action = GetEditContextEnterKeyHint();
   info.input_mode = GetInputModeOfEditContext();
   info.type = TextInputType();
@@ -551,12 +561,12 @@
 
 int EditContext::TextInputFlags() const {
   int flags = 0;
-  // Disable spellcheck & autocorrect for EditContext
+  // Disable spellcheck & autocorrect for EditContext.
   flags |= kWebTextInputFlagAutocorrectOff;
   flags |= kWebTextInputFlagSpellcheckOff;
 
   // TODO:(snianu) Enable this once the password type
-  // is supported by inputMode attribute
+  // is supported by inputMode attribute.
   // if (input_mode_ == WebTextInputMode::kPassword)
   //   flags |= kWebTextInputFlagHasBeenPasswordField;
 
diff --git a/third_party/blink/renderer/core/editing/ime/edit_context.h b/third_party/blink/renderer/core/editing/ime/edit_context.h
index 38cdc12c..7e40f1e1 100644
--- a/third_party/blink/renderer/core/editing/ime/edit_context.h
+++ b/third_party/blink/renderer/core/editing/ime/edit_context.h
@@ -29,7 +29,7 @@
 // The goal of the EditContext is to expose the lower-level APIs provided by
 // modern operating systems to facilitate various input modalities to unlock
 // advanced editing scenarios. For more information please refer
-// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md
+// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md.
 
 class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
                                       public ActiveScriptWrappable<EditContext>,
@@ -44,13 +44,13 @@
                              const EditContextInit* dict);
   ~EditContext() override;
 
-  // Event listeners for an EditContext
+  // Event listeners for an EditContext.
   DEFINE_ATTRIBUTE_EVENT_LISTENER(textupdate, kTextupdate)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(textformatupdate, kTextformatupdate)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(compositionstart, kCompositionstart)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(compositionend, kCompositionend)
 
-  // Public APIs for an EditContext (called from JS)
+  // Public APIs for an EditContext (called from JS).
 
   // When focus is called on an EditContext, it sets the active EditContext in
   // the document so it can use the text input state to send info about the
@@ -87,51 +87,51 @@
   // updated. However, in general this should be avoided during the firing of
   // textupdate as it will result in a canceled composition.
   // Also, after calling this API, update the selection by calling
-  // updateSelection
+  // updateSelection.
   void updateText(uint32_t start,
                   uint32_t end,
                   const String& new_text,
                   ExceptionState& exception_state);
 
-  // Returns the text of the EditContext
+  // Returns the text of the EditContext.
   String text() const;
 
-  // Returns the current selectionStart of the EditContext
+  // Returns the current selectionStart of the EditContext.
   uint32_t selectionStart() const;
 
-  // Returns the current selectionEnd of the EditContext
+  // Returns the current selectionEnd of the EditContext.
   uint32_t selectionEnd() const;
 
-  // Returns the InputMode of the EditContext
+  // Returns the InputMode of the EditContext.
   String inputMode() const;
 
-  // Returns the EnterKeyHint of the EditContext
+  // Returns the EnterKeyHint of the EditContext.
   String enterKeyHint() const;
 
-  // Returns the InputPanelPolicy of the EditContext
+  // Returns the InputPanelPolicy of the EditContext.
   String inputPanelPolicy() const;
 
-  // Sets the text of the EditContext which is used to display suggestions
+  // Sets the text of the EditContext which is used to display suggestions.
   void setText(const String& text);
 
-  // Sets the selectionStart of the EditContext
+  // Sets the selectionStart of the EditContext.
   void setSelectionStart(uint32_t selection_start,
                          ExceptionState& exception_state);
 
-  // Sets the selectionEnd of the EditContext
+  // Sets the selectionEnd of the EditContext.
   void setSelectionEnd(uint32_t selection_end, ExceptionState& exception_state);
 
   // Sets an input mode defined in EditContextInputMode.
-  // This relates to the inputMode attribute defined for input element
-  // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute
+  // This relates to the inputMode attribute defined for input element:
+  // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute.
   void setInputMode(const String& input_mode);
 
   // Sets a specific action related to Enter key defined in
-  // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute
+  // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute.
   void setEnterKeyHint(const String& enter_key_hint);
 
-  // Sets a policy that determines whether the VK should be raised or dismissed
-  // Auto raises the VK automatically, Manual suppresses it
+  // Sets a policy that determines whether the VK should be raised or dismissed.
+  // Auto raises the VK automatically, Manual suppresses it.
   void setInputPanelPolicy(const String& input_policy);
 
   // EventTarget overrides
@@ -163,9 +163,10 @@
   bool GetCompositionCharacterBounds(WebVector<WebRect>& bounds) override;
   WebRange GetSelectionOffsets() const override;
 
-  // Returns the control and selection bounds for an EditContext
-  void GetLayoutBounds(WebRect& web_control_bounds,
-                       WebRect& web_selection_bounds) override;
+  // Populate |control_bounds| and |selection_bounds| with the bounds fetched
+  // from the active EditContext.
+  void GetLayoutBounds(WebRect* web_control_bounds,
+                       WebRect* web_selection_bounds) override;
 
   // Sets the composition range from the already existing text
   // This is used for reconversion scenarios in JPN IME.
@@ -174,28 +175,29 @@
       int composition_end,
       const WebVector<WebImeTextSpan>& ime_text_spans);
 
-  bool IsEditContextActive() const override { return true; }
+  bool IsInputPanelPolicyManual() const override;
+  bool IsEditContextActive() const override;
   // Called from WebLocalFrame for English compositions
   // such as shape-writing, handwriting panels etc.
   // Extends the current selection range and removes the
-  // characters from the buffer
+  // characters from the buffer.
   void ExtendSelectionAndDelete(int before, int after);
 
  private:
-  // Returns the enter key action attribute set in the EditContext
+  // Returns the enter key action attribute set in the EditContext.
   ui::TextInputAction GetEditContextEnterKeyHint() const;
 
-  // Returns the inputMode of the EditContext from enterKeyHint property
+  // Returns the inputMode of the EditContext from enterKeyHint property.
   WebTextInputMode GetInputModeOfEditContext() const;
 
   InputMethodController& GetInputMethodController() const;
 
-  // Events fired to JS
-  // Fires compositionstart event to JS whenever user starts a composition
+  // Events fired to JS.
+  // Fires compositionstart event to JS whenever user starts a composition.
   bool DispatchCompositionStartEvent(const String& text);
 
   // Fires compositionend event to JS whenever composition is terminated by the
-  // user
+  // user.
   void DispatchCompositionEndEvent(const String& text);
 
   // The textformatupdate event is fired when the input method desires a
@@ -203,7 +205,7 @@
   // properties that correspond with the properties that are exposed on
   // TextFormatUpdateEvent (e.g. backgroundColor, textDecoration, etc.). The
   // consumer of the EditContext should update their view accordingly to provide
-  // the user with visual feedback as prescribed by the software keyboard
+  // the user with visual feedback as prescribed by the software keyboard.
   void DispatchTextFormatEvent(const WebVector<WebImeTextSpan>& ime_text_spans);
 
   // The textupdate event will be fired on the EditContext when user input has
@@ -227,7 +229,7 @@
                                uint32_t new_selection_start,
                                uint32_t new_selection_end);
 
-  // EditContext member variables
+  // EditContext member variables.
   String text_;
   uint32_t selection_start_ = 0;
   uint32_t selection_end_ = 0;
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
index d8291acea..222626f 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
@@ -138,8 +138,6 @@
   values_.all = 0;
 }
 
-TextIteratorBehavior::~TextIteratorBehavior() = default;
-
 bool TextIteratorBehavior::operator==(const TextIteratorBehavior& other) const {
   return values_.all == other.values_.all;
 }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h b/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
index 232842e..0ff7f22 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
@@ -19,7 +19,6 @@
 
   TextIteratorBehavior(const TextIteratorBehavior& other);
   TextIteratorBehavior();
-  ~TextIteratorBehavior();
 
   bool operator==(const TextIteratorBehavior& other) const;
   bool operator!=(const TextIteratorBehavior& other) const;
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
index 12badfa..7993c70 100644
--- a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
+++ b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
@@ -126,8 +126,6 @@
     : resolve_urls_method_(resolve_urls_method),
       serialization_type_(serialization_type) {}
 
-MarkupFormatter::~MarkupFormatter() = default;
-
 String MarkupFormatter::ResolveURLIfNeeded(const Element& element,
                                            const Attribute& attribute) const {
   String value = attribute.Value();
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_formatter.h b/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
index 48112fc..984cefb 100644
--- a/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
+++ b/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
@@ -95,7 +95,6 @@
   static void AppendXMLDeclaration(StringBuilder&, const Document&);
 
   MarkupFormatter(AbsoluteURLs, SerializationType);
-  ~MarkupFormatter();
 
   void AppendStartMarkup(StringBuilder&, const Node&);
   void AppendEndMarkup(StringBuilder&, const Element&);
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc
index 8c695e3..294d50b 100644
--- a/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -223,11 +223,11 @@
     const LocalDOMWindow* dom_window,
     MouseEventInit* initializer) {
   FloatPoint client_point;
-  FloatPoint screen_point = web_pointer_properties.PositionInScreen();
+  FloatPoint screen_point(web_pointer_properties.PositionInScreen());
   float scale_factor = 1.0f;
   if (dom_window && dom_window->GetFrame() && dom_window->GetFrame()->View()) {
     LocalFrame* frame = dom_window->GetFrame();
-    FloatPoint root_frame_point = web_pointer_properties.PositionInWidget();
+    FloatPoint root_frame_point(web_pointer_properties.PositionInWidget());
     if (Page* p = frame->GetPage()) {
       if (p->GetPointerLockController().GetElement() &&
           !p->GetPointerLockController().LockPending()) {
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.cc b/third_party/blink/renderer/core/events/pointer_event_factory.cc
index ca41652..6a1e22d 100644
--- a/third_party/blink/renderer/core/events/pointer_event_factory.cc
+++ b/third_party/blink/renderer/core/events/pointer_event_factory.cc
@@ -117,12 +117,12 @@
     // movementX/Y is type int for pointerevent, so we still need to truncated
     // the coordinates before calculate movement.
     pointer_event_init->setMovementX(
-        base::saturated_cast<int>(web_pointer_event.PositionInScreen().x *
+        base::saturated_cast<int>(web_pointer_event.PositionInScreen().x() *
                                   device_scale_factor) -
         base::saturated_cast<int>(last_global_position.X() *
                                   device_scale_factor));
     pointer_event_init->setMovementY(
-        base::saturated_cast<int>(web_pointer_event.PositionInScreen().y *
+        base::saturated_cast<int>(web_pointer_event.PositionInScreen().y() *
                                   device_scale_factor) -
         base::saturated_cast<int>(last_global_position.Y() *
                                   device_scale_factor));
@@ -195,7 +195,7 @@
           new_event_init,
           static_cast<WebInputEvent::Modifiers>(event.GetModifiers()));
 
-      last_global_position = event.PositionInScreen();
+      last_global_position = FloatPoint(event.PositionInScreen());
 
       PointerEvent* pointer_event =
           PointerEvent::Create(type, new_event_init, event.TimeStamp());
@@ -343,7 +343,7 @@
   pointer_event_init->setPredictedEvents(predicted_pointer_events);
 
   SetLastPosition(pointer_event_init->pointerId(),
-                  web_pointer_event.PositionInScreen(), event_type);
+                  FloatPoint(web_pointer_event.PositionInScreen()), event_type);
   return PointerEvent::Create(type, pointer_event_init,
                               web_pointer_event.TimeStamp());
 }
@@ -375,7 +375,7 @@
   }
   // If pointer_id is not in the map, returns the current position so the
   // movement will be zero.
-  return event.PositionInScreen();
+  return FloatPoint(event.PositionInScreen());
 }
 
 PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
index fd680c5..5e4b8e5 100644
--- a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
+++ b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
@@ -123,7 +123,7 @@
             pointer_event->pointerId(),
             WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
                                  WebPointerProperties::Button::kNoButton,
-                                 WebFloatPoint(50, 50), WebFloatPoint(20, 20)),
+                                 gfx::PointF(50, 50), gfx::PointF(20, 20)),
             type),
         FloatPoint(100, 100));
     return pointer_event;
@@ -590,7 +590,7 @@
           expected_mouse_id_,
           WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
                                WebPointerProperties::Button::kNoButton,
-                               WebFloatPoint(50, 50), WebFloatPoint(20, 20)),
+                               gfx::PointF(50, 50), gfx::PointF(20, 20)),
           WebInputEvent::kPointerMove),
       FloatPoint(20, 20));
 }
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion.cc b/third_party/blink/renderer/core/events/web_input_event_conversion.cc
index da06675..716617985 100644
--- a/third_party/blink/renderer/core/events/web_input_event_conversion.cc
+++ b/third_party/blink/renderer/core/events/web_input_event_conversion.cc
@@ -59,7 +59,7 @@
   return scale;
 }
 
-FloatPoint FrameTranslation(const LocalFrameView* frame_view) {
+gfx::Vector2dF FrameTranslation(const LocalFrameView* frame_view) {
   IntPoint visual_viewport;
   FloatSize overscroll_offset;
   if (frame_view) {
@@ -71,8 +71,8 @@
           root_view->GetPage()->GetChromeClient().ElasticOverscroll();
     }
   }
-  return FloatPoint(visual_viewport.X() + overscroll_offset.Width(),
-                    visual_viewport.Y() + overscroll_offset.Height());
+  return gfx::Vector2dF(visual_viewport.X() + overscroll_offset.Width(),
+                        visual_viewport.Y() + overscroll_offset.Height());
 }
 
 FloatPoint ConvertAbsoluteLocationForLayoutObjectFloat(
@@ -118,12 +118,12 @@
 }
 
 WebPointerEvent TransformWebPointerEvent(float frame_scale,
-                                         FloatPoint frame_translate,
+                                         gfx::Vector2dF frame_translate,
                                          const WebPointerEvent& event) {
   // frameScale is default initialized in debug builds to be 0.
   DCHECK_EQ(0, event.FrameScale());
-  DCHECK_EQ(0, event.FrameTranslate().x);
-  DCHECK_EQ(0, event.FrameTranslate().y);
+  DCHECK_EQ(0, event.FrameTranslate().x());
+  DCHECK_EQ(0, event.FrameTranslate().y());
   WebPointerEvent result = event;
   result.SetFrameScale(frame_scale);
   result.SetFrameTranslate(frame_translate);
@@ -274,7 +274,7 @@
   time_stamp_ = event.PlatformTimeStamp();
   modifiers_ = event.GetModifiers();
   frame_scale_ = 1;
-  frame_translate_ = WebFloatPoint();
+  frame_translate_ = gfx::Vector2dF();
 
   // The mouse event co-ordinates should be generated from the co-ordinates of
   // the touch point.
@@ -335,7 +335,7 @@
     LocalFrameView* frame_view,
     const WebVector<const WebInputEvent*>& coalesced_events) {
   float scale = FrameScale(frame_view);
-  FloatPoint translation = FrameTranslation(frame_view);
+  gfx::Vector2dF translation = FrameTranslation(frame_view);
   Vector<WebPointerEvent> result;
   for (auto* const event : coalesced_events) {
     DCHECK(WebInputEvent::IsPointerEventType(event->GetType()));
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
index 4047e3ba..7ce8320 100644
--- a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
+++ b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -147,8 +147,8 @@
         FlooredIntPoint(transformed_event.PositionInRootFrame());
     EXPECT_EQ(5, position.X());
     EXPECT_EQ(5, position.Y());
-    EXPECT_EQ(15, transformed_event.PositionInScreen().x);
-    EXPECT_EQ(15, transformed_event.PositionInScreen().y);
+    EXPECT_EQ(15, transformed_event.PositionInScreen().x());
+    EXPECT_EQ(15, transformed_event.PositionInScreen().y());
 
     EXPECT_EQ(15, transformed_event.movement_x);
     EXPECT_EQ(15, transformed_event.movement_y);
@@ -159,8 +159,8 @@
         WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
         WebInputEvent::GetStaticTimeStampForTests(),
         WebGestureDevice::kTouchscreen);
-    web_gesture_event.SetPositionInWidget(WebFloatPoint(15, 18));
-    web_gesture_event.SetPositionInScreen(WebFloatPoint(20, 22));
+    web_gesture_event.SetPositionInWidget(gfx::PointF(15, 18));
+    web_gesture_event.SetPositionInScreen(gfx::PointF(20, 22));
     web_gesture_event.data.scroll_update.delta_x = 45;
     web_gesture_event.data.scroll_update.delta_y = 48;
     web_gesture_event.data.scroll_update.velocity_x = 40;
@@ -174,8 +174,8 @@
         FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
     EXPECT_EQ(5, position.X());
     EXPECT_EQ(6, position.Y());
-    EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x);
-    EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y);
+    EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x());
+    EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y());
     EXPECT_EQ(15, scaled_gesture_event.DeltaXInRootFrame());
     EXPECT_EQ(16, scaled_gesture_event.DeltaYInRootFrame());
     // TODO: The velocity values may need to be scaled to page scale in
@@ -191,8 +191,8 @@
         WebInputEvent::kGestureScrollEnd, WebInputEvent::kNoModifiers,
         WebInputEvent::GetStaticTimeStampForTests(),
         WebGestureDevice::kTouchscreen);
-    web_gesture_event.SetPositionInWidget(WebFloatPoint(15, 18));
-    web_gesture_event.SetPositionInScreen(WebFloatPoint(20, 22));
+    web_gesture_event.SetPositionInWidget(gfx::PointF(15, 18));
+    web_gesture_event.SetPositionInScreen(gfx::PointF(20, 22));
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
@@ -200,8 +200,8 @@
         FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
     EXPECT_EQ(5, position.X());
     EXPECT_EQ(6, position.Y());
-    EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x);
-    EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y);
+    EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x());
+    EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y());
     EXPECT_EQ(WebGestureEvent::InertialPhaseState::kUnknownMomentum,
               scaled_gesture_event.InertialPhase());
   }
@@ -216,7 +216,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(5, area.Width());
     EXPECT_EQ(5, area.Height());
   }
@@ -231,7 +232,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(10, area.Width());
     EXPECT_EQ(10, area.Height());
   }
@@ -246,7 +248,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(3, area.Width());
     EXPECT_EQ(3, area.Height());
   }
@@ -261,7 +264,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(6, area.Width());
     EXPECT_EQ(6, area.Height());
   }
@@ -276,7 +280,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(5, area.Width());
     EXPECT_EQ(5, area.Height());
   }
@@ -291,7 +296,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(5, area.Width());
     EXPECT_EQ(5, area.Height());
   }
@@ -301,13 +307,13 @@
         WebInputEvent::kPointerDown,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(10.8f, 10.5f),
-                             WebFloatPoint(10.8f, 10.5f), 30, 30),
+                             gfx::PointF(10.8f, 10.5f),
+                             gfx::PointF(10.8f, 10.5f), 30, 30),
         6.6f, 9.9f);
-    EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInWidget().y());
     EXPECT_FLOAT_EQ(6.6f, web_pointer_event.width);
     EXPECT_FLOAT_EQ(9.9f, web_pointer_event.height);
     EXPECT_EQ(30, web_pointer_event.movement_x);
@@ -316,10 +322,10 @@
     WebPointerEvent transformed_event =
         TransformWebPointerEvent(view, web_pointer_event)
             .WebPointerEventInRootFrame();
-    EXPECT_FLOAT_EQ(10.8f, transformed_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(10.5f, transformed_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(3.6f, transformed_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(3.5f, transformed_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(10.8f, transformed_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(10.5f, transformed_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(3.6f, transformed_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(3.5f, transformed_event.PositionInWidget().y());
     EXPECT_FLOAT_EQ(2.2f, transformed_event.width);
     EXPECT_FLOAT_EQ(3.3f, transformed_event.height);
     EXPECT_EQ(30, transformed_event.movement_x);
@@ -358,12 +364,12 @@
 
     WebMouseEvent transformed_event =
         TransformWebMouseEvent(view, web_mouse_event);
-    FloatPoint position = transformed_event.PositionInRootFrame();
+    gfx::PointF position = transformed_event.PositionInRootFrame();
 
-    EXPECT_FLOAT_EQ(45, position.X());
-    EXPECT_FLOAT_EQ(45, position.Y());
-    EXPECT_EQ(90, transformed_event.PositionInScreen().x);
-    EXPECT_EQ(90, transformed_event.PositionInScreen().y);
+    EXPECT_FLOAT_EQ(45, position.x());
+    EXPECT_FLOAT_EQ(45, position.y());
+    EXPECT_EQ(90, transformed_event.PositionInScreen().x());
+    EXPECT_EQ(90, transformed_event.PositionInScreen().y());
     EXPECT_EQ(60, transformed_event.movement_x);
     EXPECT_EQ(60, transformed_event.movement_y);
   }
@@ -378,10 +384,10 @@
     web_mouse_event1.movement_y = 60;
 
     WebMouseEvent web_mouse_event2 = web_mouse_event1;
-    web_mouse_event2.SetPositionInWidget(web_mouse_event1.PositionInWidget().x,
-                                         120);
-    web_mouse_event2.SetPositionInScreen(web_mouse_event1.PositionInScreen().x,
-                                         120);
+    web_mouse_event2.SetPositionInWidget(
+        web_mouse_event1.PositionInWidget().x(), 120);
+    web_mouse_event2.SetPositionInScreen(
+        web_mouse_event1.PositionInScreen().x(), 120);
     web_mouse_event2.movement_y = 30;
 
     WebVector<const WebInputEvent*> events;
@@ -392,20 +398,20 @@
         TransformWebMouseEventVector(view, events);
     EXPECT_EQ(events.size(), coalescedevents.size());
 
-    FloatPoint position = coalescedevents[0].PositionInRootFrame();
-    EXPECT_FLOAT_EQ(45, position.X());
-    EXPECT_FLOAT_EQ(45, position.Y());
-    EXPECT_EQ(90, coalescedevents[0].PositionInScreen().x);
-    EXPECT_EQ(90, coalescedevents[0].PositionInScreen().y);
+    gfx::PointF position = coalescedevents[0].PositionInRootFrame();
+    EXPECT_FLOAT_EQ(45, position.x());
+    EXPECT_FLOAT_EQ(45, position.y());
+    EXPECT_EQ(90, coalescedevents[0].PositionInScreen().x());
+    EXPECT_EQ(90, coalescedevents[0].PositionInScreen().y());
 
     EXPECT_EQ(60, coalescedevents[0].movement_x);
     EXPECT_EQ(60, coalescedevents[0].movement_y);
 
     position = coalescedevents[1].PositionInRootFrame();
-    EXPECT_FLOAT_EQ(45, position.X());
-    EXPECT_FLOAT_EQ(60, position.Y());
-    EXPECT_EQ(90, coalescedevents[1].PositionInScreen().x);
-    EXPECT_EQ(120, coalescedevents[1].PositionInScreen().y);
+    EXPECT_FLOAT_EQ(45, position.x());
+    EXPECT_FLOAT_EQ(60, position.y());
+    EXPECT_EQ(90, coalescedevents[1].PositionInScreen().x());
+    EXPECT_EQ(120, coalescedevents[1].PositionInScreen().y());
 
     EXPECT_EQ(60, coalescedevents[1].movement_x);
     EXPECT_EQ(30, coalescedevents[1].movement_y);
@@ -416,19 +422,19 @@
         WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
         WebInputEvent::GetStaticTimeStampForTests(),
         WebGestureDevice::kTouchscreen);
-    web_gesture_event.SetPositionInWidget(WebFloatPoint(90, 90));
-    web_gesture_event.SetPositionInScreen(WebFloatPoint(90, 90));
+    web_gesture_event.SetPositionInWidget(gfx::PointF(90, 90));
+    web_gesture_event.SetPositionInScreen(gfx::PointF(90, 90));
     web_gesture_event.data.scroll_update.delta_x = 60;
     web_gesture_event.data.scroll_update.delta_y = 60;
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    FloatPoint position = scaled_gesture_event.PositionInRootFrame();
+    gfx::PointF position = scaled_gesture_event.PositionInRootFrame();
 
-    EXPECT_FLOAT_EQ(45, position.X());
-    EXPECT_FLOAT_EQ(45, position.Y());
-    EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().x);
-    EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().y);
+    EXPECT_FLOAT_EQ(45, position.x());
+    EXPECT_FLOAT_EQ(45, position.y());
+    EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().x());
+    EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().y());
     EXPECT_EQ(30, scaled_gesture_event.DeltaXInRootFrame());
     EXPECT_EQ(30, scaled_gesture_event.DeltaYInRootFrame());
   }
@@ -443,7 +449,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -458,7 +465,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -473,7 +481,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -488,7 +497,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -503,7 +513,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -518,7 +529,8 @@
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
-    IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+    IntSize area =
+        FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
     EXPECT_EQ(15, area.Width());
     EXPECT_EQ(15, area.Height());
   }
@@ -528,17 +540,17 @@
         WebInputEvent::kPointerDown,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(90, 90), WebFloatPoint(90, 90)),
+                             gfx::PointF(90, 90), gfx::PointF(90, 90)),
         30, 30);
 
     WebPointerEvent transformed_event =
         TransformWebPointerEvent(view, web_pointer_event)
             .WebPointerEventInRootFrame();
 
-    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
     EXPECT_FLOAT_EQ(15, transformed_event.width);
     EXPECT_FLOAT_EQ(15, transformed_event.height);
   }
@@ -548,14 +560,14 @@
         WebInputEvent::kPointerDown,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(90, 90), WebFloatPoint(90, 90)),
+                             gfx::PointF(90, 90), gfx::PointF(90, 90)),
         30, 30);
 
     WebPointerEvent web_pointer_event2(
         WebInputEvent::kPointerDown,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(120, 90), WebFloatPoint(120, 90)),
+                             gfx::PointF(120, 90), gfx::PointF(120, 90)),
         60, 30);
 
     WebVector<const WebInputEvent*> events;
@@ -568,18 +580,18 @@
 
     WebPointerEvent transformed_event =
         coalescedevents[0].WebPointerEventInRootFrame();
-    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
     EXPECT_FLOAT_EQ(15, transformed_event.width);
     EXPECT_FLOAT_EQ(15, transformed_event.height);
 
     transformed_event = coalescedevents[1].WebPointerEventInRootFrame();
-    EXPECT_FLOAT_EQ(120, transformed_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(60, transformed_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(120, transformed_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(60, transformed_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
     EXPECT_FLOAT_EQ(30, transformed_event.width);
     EXPECT_FLOAT_EQ(15, transformed_event.height);
   }
@@ -606,8 +618,8 @@
         WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
         WebInputEvent::GetStaticTimeStampForTests(),
         WebGestureDevice::kTouchscreen);
-    web_gesture_event.SetPositionInWidget(WebFloatPoint(10, 10));
-    web_gesture_event.SetPositionInScreen(WebFloatPoint(10, 10));
+    web_gesture_event.SetPositionInWidget(gfx::PointF(10, 10));
+    web_gesture_event.SetPositionInScreen(gfx::PointF(10, 10));
     web_gesture_event.data.tap.tap_count = 1;
     web_gesture_event.data.tap.width = 10;
     web_gesture_event.data.tap.height = 10;
@@ -618,8 +630,8 @@
         FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
     EXPECT_EQ(10.f, position.X());
     EXPECT_EQ(10.f, position.Y());
-    EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().x);
-    EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().y);
+    EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().x());
+    EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().y());
     EXPECT_EQ(1, scaled_gesture_event.TapCount());
   }
 }
@@ -659,8 +671,8 @@
         FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
     EXPECT_EQ(5 + visual_offset.X(), position.X());
     EXPECT_EQ(5 + visual_offset.Y(), position.Y());
-    EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().x);
-    EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().y);
+    EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().x());
+    EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().y());
   }
 
   {
@@ -676,8 +688,8 @@
         FlooredIntPoint(scaled_mouse_wheel_event.PositionInRootFrame());
     EXPECT_EQ(5 + visual_offset.X(), position.X());
     EXPECT_EQ(5 + visual_offset.Y(), position.Y());
-    EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().x);
-    EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().y);
+    EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().x());
+    EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().y());
   }
 
   {
@@ -685,8 +697,8 @@
         WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
         WebInputEvent::GetStaticTimeStampForTests(),
         WebGestureDevice::kTouchscreen);
-    web_gesture_event.SetPositionInWidget(WebFloatPoint(10, 10));
-    web_gesture_event.SetPositionInScreen(WebFloatPoint(10, 10));
+    web_gesture_event.SetPositionInWidget(gfx::PointF(10, 10));
+    web_gesture_event.SetPositionInScreen(gfx::PointF(10, 10));
 
     WebGestureEvent scaled_gesture_event =
         TransformWebGestureEvent(view, web_gesture_event);
@@ -694,8 +706,8 @@
         FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
     EXPECT_EQ(5 + visual_offset.X(), position.X());
     EXPECT_EQ(5 + visual_offset.Y(), position.Y());
-    EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().x);
-    EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().y);
+    EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().x());
+    EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().y());
   }
 
   {
@@ -703,24 +715,24 @@
         WebInputEvent::kPointerDown,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(10.6f, 10.4f),
-                             WebFloatPoint(10.6f, 10.4f)),
+                             gfx::PointF(10.6f, 10.4f),
+                             gfx::PointF(10.6f, 10.4f)),
         10, 10);
 
-    EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInScreen().y);
-    EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInWidget().x);
-    EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInWidget().y);
+    EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInScreen().y());
+    EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInWidget().x());
+    EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInWidget().y());
 
     WebPointerEvent transformed_event =
         TransformWebPointerEvent(view, web_pointer_event)
             .WebPointerEventInRootFrame();
-    EXPECT_FLOAT_EQ(10.6f, transformed_event.PositionInScreen().x);
-    EXPECT_FLOAT_EQ(10.4f, transformed_event.PositionInScreen().y);
+    EXPECT_FLOAT_EQ(10.6f, transformed_event.PositionInScreen().x());
+    EXPECT_FLOAT_EQ(10.4f, transformed_event.PositionInScreen().y());
     EXPECT_FLOAT_EQ(5.3f + visual_offset.X(),
-                    transformed_event.PositionInWidget().x);
+                    transformed_event.PositionInWidget().x());
     EXPECT_FLOAT_EQ(5.2f + visual_offset.Y(),
-                    transformed_event.PositionInWidget().y);
+                    transformed_event.PositionInWidget().y());
   }
 }
 
@@ -758,14 +770,14 @@
     IntPoint position =
         FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
 
-    EXPECT_EQ(web_mouse_event.PositionInWidget().x + elastic_overscroll.x(),
+    EXPECT_EQ(web_mouse_event.PositionInWidget().x() + elastic_overscroll.x(),
               position.X());
-    EXPECT_EQ(web_mouse_event.PositionInWidget().y + elastic_overscroll.y(),
+    EXPECT_EQ(web_mouse_event.PositionInWidget().y() + elastic_overscroll.y(),
               position.Y());
-    EXPECT_EQ(web_mouse_event.PositionInScreen().x,
-              transformed_mouse_event.PositionInScreen().x);
-    EXPECT_EQ(web_mouse_event.PositionInScreen().y,
-              transformed_mouse_event.PositionInScreen().y);
+    EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+              transformed_mouse_event.PositionInScreen().x());
+    EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+              transformed_mouse_event.PositionInScreen().y());
   }
 
   // Elastic overscroll and pinch-zoom (this doesn't actually ever happen,
@@ -787,16 +799,16 @@
     IntPoint position =
         FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
 
-    EXPECT_EQ(web_mouse_event.PositionInWidget().x / page_scale +
+    EXPECT_EQ(web_mouse_event.PositionInWidget().x() / page_scale +
                   visual_offset.X() + elastic_overscroll.x(),
               position.X());
-    EXPECT_EQ(web_mouse_event.PositionInWidget().y / page_scale +
+    EXPECT_EQ(web_mouse_event.PositionInWidget().y() / page_scale +
                   visual_offset.Y() + elastic_overscroll.y(),
               position.Y());
-    EXPECT_EQ(web_mouse_event.PositionInScreen().x,
-              transformed_mouse_event.PositionInScreen().x);
-    EXPECT_EQ(web_mouse_event.PositionInScreen().y,
-              transformed_mouse_event.PositionInScreen().y);
+    EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+              transformed_mouse_event.PositionInScreen().x());
+    EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+              transformed_mouse_event.PositionInScreen().y());
   }
 }
 
@@ -836,14 +848,14 @@
     IntPoint position =
         FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
 
-    EXPECT_EQ(web_mouse_event.PositionInWidget().x + elastic_overscroll.x(),
+    EXPECT_EQ(web_mouse_event.PositionInWidget().x() + elastic_overscroll.x(),
               position.X());
-    EXPECT_EQ(web_mouse_event.PositionInWidget().y + elastic_overscroll.y(),
+    EXPECT_EQ(web_mouse_event.PositionInWidget().y() + elastic_overscroll.y(),
               position.Y());
-    EXPECT_EQ(web_mouse_event.PositionInScreen().x,
-              transformed_mouse_event.PositionInScreen().x);
-    EXPECT_EQ(web_mouse_event.PositionInScreen().y,
-              transformed_mouse_event.PositionInScreen().y);
+    EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+              transformed_mouse_event.PositionInScreen().x());
+    EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+              transformed_mouse_event.PositionInScreen().y());
   }
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
index 317ed783..62edab1 100644
--- a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/loader/subresource_filter.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/mhtml/archive_resource.h"
 #include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h"
@@ -141,8 +142,8 @@
 
 void WebDocumentLoaderImpl::SetSubresourceFilter(
     WebDocumentSubresourceFilter* subresource_filter) {
-  DocumentLoader::SetSubresourceFilter(SubresourceFilter::Create(
-      *GetFrame()->GetDocument(), base::WrapUnique(subresource_filter)));
+  DocumentLoader::SetSubresourceFilter(MakeGarbageCollected<SubresourceFilter>(
+      GetFrame()->GetDocument(), base::WrapUnique(subresource_filter)));
 }
 
 void WebDocumentLoaderImpl::SetLoadingHintsProvider(
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index ffdb81e..e79e713 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -9709,7 +9709,7 @@
   WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(20, 20));
+  event.SetPositionInWidget(gfx::PointF(20, 20));
   child_frame->FrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
   EXPECT_TRUE(child_widget_client.DidHandleGestureEvent());
 
@@ -10047,7 +10047,7 @@
                           GetParam());
     // TODO(wjmaclean): Make sure that touchpad device is only ever used for
     // gesture scrolling event types.
-    event.SetPositionInWidget(WebFloatPoint(100, 100));
+    event.SetPositionInWidget(gfx::PointF(100, 100));
     if (type == WebInputEvent::kGestureScrollUpdate) {
       event.data.scroll_update.delta_x = delta_x;
       event.data.scroll_update.delta_y = delta_y;
@@ -11294,8 +11294,8 @@
   // Mouse over link. Mouse cursor should be hand.
   WebMouseEvent mouse_move_over_link_event(
       WebInputEvent::kMouseMove,
-      WebFloatPoint(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
-      WebFloatPoint(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
+      gfx::PointF(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
+      gfx::PointF(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
       WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_move_over_link_event.SetFrameScale(1);
@@ -11314,8 +11314,8 @@
 
   WebMouseEvent mouse_move_event(
       WebInputEvent::kMouseMove,
-      WebFloatPoint(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
-      WebFloatPoint(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
+      gfx::PointF(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
+      gfx::PointF(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
       WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_move_event.SetFrameScale(1);
diff --git a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
index 018b09b..abf2c0f3 100644
--- a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
@@ -174,14 +174,23 @@
   return GetFrame()->GetInputMethodController().TextInputType();
 }
 
-void WebInputMethodControllerImpl::GetLayoutBounds(WebRect& control_bounds,
-                                                   WebRect& selection_bounds) {
+void WebInputMethodControllerImpl::GetLayoutBounds(WebRect* control_bounds,
+                                                   WebRect* selection_bounds) {
   if (IsEditContextActive()) {
     return GetInputMethodController().GetActiveEditContext()->GetLayoutBounds(
         control_bounds, selection_bounds);
   }
 }
 
+bool WebInputMethodControllerImpl::IsInputPanelPolicyManual() const {
+  if (IsEditContextActive()) {
+    return GetInputMethodController()
+        .GetActiveEditContext()
+        ->IsInputPanelPolicyManual();
+  }
+  return false;  // Default should always be automatic.
+}
+
 WebRange WebInputMethodControllerImpl::CompositionRange() {
   if (IsEditContextActive()) {
     return GetInputMethodController()
diff --git a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
index 422c245..cd4268a2 100644
--- a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
+++ b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h
@@ -49,8 +49,9 @@
 
   WebRange GetSelectionOffsets() const override;
 
-  void GetLayoutBounds(WebRect& control_bounds,
-                       WebRect& selection_bounds) override;
+  void GetLayoutBounds(WebRect* control_bounds,
+                       WebRect* selection_bounds) override;
+  bool IsInputPanelPolicyManual() const override;
   bool IsEditContextActive() const override;
 
   void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/core/exported/web_navigation_params.cc b/third_party/blink/renderer/core/exported/web_navigation_params.cc
index df6f05c..b7b3168 100644
--- a/third_party/blink/renderer/core/exported/web_navigation_params.cc
+++ b/third_party/blink/renderer/core/exported/web_navigation_params.cc
@@ -29,7 +29,7 @@
   auto result = std::make_unique<WebNavigationParams>();
   result->url = info.url_request.Url();
   result->http_method = info.url_request.HttpMethod();
-  result->referrer = info.url_request.HttpHeaderField(http_names::kReferer);
+  result->referrer = info.url_request.ReferrerString();
   result->referrer_policy = info.url_request.GetReferrerPolicy();
   result->http_body = info.url_request.HttpBody();
   result->http_content_type =
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index ec9a1c4..d30b72aa 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -132,8 +132,21 @@
       // (provided by WebViewTestProxy or WebWidgetTestProxy) runs the composite
       // step for the current popup. We don't run popup tests with a compositor
       // thread.
-      WebWidgetClient* widget_client =
-          popup_->web_view_->MainFrameImpl()->FrameWidgetImpl()->Client();
+      WebLocalFrameImpl* web_frame = popup_->web_view_->MainFrameImpl();
+      WebWidgetClient* widget_client = nullptr;
+
+      if (web_frame) {
+        widget_client = web_frame->FrameWidgetImpl()->Client();
+      } else {
+        // We'll enter this case for a popup in an out-of-proc iframe.
+        // Get the WidgetClient for the frame of the popup's owner element,
+        // instead of the WebView's MainFrame.
+        Element& popup_owner_element = popup_->popup_client_->OwnerElement();
+        WebLocalFrameImpl* web_local_frame_impl = WebLocalFrameImpl::FromFrame(
+            popup_owner_element.GetDocument().GetFrame());
+        widget_client = web_local_frame_impl->FrameWidgetImpl()->Client();
+      }
+
       widget_client->ScheduleAnimation();
       return;
     }
@@ -433,8 +446,8 @@
     return WebInputEventResult::kNotHandled;
   if ((event.GetType() == WebInputEvent::kGestureTap ||
        event.GetType() == WebInputEvent::kGestureTapDown) &&
-      !IsViewportPointInWindow(event.PositionInWidget().x,
-                               event.PositionInWidget().y)) {
+      !IsViewportPointInWindow(event.PositionInWidget().x(),
+                               event.PositionInWidget().y())) {
     Cancel();
     return WebInputEventResult::kNotHandled;
   }
@@ -445,8 +458,8 @@
 
 void WebPagePopupImpl::HandleMouseDown(LocalFrame& main_frame,
                                        const WebMouseEvent& event) {
-  if (IsViewportPointInWindow(event.PositionInWidget().x,
-                              event.PositionInWidget().y))
+  if (IsViewportPointInWindow(event.PositionInWidget().x(),
+                              event.PositionInWidget().y()))
     PageWidgetEventHandler::HandleMouseDown(main_frame, event);
   else
     Cancel();
@@ -455,8 +468,8 @@
 WebInputEventResult WebPagePopupImpl::HandleMouseWheel(
     LocalFrame& main_frame,
     const WebMouseWheelEvent& event) {
-  if (IsViewportPointInWindow(event.PositionInWidget().x,
-                              event.PositionInWidget().y))
+  if (IsViewportPointInWindow(event.PositionInWidget().x(),
+                              event.PositionInWidget().y()))
     return PageWidgetEventHandler::HandleMouseWheel(main_frame, event);
   Cancel();
   return WebInputEventResult::kNotHandled;
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index df68d3c8..b162c29 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -860,7 +860,8 @@
 }
 
 void WebPluginContainerImpl::HandleWheelEvent(WheelEvent& event) {
-  WebFloatPoint absolute_location = event.NativeEvent().PositionInRootFrame();
+  FloatPoint absolute_location =
+      FloatPoint(event.NativeEvent().PositionInRootFrame());
 
   // Translate the root frame position to content coordinates.
   absolute_location =
@@ -955,8 +956,8 @@
 
   LocalFrameView* parent = ParentFrameView();
   for (unsigned i = 0; i < transformed_event.touches_length; ++i) {
-    WebFloatPoint absolute_location =
-        transformed_event.touches[i].PositionInWidget();
+    FloatPoint absolute_location =
+        FloatPoint(transformed_event.touches[i].PositionInWidget());
 
     // Translate the root frame position to content coordinates.
     absolute_location = parent->ConvertFromRootFrame(absolute_location);
@@ -1021,11 +1022,11 @@
   // Take a copy of the event and translate it into the coordinate
   // system of the plugin.
   WebGestureEvent translated_event = event.NativeEvent();
-  WebFloatPoint absolute_root_frame_location =
+  gfx::PointF absolute_root_frame_location =
       event.NativeEvent().PositionInRootFrame();
   FloatPoint local_point =
       element_->GetLayoutObject()->AbsoluteToLocalFloatPoint(
-          absolute_root_frame_location);
+          FloatPoint(absolute_root_frame_location));
   translated_event.FlattenTransform();
   translated_event.SetPositionInWidget(local_point);
 
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
index 915109f..d2f1762 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -643,15 +643,15 @@
         event.GetType() == WebInputEvent::kMouseWheel) {
       const WebMouseEvent& mouse_event =
           static_cast<const WebMouseEvent&>(event);
-      last_event_location_ = IntPoint(mouse_event.PositionInWidget().x,
-                                      mouse_event.PositionInWidget().y);
+      last_event_location_ = IntPoint(mouse_event.PositionInWidget().x(),
+                                      mouse_event.PositionInWidget().y());
     } else if (WebInputEvent::IsTouchEventType(event.GetType())) {
       const WebTouchEvent& touch_event =
           static_cast<const WebTouchEvent&>(event);
       if (touch_event.touches_length == 1) {
         last_event_location_ =
-            IntPoint(touch_event.touches[0].PositionInWidget().x,
-                     touch_event.touches[0].PositionInWidget().y);
+            IntPoint(touch_event.touches[0].PositionInWidget().x(),
+                     touch_event.touches[0].PositionInWidget().y());
       } else {
         last_event_location_ = IntPoint();
       }
@@ -702,7 +702,7 @@
 
   // First, send an event that doesn't hit the plugin to verify that the
   // plugin doesn't receive it.
-  event.SetPositionInWidget(WebFloatPoint(0, 0));
+  event.SetPositionInWidget(gfx::PointF());
 
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
   RunPendingTasks();
@@ -713,7 +713,7 @@
   // it.
   WebRect rect = plugin_container_one_element.BoundsInViewport();
   event.SetPositionInWidget(
-      WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2));
+      gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2));
 
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
   RunPendingTasks();
@@ -815,8 +815,8 @@
       WebPointerProperties(
           1, WebPointerProperties::PointerType::kTouch,
           WebPointerProperties::Button::kLeft,
-          WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
-          WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+          gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+          gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
       1.0f, 1.0f);
 
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -857,8 +857,8 @@
         WebPointerProperties(
             1, WebPointerProperties::PointerType::kTouch,
             WebPointerProperties::Button::kLeft,
-            WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
-            WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+            gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+            gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
         1.0f, 1.0f);
 
     WebCoalescedInputEvent coalesced_event(event);
@@ -880,10 +880,10 @@
         WebInputEvent::kPointerMove,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(rect.x + rect.width / 2 + 1,
-                                           rect.y + rect.height / 2 + 1),
-                             WebFloatPoint(rect.x + rect.width / 2 + 1,
-                                           rect.y + rect.height / 2 + 1)),
+                             gfx::PointF(rect.x + rect.width / 2 + 1,
+                                         rect.y + rect.height / 2 + 1),
+                             gfx::PointF(rect.x + rect.width / 2 + 1,
+                                         rect.y + rect.height / 2 + 1)),
         1.0f, 1.0f);
 
     WebCoalescedInputEvent coalesced_event(event1);
@@ -892,19 +892,19 @@
         WebInputEvent::kPointerMove,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(rect.x + rect.width / 2 + 2,
-                                           rect.y + rect.height / 2 + 2),
-                             WebFloatPoint(rect.x + rect.width / 2 + 2,
-                                           rect.y + rect.height / 2 + 2)),
+                             gfx::PointF(rect.x + rect.width / 2 + 2,
+                                         rect.y + rect.height / 2 + 2),
+                             gfx::PointF(rect.x + rect.width / 2 + 2,
+                                         rect.y + rect.height / 2 + 2)),
         1.0f, 1.0f);
     WebPointerEvent event3(
         WebInputEvent::kPointerMove,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(rect.x + rect.width / 2 + 3,
-                                           rect.y + rect.height / 2 + 3),
-                             WebFloatPoint(rect.x + rect.width / 2 + 3,
-                                           rect.y + rect.height / 2 + 3)),
+                             gfx::PointF(rect.x + rect.width / 2 + 3,
+                                         rect.y + rect.height / 2 + 3),
+                             gfx::PointF(rect.x + rect.width / 2 + 3,
+                                         rect.y + rect.height / 2 + 3)),
         1.0f, 1.0f);
 
     coalesced_event.AddCoalescedEvent(event2);
@@ -1109,8 +1109,8 @@
       WebPointerProperties(
           1, WebPointerProperties::PointerType::kTouch,
           WebPointerProperties::Button::kLeft,
-          WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
-          WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+          gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+          gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
       1.0f, 1.0f);
 
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
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 a21a254..0f690a8 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -354,8 +354,8 @@
   // If the hit node is a plugin but a scrollbar is over it don't start mouse
   // capture because it will interfere with the scrollbar receiving events.
   if (event.button == WebMouseEvent::Button::kLeft) {
-    HitTestLocation location(
-        main_frame.View()->ConvertFromRootFrame(event.PositionInWidget()));
+    HitTestLocation location(main_frame.View()->ConvertFromRootFrame(
+        FloatPoint(event.PositionInWidget())));
     HitTestResult result(
         main_frame.GetEventHandler().HitTestResultAtLocation(location));
     result.SetToShadowHostIfInRestrictedShadowRoot();
@@ -411,7 +411,7 @@
       TransformWebMouseEvent(MainFrameImpl()->GetFrameView(), event);
   transformed_event.menu_source_type = kMenuSourceMouse;
   PhysicalOffset position_in_root_frame = PhysicalOffset::FromFloatPointRound(
-      transformed_event.PositionInRootFrame());
+      FloatPoint(transformed_event.PositionInRootFrame()));
 
   // Find the right target frame. See issue 1186900.
   HitTestResult result = HitTestResultForRootFramePos(position_in_root_frame);
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index de204c4d..4501761 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -209,11 +209,11 @@
   void DidHandleGestureEvent(const WebGestureEvent& event,
                              bool event_cancelled) override {
     if (event.GetType() == WebInputEvent::kGestureTap) {
-      tap_x_ = event.PositionInWidget().x;
-      tap_y_ = event.PositionInWidget().y;
+      tap_x_ = event.PositionInWidget().x();
+      tap_y_ = event.PositionInWidget().y();
     } else if (event.GetType() == WebInputEvent::kGestureLongPress) {
-      longpress_x_ = event.PositionInWidget().x;
-      longpress_y_ = event.PositionInWidget().y;
+      longpress_x_ = event.PositionInWidget().x();
+      longpress_y_ = event.PositionInWidget().y();
     }
   }
 
@@ -1144,7 +1144,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(100, 150));
+  event.SetPositionInWidget(gfx::PointF(100, 150));
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
                 WebCoalescedInputEvent(event)));
@@ -2614,14 +2614,14 @@
   WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(3, 8));
+  event.SetPositionInWidget(gfx::PointF(3, 8));
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
   RunPendingTasks();
   EXPECT_EQ(3, client.TapX());
   EXPECT_EQ(8, client.TapY());
   client.Reset();
   event.SetType(WebInputEvent::kGestureLongPress);
-  event.SetPositionInWidget(WebFloatPoint(25, 7));
+  event.SetPositionInWidget(gfx::PointF(25, 7));
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
   RunPendingTasks();
   EXPECT_EQ(25, client.LongpressX());
@@ -2647,7 +2647,7 @@
   WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(3, 8));
+  event.SetPositionInWidget(gfx::PointF(3, 8));
   EXPECT_EQ(WebInputEventResult::kNotHandled,
             web_view->MainFrameWidget()->HandleInputEvent(
                 WebCoalescedInputEvent(event)));
@@ -2668,7 +2668,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(250, 150));
+  event.SetPositionInWidget(gfx::PointF(250, 150));
 
   EXPECT_EQ(WebInputEventResult::kNotHandled,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2689,7 +2689,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(250, 150));
+  event.SetPositionInWidget(gfx::PointF(250, 150));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2710,7 +2710,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_NE(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2735,7 +2735,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2760,7 +2760,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2785,7 +2785,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2806,7 +2806,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(500, 300));
+  event.SetPositionInWidget(gfx::PointF(500, 300));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2894,7 +2894,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -2914,7 +2914,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(300, 300));
+  event.SetPositionInWidget(gfx::PointF(300, 300));
   WebLocalFrameImpl* frame = web_view->MainFrameImpl();
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
@@ -2999,7 +2999,7 @@
   WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(100, 25));
+  event.SetPositionInWidget(gfx::PointF(100, 25));
   event.data.tap.tap_count = 2;
 
   web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -3336,7 +3336,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(20, 20));
+  event.SetPositionInWidget(gfx::PointF(20, 20));
 
   // Just make sure we don't hit any asserts.
   web_view_impl->MainFrameWidget()->HandleInputEvent(
@@ -5804,7 +5804,7 @@
                         WebInputEvent::kNoModifiers,
                         WebInputEvent::GetStaticTimeStampForTests(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(10, 10));
+  event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kHandledSystem,
             web_view->MainFrameWidget()->HandleInputEvent(
@@ -5818,7 +5818,7 @@
                             WebInputEvent::kNoModifiers,
                             WebInputEvent::GetStaticTimeStampForTests(),
                             WebGestureDevice::kTouchscreen);
-  tap_event.SetPositionInWidget(WebFloatPoint(10, 10));
+  tap_event.SetPositionInWidget(gfx::PointF(10, 10));
 
   EXPECT_EQ(WebInputEventResult::kNotHandled,
             web_view->MainFrameWidget()->HandleInputEvent(
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 1e37f6d8..f260d0a4 100644
--- a/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -714,6 +714,7 @@
   request.SetRequestorOrigin(fetch_request_data_->Origin());
   request.SetIsolatedWorldOrigin(fetch_request_data_->IsolatedWorldOrigin());
   request.SetRequestContext(fetch_request_data_->Context());
+  request.SetRequestDestination(fetch_request_data_->Destination());
   request.SetHttpMethod(fetch_request_data_->Method());
   request.SetFetchWindowId(fetch_request_data_->WindowId());
 
@@ -823,6 +824,7 @@
   ResourceRequest request(fetch_request_data_->Url());
   request.SetRequestorOrigin(fetch_request_data_->Origin());
   request.SetRequestContext(fetch_request_data_->Context());
+  request.SetRequestDestination(fetch_request_data_->Destination());
   request.SetUseStreamOnResponse(true);
   request.SetHttpMethod(fetch_request_data_->Method());
   request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
@@ -883,6 +885,7 @@
   }
 
   request->SetContext(mojom::RequestContextType::FETCH);
+  request->SetDestination(network::mojom::RequestDestination::kEmpty);
 
   auto* loader = MakeGarbageCollected<Loader>(
       GetExecutionContext(), this, resolver, request,
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
index 265e0a4..06ec507e 100644
--- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -103,6 +103,7 @@
   }
 
   request->SetContext(fetch_api_request.request_context_type);
+  request->SetDestination(fetch_api_request.destination);
   request->SetReferrerString(AtomicString(Referrer::NoReferrer()));
   if (fetch_api_request.referrer) {
     if (!fetch_api_request.referrer->url.IsEmpty())
@@ -132,6 +133,7 @@
   request->origin_ = origin_;
   request->isolated_world_origin_ = isolated_world_origin_;
   request->context_ = context_;
+  request->destination_ = destination_;
   request->referrer_string_ = referrer_string_;
   request->referrer_policy_ = referrer_policy_;
   request->mode_ = mode_;
@@ -189,6 +191,7 @@
     : method_(http_names::kGET),
       header_list_(MakeGarbageCollected<FetchHeaderList>()),
       context_(mojom::RequestContextType::UNSPECIFIED),
+      destination_(network::mojom::RequestDestination::kEmpty),
       referrer_string_(Referrer::ClientReferrerString()),
       referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
       mode_(network::mojom::RequestMode::kNoCors),
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h
index babd99bd..d346ac6a 100644
--- a/third_party/blink/renderer/core/fetch/fetch_request_data.h
+++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -52,6 +52,12 @@
   const KURL& Url() const { return url_; }
   mojom::RequestContextType Context() const { return context_; }
   void SetContext(mojom::RequestContextType context) { context_ = context; }
+  network::mojom::RequestDestination Destination() const {
+    return destination_;
+  }
+  void SetDestination(network::mojom::RequestDestination destination) {
+    destination_ = destination;
+  }
   scoped_refptr<const SecurityOrigin> Origin() const { return origin_; }
   void SetOrigin(scoped_refptr<const SecurityOrigin> origin) {
     origin_ = std::move(origin);
@@ -128,6 +134,7 @@
   Member<FetchHeaderList> header_list_;
   // FIXME: Support m_skipServiceWorkerFlag;
   mojom::RequestContextType context_;
+  network::mojom::RequestDestination destination_;
   scoped_refptr<const SecurityOrigin> origin_;
   scoped_refptr<const SecurityOrigin> isolated_world_origin_;
   // FIXME: Support m_forceOriginHeaderFlag;
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc
index 28152741..b4e9313 100644
--- a/third_party/blink/renderer/core/fetch/request.cc
+++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -5,9 +5,9 @@
 #include "third_party/blink/renderer/core/fetch/request.h"
 
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/cpp/request_destination.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "third_party/blink/public/common/blob/blob_utils.h"
-#include "third_party/blink/public/common/loader/request_destination.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
@@ -685,7 +685,7 @@
 
 String Request::destination() const {
   // "The destination attribute’s getter must return request’s destination."
-  return GetRequestDestinationFromContext(request_->Context());
+  return network::RequestDestinationToString(request_->Destination());
 }
 
 String Request::referrer() const {
@@ -857,6 +857,7 @@
   fetch_api_request->integrity = request_->Integrity();
   fetch_api_request->is_history_navigation = request_->IsHistoryNavigation();
   fetch_api_request->request_context_type = request_->Context();
+  fetch_api_request->destination = request_->Destination();
 
   // Strip off the fragment part of URL. So far, all callers expect the fragment
   // to be excluded.
@@ -909,6 +910,13 @@
   return request_->Context();
 }
 
+network::mojom::RequestDestination Request::GetRequestDestination() const {
+  if (!request_) {
+    return network::mojom::RequestDestination::kEmpty;
+  }
+  return request_->Destination();
+}
+
 void Request::Trace(blink::Visitor* visitor) {
   Body::Trace(visitor);
   visitor->Trace(request_);
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h
index f77e360f..17bd42c 100644
--- a/third_party/blink/renderer/core/fetch/request.h
+++ b/third_party/blink/renderer/core/fetch/request.h
@@ -94,6 +94,7 @@
     return request_->Buffer();
   }
   mojom::RequestContextType GetRequestContextType() const;
+  network::mojom::RequestDestination GetRequestDestination() const;
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/blink/renderer/core/fetch/request_test.cc b/third_party/blink/renderer/core/fetch/request_test.cc
index 9ec1526..0e69e47 100644
--- a/third_party/blink/renderer/core/fetch/request_test.cc
+++ b/third_party/blink/renderer/core/fetch/request_test.cc
@@ -60,6 +60,8 @@
   const network::mojom::ReferrerPolicy kReferrerPolicy =
       network::mojom::ReferrerPolicy::kAlways;
   const mojom::RequestContextType kContext = mojom::RequestContextType::AUDIO;
+  const network::mojom::RequestDestination kDestination =
+      network::mojom::RequestDestination::kAudio;
   const network::mojom::RequestMode kMode =
       network::mojom::RequestMode::kNavigate;
   const network::mojom::CredentialsMode kCredentialsMode =
@@ -75,6 +77,7 @@
   fetch_api_request->cache_mode = kCacheMode;
   fetch_api_request->redirect_mode = kRedirectMode;
   fetch_api_request->request_context_type = kContext;
+  fetch_api_request->destination = kDestination;
   for (int i = 0; headers[i].key; ++i) {
     fetch_api_request->headers.insert(String(headers[i].key),
                                       String(headers[i].value));
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index ed718e7a..44fe75a 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -677,8 +677,6 @@
 Deprecation::Deprecation() : mute_count_(0) {
 }
 
-Deprecation::~Deprecation() = default;
-
 void Deprecation::ClearSuppression() {
   css_property_deprecation_bits_.reset();
   features_deprecation_bits_.reset();
diff --git a/third_party/blink/renderer/core/frame/deprecation.h b/third_party/blink/renderer/core/frame/deprecation.h
index 07dc3dc..080f1af 100644
--- a/third_party/blink/renderer/core/frame/deprecation.h
+++ b/third_party/blink/renderer/core/frame/deprecation.h
@@ -27,7 +27,6 @@
 
  public:
   Deprecation();
-  ~Deprecation();
 
   static void WarnOnDeprecatedProperties(const LocalFrame*,
                                          CSSPropertyID unresolved_property);
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index 7319b15c..fa6e97fb 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -632,7 +632,8 @@
       return;
 
     if (base::FeatureList::IsEnabled(
-            features::kHtmlImportsRequestInitiatorLock)) {
+            features::kHtmlImportsRequestInitiatorLock) &&
+        document.ImportsController()) {
       if (Document* context_document = document.ContextDocument()) {
         // For @imports from HTML imported Documents, we use the
         // context document for getting origin and ResourceFetcher to use the
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index f3b5b41..20da7ea 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1549,13 +1549,13 @@
   // an embedder-initiated navigation.  FrameLoader assumes no responsibility
   // for generating an embedder-initiated navigation's referrer, so we need to
   // ensure the proper referrer is set now.
-  // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store
-  // this is a separate member. See https://crbug.com/850813.
-  frame_request.GetResourceRequest().SetHttpReferrer(
-      SecurityPolicy::GenerateReferrer(
-          active_document->GetReferrerPolicy(), completed_url,
-          window_features.noreferrer ? Referrer::NoReferrer()
-                                     : active_document->OutgoingReferrer()));
+  Referrer referrer = SecurityPolicy::GenerateReferrer(
+      active_document->GetReferrerPolicy(), completed_url,
+      window_features.noreferrer ? Referrer::NoReferrer()
+                                 : active_document->OutgoingReferrer());
+  frame_request.GetResourceRequest().SetReferrerString(referrer.referrer);
+  frame_request.GetResourceRequest().SetReferrerPolicy(
+      referrer.referrer_policy);
 
   frame_request.GetResourceRequest().SetHasUserGesture(
       LocalFrame::HasTransientUserActivation(GetFrame()));
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index 6957f3b4..e3c26f3d 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -1143,8 +1143,8 @@
   VisualViewportMockWebFrameClient mock_web_frame_client;
   EXPECT_CALL(mock_web_frame_client,
               ShowContextMenu(ContextMenuAtLocation(
-                  mouse_down_event.PositionInWidget().x,
-                  mouse_down_event.PositionInWidget().y)));
+                  mouse_down_event.PositionInWidget().x(),
+                  mouse_down_event.PositionInWidget().y())));
 
   // Do a sanity check with no scale applied.
   WebView()->MainFrameImpl()->SetClient(&mock_web_frame_client);
@@ -1166,8 +1166,8 @@
   visual_viewport.SetLocation(FloatPoint(60, 80));
   EXPECT_CALL(mock_web_frame_client,
               ShowContextMenu(ContextMenuAtLocation(
-                  mouse_down_event.PositionInWidget().x,
-                  mouse_down_event.PositionInWidget().y)));
+                  mouse_down_event.PositionInWidget().x(),
+                  mouse_down_event.PositionInWidget().y())));
 
   mouse_down_event.button = WebMouseEvent::Button::kRight;
   WebView()->MainFrameWidget()->HandleInputEvent(
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
index 771b323..3bdf036 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -214,13 +214,14 @@
     CancelDrag();
     return;
   }
-  WebFloatPoint point_in_root_frame(
+  gfx::PointF point_in_root_frame(
       GetPage()->GetVisualViewport().ViewportToRootFrame(point_in_viewport));
 
-  WebMouseEvent fake_mouse_move(
-      WebInputEvent::kMouseMove, point_in_root_frame, screen_point,
-      WebPointerProperties::Button::kLeft, 0, WebInputEvent::kNoModifiers,
-      base::TimeTicks::Now());
+  WebMouseEvent fake_mouse_move(WebInputEvent::kMouseMove, point_in_root_frame,
+                                gfx::PointF(screen_point.x, screen_point.y),
+                                WebPointerProperties::Button::kLeft, 0,
+                                WebInputEvent::kNoModifiers,
+                                base::TimeTicks::Now());
   fake_mouse_move.SetFrameScale(1);
   local_root_->GetFrame()->GetEventHandler().DragSourceEndedAt(
       fake_mouse_move, static_cast<DragOperation>(operation));
@@ -264,7 +265,7 @@
     return kWebDragOperationNone;
   }
 
-  WebFloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
+  FloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
 
   current_drag_data_->SetModifiers(modifiers);
   DragData drag_data(current_drag_data_.Get(), point_in_root_frame,
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 74cf0df..e65c822 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -681,8 +681,8 @@
   // Take capture on a mouse down on a plugin so we can send it mouse events.
   // If the hit node is a plugin but a scrollbar is over it don't start mouse
   // capture because it will interfere with the scrollbar receiving events.
-  PhysicalOffset point(LayoutUnit(event.PositionInWidget().x),
-                       LayoutUnit(event.PositionInWidget().y));
+  PhysicalOffset point(LayoutUnit(event.PositionInWidget().x()),
+                       LayoutUnit(event.PositionInWidget().y()));
   if (event.button == WebMouseEvent::Button::kLeft) {
     HitTestLocation location(
         LocalRootImpl()->GetFrameView()->ConvertFromRootFrame(point));
@@ -865,6 +865,17 @@
   // event.
   suppress_next_keypress_event_ = false;
 
+  // If there is a popup open, it should be the one processing the event,
+  // not the page.
+  scoped_refptr<WebPagePopupImpl> page_popup = View()->GetPagePopup();
+  if (page_popup) {
+    page_popup->HandleKeyEvent(event);
+    if (event.GetType() == WebInputEvent::kRawKeyDown) {
+      suppress_next_keypress_event_ = true;
+    }
+    return WebInputEventResult::kHandledSystem;
+  }
+
   auto* frame = DynamicTo<LocalFrame>(FocusedCoreFrame());
   if (!frame)
     return WebInputEventResult::kNotHandled;
diff --git a/third_party/blink/renderer/core/geometry/dom_rect_list.h b/third_party/blink/renderer/core/geometry/dom_rect_list.h
index f3dc17b..1a7b9f84 100644
--- a/third_party/blink/renderer/core/geometry/dom_rect_list.h
+++ b/third_party/blink/renderer/core/geometry/dom_rect_list.h
@@ -39,16 +39,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static DOMRectList* Create() { return MakeGarbageCollected<DOMRectList>(); }
-  static DOMRectList* Create(const Vector<FloatQuad>& quads) {
-    return MakeGarbageCollected<DOMRectList>(quads);
-  }
-
-  template <typename Rects>
-  static DOMRectList* Create(const Rects& rects) {
-    return MakeGarbageCollected<DOMRectList>(rects);
-  }
-
   DOMRectList();
 
   template <typename Rects>
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
index 08db540..9191f0d9 100644
--- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -201,8 +201,6 @@
 // RadioButtonGroup in the header.
 RadioButtonGroupScope::RadioButtonGroupScope() = default;
 
-RadioButtonGroupScope::~RadioButtonGroupScope() = default;
-
 void RadioButtonGroupScope::AddButton(HTMLInputElement* element) {
   DCHECK_EQ(element->type(), input_type_names::kRadio);
   if (element->GetName().IsEmpty())
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
index 11399c9..a6ba8d9 100644
--- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
+++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h
@@ -36,7 +36,6 @@
 
  public:
   RadioButtonGroupScope();
-  ~RadioButtonGroupScope();
   void Trace(Visitor*);
   void AddButton(HTMLInputElement*);
   void UpdateCheckedState(HTMLInputElement*);
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc
index b44cc170..452fc6b 100644
--- a/third_party/blink/renderer/core/html/html_link_element.cc
+++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -56,7 +56,8 @@
 HTMLLinkElement::HTMLLinkElement(Document& document,
                                  const CreateElementFlags flags)
     : HTMLElement(html_names::kLinkTag, document),
-      link_loader_(LinkLoader::Create(this)),
+      link_loader_(
+          MakeGarbageCollected<LinkLoader>(this, GetLoadingTaskRunner())),
       referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
       sizes_(MakeGarbageCollected<DOMTokenList>(*this, html_names::kSizesAttr)),
       rel_list_(MakeGarbageCollected<RelList>(this)),
diff --git a/third_party/blink/renderer/core/html/imports/html_imports_controller.cc b/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
index 42488b83..8a3ea3e 100644
--- a/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
+++ b/third_party/blink/renderer/core/html/imports/html_imports_controller.cc
@@ -122,7 +122,8 @@
   ResourceFetcher* fetcher = parent->GetDocument()->Fetcher();
 
   if (base::FeatureList::IsEnabled(
-          features::kHtmlImportsRequestInitiatorLock)) {
+          features::kHtmlImportsRequestInitiatorLock) &&
+      parent->GetDocument()->ImportsController()) {
     Document* context_document = parent->GetDocument()->ContextDocument();
     if (!context_document)
       return nullptr;
diff --git a/third_party/blink/renderer/core/html/parser/html_element_stack.cc b/third_party/blink/renderer/core/html/parser/html_element_stack.cc
index 598ed12a..a1fee9e 100644
--- a/third_party/blink/renderer/core/html/parser/html_element_stack.cc
+++ b/third_party/blink/renderer/core/html/parser/html_element_stack.cc
@@ -134,8 +134,6 @@
       body_element_(nullptr),
       stack_depth_(0) {}
 
-HTMLElementStack::~HTMLElementStack() = default;
-
 bool HTMLElementStack::HasOnlyOneElement() const {
   return !TopRecord()->Next();
 }
diff --git a/third_party/blink/renderer/core/html/parser/html_element_stack.h b/third_party/blink/renderer/core/html/parser/html_element_stack.h
index bafb57a..a433c82 100644
--- a/third_party/blink/renderer/core/html/parser/html_element_stack.h
+++ b/third_party/blink/renderer/core/html/parser/html_element_stack.h
@@ -45,7 +45,6 @@
 
  public:
   HTMLElementStack();
-  ~HTMLElementStack();
 
   class ElementRecord final : public GarbageCollected<ElementRecord> {
    public:
diff --git a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
index 9741293..8ade3c1 100644
--- a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
+++ b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
@@ -39,8 +39,6 @@
 
 HTMLFormattingElementList::HTMLFormattingElementList() = default;
 
-HTMLFormattingElementList::~HTMLFormattingElementList() = default;
-
 Element* HTMLFormattingElementList::ClosestElementInScopeWithName(
     const AtomicString& target_name) {
   for (wtf_size_t i = 1; i <= entries_.size(); ++i) {
diff --git a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
index 7d8e16b..f9c4f2a1 100644
--- a/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
+++ b/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h
@@ -42,7 +42,6 @@
 
  public:
   HTMLFormattingElementList();
-  ~HTMLFormattingElementList();
 
   // Ideally Entry would be private, but HTMLTreeBuilder has to coordinate
   // between the HTMLFormattingElementList and HTMLElementStack and needs access
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
index b469915..5fbe713 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -146,7 +146,8 @@
     PreloadRequestVerification(type, url, base_url, width, referrer_policy);
     Resource* resource = preload_request_->Start(document);
     ASSERT_TRUE(resource);
-    EXPECT_EQ(expected_referrer, resource->GetResourceRequest().HttpReferrer());
+    EXPECT_EQ(expected_referrer,
+              resource->GetResourceRequest().ReferrerString());
   }
 
   void PreconnectRequestVerification(const String& host,
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc
index b90b9f09..e5fbe0f 100644
--- a/third_party/blink/renderer/core/html/parser/preload_request.cc
+++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -47,6 +47,8 @@
 
   resource_request.SetRequestContext(
       ResourceFetcher::DetermineRequestContext(resource_type_, is_image_set_));
+  resource_request.SetRequestDestination(
+      ResourceFetcher::DetermineRequestDestination(resource_type_));
 
   resource_request.SetFetchImportanceMode(importance_);
 
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index da120af..984ae3d 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1196,8 +1196,8 @@
 
   if (AutoscrollController* controller =
           scroll_manager_->GetAutoscrollController()) {
-    controller->UpdateDragAndDrop(new_target, event.PositionInRootFrame(),
-                                  event.TimeStamp());
+    controller->UpdateDragAndDrop(
+        new_target, FloatPoint(event.PositionInRootFrame()), event.TimeStamp());
   }
 
   if (drag_target_ != new_target) {
@@ -1909,12 +1909,13 @@
   LocalFrame& root_frame = frame_->LocalFrameRoot();
   HitTestResult hit_test_result;
   if (hit_rect_size.IsEmpty()) {
-    location = HitTestLocation(adjusted_event.PositionInRootFrame());
+    location =
+        HitTestLocation(FloatPoint(adjusted_event.PositionInRootFrame()));
     hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
         location, hit_type);
   } else {
     PhysicalOffset top_left = PhysicalOffset::FromFloatPointRound(
-        adjusted_event.PositionInRootFrame());
+        FloatPoint(adjusted_event.PositionInRootFrame()));
     top_left -= PhysicalOffset(hit_rect_size * 0.5f);
     location = HitTestLocation(PhysicalRect(top_left, hit_rect_size));
     hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
@@ -1934,7 +1935,8 @@
     LocalFrame* hit_frame = hit_test_result.InnerNodeFrame();
     if (!hit_frame)
       hit_frame = frame_;
-    location = HitTestLocation(adjusted_event.PositionInRootFrame());
+    location =
+        HitTestLocation(FloatPoint(adjusted_event.PositionInRootFrame()));
     hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
         location,
         (hit_type | HitTestRequest::kReadOnly) & ~HitTestRequest::kListBased);
@@ -1983,7 +1985,7 @@
     DCHECK(location.IsRectBasedTest());
     location = hit_test_result->ResolveRectBasedTest(adjusted_node, point);
     gesture_event->ApplyTouchAdjustment(
-        WebFloatPoint(adjusted_point.X(), adjusted_point.Y()));
+        gfx::PointF(adjusted_point.X(), adjusted_point.Y()));
   }
 }
 
@@ -2134,8 +2136,8 @@
 
   WebMouseEvent mouse_event(
       event_type,
-      WebFloatPoint(location_in_root_frame.X(), location_in_root_frame.Y()),
-      WebFloatPoint(global_position.X(), global_position.Y()),
+      gfx::PointF(location_in_root_frame.X(), location_in_root_frame.Y()),
+      gfx::PointF(global_position.X(), global_position.Y()),
       WebPointerProperties::Button::kNoButton, /* clickCount */ 0,
       WebInputEvent::kNoModifiers, base::TimeTicks::Now(), source_type);
 
@@ -2416,7 +2418,7 @@
     const WebMouseEvent& event) {
   PhysicalOffset document_point =
       event_handling_util::ContentPointFromRootFrame(
-          frame_, event.PositionInRootFrame());
+          frame_, FloatPoint(event.PositionInRootFrame()));
 
   // TODO(eirage): This does not handle chorded buttons yet.
   if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled() &&
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc
index 4f8a451..98f103a8 100644
--- a/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -60,8 +60,8 @@
 class EventHandlerSimTest : public SimTest {
  public:
   void InitializeMousePositionAndActivateView(float x, float y) {
-    WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
-                                   WebFloatPoint(x, y), WebFloatPoint(x, y),
+    WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove, gfx::PointF(x, y),
+                                   gfx::PointF(x, y),
                                    WebPointerProperties::Button::kNoButton, 0,
                                    WebInputEvent::Modifiers::kNoModifiers,
                                    WebInputEvent::GetStaticTimeStampForTests());
@@ -219,8 +219,8 @@
   frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 400),
                                                 kProgrammaticScroll);
 
-  WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown, WebFloatPoint(0, 0),
-                                 WebFloatPoint(100, 200),
+  WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown, gfx::PointF(0, 0),
+                                 gfx::PointF(100, 200),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -234,11 +234,11 @@
                   .GetSelectionController()
                   .MouseDownMayStartSelect());
 
-  WebMouseEvent mouse_move_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(100, 50),
-      WebFloatPoint(200, 250), WebPointerProperties::Button::kLeft, 1,
-      WebInputEvent::Modifiers::kLeftButtonDown,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
+                                 gfx::PointF(100, 50), gfx::PointF(200, 250),
+                                 WebPointerProperties::Button::kLeft, 1,
+                                 WebInputEvent::Modifiers::kLeftButtonDown,
+                                 WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_event.SetFrameScale(1);
   GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
       mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -247,7 +247,7 @@
   GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
 
   WebMouseEvent mouse_up_event(
-      WebMouseEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+      WebMouseEvent::kMouseUp, gfx::PointF(100, 50), gfx::PointF(200, 250),
       WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_up_event.SetFrameScale(1);
@@ -349,7 +349,7 @@
       "<span class='line' draggable='true'>abcd</span>"
       "</div>");
   WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
-                                 WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+                                 gfx::PointF(262, 29), gfx::PointF(329, 67),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -357,11 +357,11 @@
   GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
       mouse_down_event);
 
-  WebMouseEvent mouse_move_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
-      WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
-      WebInputEvent::Modifiers::kLeftButtonDown,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
+                                 gfx::PointF(618, 298), gfx::PointF(685, 436),
+                                 WebPointerProperties::Button::kLeft, 1,
+                                 WebInputEvent::Modifiers::kLeftButtonDown,
+                                 WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_event.SetFrameScale(1);
   GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
       mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -386,20 +386,20 @@
       "draggable='true'/>"
       "</svg>"
       "</div>");
-  WebMouseEvent mouse_down_event(
-      WebMouseEvent::kMouseDown, WebFloatPoint(145, 144),
-      WebFloatPoint(212, 282), WebPointerProperties::Button::kLeft, 1,
-      WebInputEvent::Modifiers::kLeftButtonDown,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
+                                 gfx::PointF(145, 144), gfx::PointF(212, 282),
+                                 WebPointerProperties::Button::kLeft, 1,
+                                 WebInputEvent::Modifiers::kLeftButtonDown,
+                                 WebInputEvent::GetStaticTimeStampForTests());
   mouse_down_event.SetFrameScale(1);
   GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
       mouse_down_event);
 
-  WebMouseEvent mouse_move_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
-      WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
-      WebInputEvent::Modifiers::kLeftButtonDown,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
+                                 gfx::PointF(618, 298), gfx::PointF(685, 436),
+                                 WebPointerProperties::Button::kLeft, 1,
+                                 WebInputEvent::Modifiers::kLeftButtonDown,
+                                 WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_event.SetFrameScale(1);
   GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
       mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -813,7 +813,7 @@
           .Collapse(Position(GetDocument().body(), 0))
           .Build());
   WebMouseEvent mouse_down_event(
-      WebMouseEvent::kMouseDown, WebFloatPoint(0, 0), WebFloatPoint(100, 200),
+      WebMouseEvent::kMouseDown, gfx::PointF(0, 0), gfx::PointF(100, 200),
       WebPointerProperties::Button::kRight, 1,
       WebInputEvent::Modifiers::kRightButtonDown, base::TimeTicks::Now());
   mouse_down_event.SetFrameScale(1);
@@ -970,7 +970,7 @@
       "<a class='box' href=''>Drag me</a>");
 
   WebMouseEvent mouse_down_event(
-      WebInputEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+      WebInputEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
       WebPointerProperties::Button::kLeft, 1,
       WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
   mouse_down_event.SetFrameScale(1);
@@ -978,7 +978,7 @@
       mouse_down_event);
 
   WebMouseEvent mouse_move_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+      WebInputEvent::kMouseMove, gfx::PointF(51, 50), gfx::PointF(51, 50),
       WebPointerProperties::Button::kLeft, 1,
       WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
   mouse_move_event.SetFrameScale(1);
@@ -992,7 +992,7 @@
   // dragSourceEndedAt() call could occur before a drag operation is started.
 
   WebMouseEvent mouse_up_event(
-      WebInputEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+      WebInputEvent::kMouseUp, gfx::PointF(100, 50), gfx::PointF(200, 250),
       WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_up_event.SetFrameScale(1);
@@ -1015,7 +1015,7 @@
       "<span class='line' draggable='true'>abcd</span>"
       "</div>");
   WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
-                                 WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+                                 gfx::PointF(262, 29), gfx::PointF(329, 67),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -1024,8 +1024,8 @@
       mouse_down_event);
 
   WebMouseEvent fake_mouse_move(
-      WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
-      WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
+      WebMouseEvent::kMouseMove, gfx::PointF(618, 298), gfx::PointF(685, 436),
+      WebPointerProperties::Button::kLeft, 1,
       WebInputEvent::Modifiers::kLeftButtonDown |
           WebInputEvent::Modifiers::kRelativeMotionEvent,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -1082,7 +1082,7 @@
   EXPECT_EQ(WTF::String(), LastToolTip());
 
   WebMouseEvent mouse_move_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+      WebInputEvent::kMouseMove, gfx::PointF(51, 50), gfx::PointF(51, 50),
       WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_move_event.SetFrameScale(1);
@@ -1092,7 +1092,7 @@
   EXPECT_EQ("tooltip", LastToolTip());
 
   WebMouseEvent mouse_leave_event(
-      WebInputEvent::kMouseLeave, WebFloatPoint(0, 0), WebFloatPoint(0, 0),
+      WebInputEvent::kMouseLeave, gfx::PointF(0, 0), gfx::PointF(0, 0),
       WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_leave_event.SetFrameScale(1);
@@ -1151,7 +1151,7 @@
   ASSERT_FALSE(chrome_client_->ReceivedRequestForUnbufferedInput());
 
   WebMouseEvent mouse_press_event(
-      WebInputEvent::kMouseDown, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+      WebInputEvent::kMouseDown, gfx::PointF(51, 50), gfx::PointF(51, 50),
       WebPointerProperties::Button::kLeft, 0, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now());
   mouse_press_event.SetFrameScale(1);
@@ -1194,7 +1194,7 @@
   bool scrollbar_theme_allows_hit_test =
       GetDocument().GetPage()->GetScrollbarTheme().AllowsHitTest();
 
-  const WebFloatPoint scrollbar_forward_track(795, 560);
+  const gfx::PointF scrollbar_forward_track(795, 560);
   WebMouseEvent mouse_down(WebInputEvent::kMouseDown, scrollbar_forward_track,
                            scrollbar_forward_track,
                            WebPointerProperties::Button::kLeft, 0,
@@ -1213,7 +1213,7 @@
     EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
   }
 
-  const WebFloatPoint middle_of_page(100, 100);
+  const gfx::PointF middle_of_page(100, 100);
   WebMouseEvent mouse_move(WebInputEvent::kMouseMove, middle_of_page,
                            middle_of_page, WebPointerProperties::Button::kLeft,
                            0, WebInputEvent::kNoModifiers,
@@ -1263,7 +1263,7 @@
   // Validate that we don't inject a ScrollEnd (since no ScrollBegin was
   // injected).
 
-  const WebFloatPoint middle_of_page(100, 100);
+  const gfx::PointF middle_of_page(100, 100);
   WebMouseEvent mouse_down(WebInputEvent::kMouseDown, middle_of_page,
                            middle_of_page, WebPointerProperties::Button::kLeft,
                            0, WebInputEvent::kNoModifiers,
@@ -1274,7 +1274,7 @@
   // Mouse down on the page should not generate scroll gestures.
   EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
 
-  const WebFloatPoint scrollbar_forward_track(795, 560);
+  const gfx::PointF scrollbar_forward_track(795, 560);
   WebMouseEvent mouse_move(WebInputEvent::kMouseMove, scrollbar_forward_track,
                            scrollbar_forward_track,
                            WebPointerProperties::Button::kLeft, 0,
@@ -1315,7 +1315,7 @@
   // track, and release the mouse and verify that no gesture events are
   // queued up (right click doesn't scroll scrollbars).
 
-  const WebFloatPoint scrollbar_forward_track(795, 560);
+  const gfx::PointF scrollbar_forward_track(795, 560);
   WebMouseEvent mouse_down(WebInputEvent::kMouseDown, scrollbar_forward_track,
                            scrollbar_forward_track,
                            WebPointerProperties::Button::kRight, 0,
@@ -1393,7 +1393,7 @@
 
   // kGestureTapDown sets the pressed parts which is a pre-requisite for
   // kGestureTap performing a scroll.
-  const WebFloatPoint scrollbar_forward_track(495, 450);
+  const FloatPoint scrollbar_forward_track(495, 450);
   TapDownEventBuilder tap_down(scrollbar_forward_track);
   GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(tap_down);
 
@@ -1467,7 +1467,7 @@
 TEST_F(EventHandlerTest, MouseLeaveResetsUnknownState) {
   SetHtmlInnerHTML("<div></div>");
   WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
-                                 WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+                                 gfx::PointF(262, 29), gfx::PointF(329, 67),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -1477,11 +1477,11 @@
   EXPECT_FALSE(
       GetDocument().GetFrame()->GetEventHandler().IsMousePositionUnknown());
 
-  WebMouseEvent mouse_leave_event(
-      WebMouseEvent::kMouseLeave, WebFloatPoint(262, 29),
-      WebFloatPoint(329, 67), WebPointerProperties::Button::kNoButton, 1,
-      WebInputEvent::Modifiers::kNoModifiers,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_leave_event(WebMouseEvent::kMouseLeave,
+                                  gfx::PointF(262, 29), gfx::PointF(329, 67),
+                                  WebPointerProperties::Button::kNoButton, 1,
+                                  WebInputEvent::Modifiers::kNoModifiers,
+                                  WebInputEvent::GetStaticTimeStampForTests());
   mouse_leave_event.SetFrameScale(1);
   GetDocument().GetFrame()->GetEventHandler().HandleMouseLeaveEvent(
       mouse_leave_event);
@@ -1518,8 +1518,8 @@
   frame_resource.Complete("<!DOCTYPE html>");
   Compositor().BeginFrame();
   WebMouseEvent mouse_move_inside_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(100, 229),
-      WebFloatPoint(100, 229), WebPointerProperties::Button::kNoButton, 0,
+      WebMouseEvent::kMouseMove, gfx::PointF(100, 229), gfx::PointF(100, 229),
+      WebPointerProperties::Button::kNoButton, 0,
       WebInputEvent::Modifiers::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_inside_event.SetFrameScale(1);
@@ -1537,7 +1537,7 @@
                    .IsMousePositionUnknown());
 
   WebMouseEvent mouse_move_outside_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+      WebMouseEvent::kMouseMove, gfx::PointF(300, 29), gfx::PointF(300, 29),
       WebPointerProperties::Button::kNoButton, 0,
       WebInputEvent::Modifiers::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -1573,7 +1573,7 @@
   Compositor().BeginFrame();
 
   WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
-                                 WebFloatPoint(150, 50), WebFloatPoint(150, 50),
+                                 gfx::PointF(150, 50), gfx::PointF(150, 50),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -1582,7 +1582,7 @@
       mouse_down_event);
 
   WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
-                                 WebFloatPoint(151, 50), WebFloatPoint(151, 50),
+                                 gfx::PointF(151, 50), gfx::PointF(151, 50),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -2114,8 +2114,8 @@
   // Move the cursor so no part of it intersects the viewport.
   {
     WebMouseEvent mouse_move_event(
-        WebMouseEvent::kMouseMove, WebFloatPoint(101, 101),
-        WebFloatPoint(101, 101), WebPointerProperties::Button::kNoButton, 0, 0,
+        WebMouseEvent::kMouseMove, gfx::PointF(101, 101), gfx::PointF(101, 101),
+        WebPointerProperties::Button::kNoButton, 0, 0,
         WebInputEvent::GetStaticTimeStampForTests());
     mouse_move_event.SetFrameScale(1);
     GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
@@ -2130,7 +2130,7 @@
   // should be removed.
   {
     WebMouseEvent mouse_move_event(
-        WebMouseEvent::kMouseMove, WebFloatPoint(99, 99), WebFloatPoint(99, 99),
+        WebMouseEvent::kMouseMove, gfx::PointF(99, 99), gfx::PointF(99, 99),
         WebPointerProperties::Button::kNoButton, 0, 0,
         WebInputEvent::GetStaticTimeStampForTests());
     mouse_move_event.SetFrameScale(1);
@@ -2173,7 +2173,7 @@
   // Move the cursor so no part of it intersects the viewport.
   {
     WebMouseEvent mouse_move_event(
-        WebMouseEvent::kMouseMove, WebFloatPoint(25, 25), WebFloatPoint(25, 25),
+        WebMouseEvent::kMouseMove, gfx::PointF(25, 25), gfx::PointF(25, 25),
         WebPointerProperties::Button::kNoButton, 0, 0,
         WebInputEvent::GetStaticTimeStampForTests());
     mouse_move_event.SetFrameScale(1);
@@ -2190,7 +2190,7 @@
   // kMaximumCursorSizeWithoutFallback.
   {
     WebMouseEvent mouse_move_event(
-        WebMouseEvent::kMouseMove, WebFloatPoint(23, 23), WebFloatPoint(23, 23),
+        WebMouseEvent::kMouseMove, gfx::PointF(23, 23), gfx::PointF(23, 23),
         WebPointerProperties::Button::kNoButton, 0, 0,
         WebInputEvent::GetStaticTimeStampForTests());
     mouse_move_event.SetFrameScale(1);
@@ -2381,8 +2381,8 @@
       WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests(),
       blink::WebGestureDevice::kTouchpad);
-  scroll_begin_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_begin_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_begin_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_begin_event.SetPositionInScreen(gfx::PointF(10, 10));
   scroll_begin_event.SetFrameScale(1);
 
   WebGestureEvent scroll_update_event(
@@ -2391,16 +2391,16 @@
       blink::WebGestureDevice::kTouchpad);
   scroll_update_event.data.scroll_update.delta_x = -100;
   scroll_update_event.data.scroll_update.delta_y = -100;
-  scroll_update_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_update_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_update_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_update_event.SetPositionInScreen(gfx::PointF(10, 10));
   scroll_update_event.SetFrameScale(1);
 
   WebGestureEvent scroll_end_event(WebInputEvent::kGestureScrollEnd,
                                    WebInputEvent::kNoModifiers,
                                    WebInputEvent::GetStaticTimeStampForTests(),
                                    blink::WebGestureDevice::kTouchpad);
-  scroll_end_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_end_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_end_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_end_event.SetPositionInScreen(gfx::PointF(10, 10));
 
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(scroll_begin_event));
@@ -2443,8 +2443,8 @@
       WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests(),
       blink::WebGestureDevice::kTouchpad);
-  scroll_begin_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_begin_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_begin_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_begin_event.SetPositionInScreen(gfx::PointF(10, 10));
   scroll_begin_event.SetFrameScale(1);
 
   WebGestureEvent scroll_update_event(
@@ -2453,16 +2453,16 @@
       blink::WebGestureDevice::kTouchpad);
   scroll_update_event.data.scroll_update.delta_x = 0;
   scroll_update_event.data.scroll_update.delta_y = -100;
-  scroll_update_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_update_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_update_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_update_event.SetPositionInScreen(gfx::PointF(10, 10));
   scroll_update_event.SetFrameScale(1);
 
   WebGestureEvent scroll_end_event(WebInputEvent::kGestureScrollEnd,
                                    WebInputEvent::kNoModifiers,
                                    WebInputEvent::GetStaticTimeStampForTests(),
                                    blink::WebGestureDevice::kTouchpad);
-  scroll_end_event.SetPositionInWidget(WebFloatPoint(10, 10));
-  scroll_end_event.SetPositionInScreen(WebFloatPoint(10, 10));
+  scroll_end_event.SetPositionInWidget(gfx::PointF(10, 10));
+  scroll_end_event.SetPositionInScreen(gfx::PointF(10, 10));
 
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(scroll_begin_event));
@@ -2697,7 +2697,7 @@
   Compositor().BeginFrame();
 
   WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown,
-                                 WebFloatPoint(100, 20), WebFloatPoint(0, 0),
+                                 gfx::PointF(100, 20), gfx::PointF(0, 0),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -2716,7 +2716,7 @@
       PointerEventFactory::kMouseId, target);
 
   WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
-                                 WebFloatPoint(258, 20), WebFloatPoint(0, 0),
+                                 gfx::PointF(258, 20), gfx::PointF(0, 0),
                                  WebPointerProperties::Button::kLeft, 1,
                                  WebInputEvent::Modifiers::kLeftButtonDown,
                                  WebInputEvent::GetStaticTimeStampForTests());
@@ -2725,7 +2725,7 @@
       mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
 
   WebMouseEvent mouse_up_event(
-      WebMouseEvent::kMouseUp, WebFloatPoint(258, 20), WebFloatPoint(0, 0),
+      WebMouseEvent::kMouseUp, gfx::PointF(258, 20), gfx::PointF(0, 0),
       WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_up_event.SetFrameScale(1);
@@ -2785,7 +2785,7 @@
   Compositor().BeginFrame();
 
   WebMouseEvent mouse_down_inside_event(
-      WebMouseEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+      WebMouseEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
       WebPointerProperties::Button::kLeft, 0,
       WebInputEvent::Modifiers::kLeftButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -2794,8 +2794,8 @@
       WebCoalescedInputEvent(mouse_down_inside_event));
 
   WebMouseEvent mouse_move_inside_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(100, 100),
-      WebFloatPoint(100, 100), WebPointerProperties::Button::kLeft, 1,
+      WebInputEvent::kMouseMove, gfx::PointF(100, 100), gfx::PointF(100, 100),
+      WebPointerProperties::Button::kLeft, 1,
       WebInputEvent::Modifiers::kLeftButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_inside_event.SetFrameScale(1);
@@ -2815,8 +2815,8 @@
 
   // Without capturing, next mouse move will be send to outer frame.
   WebMouseEvent mouse_move_outside_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(100, 300),
-      WebFloatPoint(100, 300), WebPointerProperties::Button::kLeft, 1,
+      WebInputEvent::kMouseMove, gfx::PointF(100, 300), gfx::PointF(100, 300),
+      WebPointerProperties::Button::kLeft, 1,
       WebInputEvent::Modifiers::kLeftButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_outside_event.SetFrameScale(1);
@@ -2877,7 +2877,7 @@
   Compositor().BeginFrame();
 
   WebMouseEvent mouse_down_inside_event(
-      WebMouseEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+      WebMouseEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
       WebPointerProperties::Button::kLeft, 0,
       WebInputEvent::Modifiers::kLeftButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -2896,11 +2896,11 @@
   EXPECT_TRUE(target->hasPointerCapture(PointerEventFactory::kMouseId));
 
   // With pointercapture, next mouse move will be send to inner frame.
-  WebMouseEvent mouse_move_event(
-      WebInputEvent::kMouseMove, WebFloatPoint(100, 300),
-      WebFloatPoint(100, 300), WebPointerProperties::Button::kLeft, 1,
-      WebInputEvent::Modifiers::kLeftButtonDown,
-      WebInputEvent::GetStaticTimeStampForTests());
+  WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
+                                 gfx::PointF(100, 300), gfx::PointF(100, 300),
+                                 WebPointerProperties::Button::kLeft, 1,
+                                 WebInputEvent::Modifiers::kLeftButtonDown,
+                                 WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_event.SetFrameScale(1);
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(mouse_move_event));
@@ -2954,7 +2954,7 @@
   frame_resource.Complete("<!DOCTYPE html>");
   Compositor().BeginFrame();
   WebMouseEvent mouse_down_outside_event(
-      WebMouseEvent::kMouseDown, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+      WebMouseEvent::kMouseDown, gfx::PointF(300, 29), gfx::PointF(300, 29),
       WebPointerProperties::Button::kRight, 0,
       WebInputEvent::Modifiers::kRightButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -2963,7 +2963,7 @@
       WebCoalescedInputEvent(mouse_down_outside_event));
 
   WebMouseEvent mouse_move_outside_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+      WebMouseEvent::kMouseMove, gfx::PointF(300, 29), gfx::PointF(300, 29),
       WebPointerProperties::Button::kRight, 0,
       WebInputEvent::Modifiers::kRightButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -2972,8 +2972,8 @@
       WebCoalescedInputEvent(mouse_move_outside_event));
 
   WebMouseEvent mouse_move_inside_event(
-      WebMouseEvent::kMouseMove, WebFloatPoint(100, 229),
-      WebFloatPoint(100, 229), WebPointerProperties::Button::kRight, 0,
+      WebMouseEvent::kMouseMove, gfx::PointF(100, 229), gfx::PointF(100, 229),
+      WebPointerProperties::Button::kRight, 0,
       WebInputEvent::Modifiers::kRightButtonDown,
       WebInputEvent::GetStaticTimeStampForTests());
   mouse_move_inside_event.SetFrameScale(1);
@@ -3005,8 +3005,8 @@
   )HTML");
 
   Compositor().BeginFrame();
-  WebMouseEvent pen_down(WebMouseEvent::kMouseDown, WebFloatPoint(100, 100),
-                         WebFloatPoint(100, 100),
+  WebMouseEvent pen_down(WebMouseEvent::kMouseDown, gfx::PointF(100, 100),
+                         gfx::PointF(100, 100),
                          WebPointerProperties::Button::kLeft, 0,
                          WebInputEvent::Modifiers::kLeftButtonDown,
                          WebInputEvent::GetStaticTimeStampForTests());
@@ -3015,8 +3015,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(pen_down));
 
-  WebMouseEvent pen_move(WebMouseEvent::kMouseMove, WebFloatPoint(100, 100),
-                         WebFloatPoint(100, 100),
+  WebMouseEvent pen_move(WebMouseEvent::kMouseMove, gfx::PointF(100, 100),
+                         gfx::PointF(100, 100),
                          WebPointerProperties::Button::kLeft, 0,
                          WebInputEvent::Modifiers::kLeftButtonDown,
                          WebInputEvent::GetStaticTimeStampForTests());
diff --git a/third_party/blink/renderer/core/input/event_handling_util.cc b/third_party/blink/renderer/core/input/event_handling_util.cc
index 632af12..6bfbf94 100644
--- a/third_party/blink/renderer/core/input/event_handling_util.cc
+++ b/third_party/blink/renderer/core/input/event_handling_util.cc
@@ -135,7 +135,8 @@
   DCHECK(frame->GetDocument());
 
   return frame->GetDocument()->PerformMouseEventHitTest(
-      request, ContentPointFromRootFrame(frame, mev.PositionInRootFrame()),
+      request,
+      ContentPointFromRootFrame(frame, FloatPoint(mev.PositionInRootFrame())),
       mev);
 }
 
diff --git a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
index 7da8a25..ca41ed3 100644
--- a/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
+++ b/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
@@ -355,8 +355,8 @@
   if (!root_frame_->GetDocument() || !root_frame_->GetDocument()->View())
     return;
 
-  IntPoint location_in_root_frame{e.PositionInRootFrame().x,
-                                  e.PositionInRootFrame().y};
+  IntPoint location_in_root_frame{e.PositionInRootFrame().x(),
+                                  e.PositionInRootFrame().y()};
 
   // Make sure we unlock all movement if the cursor is outside our bounds. This
   // can happen when the cursor is enabled/disabled (e.g. position: -1,-1).
@@ -388,7 +388,7 @@
   ResetCurrentScrollable();
 
   // Re hit test since we need a hit test with child frame.
-  IntPoint location{e.PositionInRootFrame().x, e.PositionInRootFrame().y};
+  IntPoint location{e.PositionInRootFrame().x(), e.PositionInRootFrame().y()};
   HitTestResult hit_test_result =
       HitTest(root_frame_->GetDocument()->GetLayoutView(), location);
   Node* node = hit_test_result.InnerNode();
diff --git a/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc b/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
index 925a4a56..4e4a96d 100644
--- a/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
+++ b/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
@@ -82,8 +82,8 @@
   }
 
   void MouseMove(int x, int y, float scale = 1.0f) {
-    WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(x, y),
-                        WebFloatPoint(x, y),
+    WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(x, y),
+                        gfx::PointF(x, y),
                         WebPointerProperties::Button::kNoButton, 0,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now());
     event.SetFrameScale(scale);
@@ -110,10 +110,10 @@
   }
 
   void MouseDown(int x, int y) {
-    WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+                        gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kLeftButtonDown,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
   }
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc
index dac1b31..fe11265 100644
--- a/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -86,11 +86,11 @@
     // movementX/Y is type int for now, so we need to truncated the coordinates
     // before calculate movement.
     initializer->setMovementX(
-        base::saturated_cast<int>(mouse_event.PositionInScreen().x *
+        base::saturated_cast<int>(mouse_event.PositionInScreen().x() *
                                   device_scale_factor) -
         base::saturated_cast<int>(last_position->X() * device_scale_factor));
     initializer->setMovementY(
-        base::saturated_cast<int>(mouse_event.PositionInScreen().y *
+        base::saturated_cast<int>(mouse_event.PositionInScreen().y() *
                                   device_scale_factor) -
         base::saturated_cast<int>(last_position->Y() * device_scale_factor));
   }
@@ -698,8 +698,8 @@
 
 void MouseEventManager::SetLastKnownMousePosition(const WebMouseEvent& event) {
   is_mouse_position_unknown_ = event.GetType() == WebInputEvent::kMouseLeave;
-  last_known_mouse_position_ = event.PositionInWidget();
-  last_known_mouse_screen_position_ = event.PositionInScreen();
+  last_known_mouse_position_ = FloatPoint(event.PositionInWidget());
+  last_known_mouse_screen_position_ = FloatPoint(event.PositionInScreen());
 }
 
 void MouseEventManager::SetLastMousePositionAsUnknown() {
diff --git a/third_party/blink/renderer/core/input/overscroll_behavior_test.cc b/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
index 06b3363..d054a8a 100644
--- a/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
+++ b/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
@@ -73,8 +73,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollBegin,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(20, 20));
-  event.SetPositionInScreen(WebFloatPoint(20, 20));
+  event.SetPositionInWidget(gfx::PointF(20, 20));
+  event.SetPositionInScreen(gfx::PointF(20, 20));
   event.data.scroll_begin.delta_x_hint = -hint_x;
   event.data.scroll_begin.delta_y_hint = -hint_y;
   event.data.scroll_begin.pointer_count = 1;
@@ -86,8 +86,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollUpdate,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(20, 20));
-  event.SetPositionInScreen(WebFloatPoint(20, 20));
+  event.SetPositionInWidget(gfx::PointF(20, 20));
+  event.SetPositionInScreen(gfx::PointF(20, 20));
   event.data.scroll_update.delta_x = -delta_x;
   event.data.scroll_update.delta_y = -delta_y;
   event.SetFrameScale(1);
@@ -98,8 +98,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollEnd,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(20, 20));
-  event.SetPositionInScreen(WebFloatPoint(20, 20));
+  event.SetPositionInWidget(gfx::PointF(20, 20));
+  event.SetPositionInScreen(gfx::PointF(20, 20));
   GetDocument().GetFrame()->GetEventHandler().HandleGestureScrollEvent(event);
 }
 
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc
index c6c044b..09181ac 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager.cc
+++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -366,8 +366,8 @@
       HitTestRequest::kRetargetForInert;
   LocalFrame& root_frame = frame_->LocalFrameRoot();
   // TODO(szager): Shouldn't this be PositionInScreen() ?
-  PhysicalOffset hit_test_point =
-      PhysicalOffset::FromFloatPointRound(pointer_event.PositionInWidget());
+  PhysicalOffset hit_test_point = PhysicalOffset::FromFloatPointRound(
+      FloatPoint(pointer_event.PositionInWidget()));
   hit_test_point -= PhysicalOffset(hit_rect_size * 0.5f);
   HitTestLocation location(PhysicalRect(hit_test_point, hit_rect_size));
   HitTestResult hit_test_result =
@@ -381,7 +381,8 @@
     pointer_event.SetPositionInWidget(adjusted_point.X(), adjusted_point.Y());
 
   frame_->GetEventHandler().CacheTouchAdjustmentResult(
-      pointer_event.unique_touch_event_id, pointer_event.PositionInWidget());
+      pointer_event.unique_touch_event_id,
+      FloatPoint(pointer_event.PositionInWidget()));
 }
 
 bool PointerEventManager::ShouldFilterEvent(PointerEvent* pointer_event) {
@@ -424,7 +425,7 @@
         HitTestRequest::kActive | HitTestRequest::kRetargetForInert;
     HitTestLocation location(frame_->View()->ConvertFromRootFrame(
         PhysicalOffset::FromFloatPointRound(
-            web_pointer_event.PositionInWidget())));
+            FloatPoint(web_pointer_event.PositionInWidget()))));
     HitTestResult hit_test_tesult =
         frame_->GetEventHandler().HitTestResultAtLocation(location, hit_type);
     Element* target = hit_test_tesult.InnerElement();
@@ -706,8 +707,8 @@
     return result;
   }
   pointer_event_factory_.SetLastPosition(
-      pointer_event_factory_.GetPointerEventId(event), event.PositionInScreen(),
-      event.GetType());
+      pointer_event_factory_.GetPointerEventId(event),
+      FloatPoint(event.PositionInScreen()), event.GetType());
 
   return WebInputEventResult::kHandledSuppressed;
 }
@@ -1084,9 +1085,9 @@
     pointer_event_factory_.RemoveLastPosition(pointer_id);
   } else if (!last_target || new_target->GetDocument().GetFrame() !=
                                  last_target->GetDocument().GetFrame()) {
-    pointer_event_factory_.SetLastPosition(pointer_id,
-                                           web_pointer_event.PositionInScreen(),
-                                           web_pointer_event.GetType());
+    pointer_event_factory_.SetLastPosition(
+        pointer_id, FloatPoint(web_pointer_event.PositionInScreen()),
+        web_pointer_event.GetType());
   }
 }
 
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager_test.cc b/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
index c2a164b..cd7acb6 100644
--- a/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
+++ b/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
@@ -82,8 +82,8 @@
   WebPointerEvent CreateTestPointerEvent(
       WebInputEvent::Type type,
       WebPointerProperties::PointerType pointer_type,
-      WebFloatPoint position_in_widget = WebFloatPoint(100, 100),
-      WebFloatPoint position_in_screen = WebFloatPoint(100, 100),
+      gfx::PointF position_in_widget = gfx::PointF(100, 100),
+      gfx::PointF position_in_screen = gfx::PointF(100, 100),
       int movement_x = 0,
       int movement_y = 0,
       float width = 1,
@@ -97,7 +97,7 @@
     return event;
   }
   WebMouseEvent CreateTestMouseEvent(WebInputEvent::Type type,
-                                     const WebFloatPoint& coordinates) {
+                                     const gfx::PointF& coordinates) {
     WebMouseEvent event(type, coordinates, coordinates,
                         WebPointerProperties::Button::kLeft, 0,
                         WebInputEvent::kLeftButtonDown,
@@ -125,7 +125,7 @@
   ExceptionState exception(nullptr, ExceptionState::kExecutionContext, "", "");
 
   GetEventHandler().HandleMousePressEvent(
-      CreateTestMouseEvent(WebInputEvent::kMouseDown, WebFloatPoint(100, 100)));
+      CreateTestMouseEvent(WebInputEvent::kMouseDown, gfx::PointF(100, 100)));
 
   ASSERT_FALSE(
       GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
@@ -136,7 +136,7 @@
       GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
 
   GetEventHandler().HandleMouseMoveEvent(
-      CreateTestMouseEvent(WebInputEvent::kMouseMove, WebFloatPoint(200, 200)),
+      CreateTestMouseEvent(WebInputEvent::kMouseMove, gfx::PointF(200, 200)),
       Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
 
   ASSERT_TRUE(
@@ -171,7 +171,7 @@
       {}, {}));
 
   GetEventHandler().HandleMousePressEvent(
-      CreateTestMouseEvent(WebInputEvent::kMouseDown, WebFloatPoint(100, 100)));
+      CreateTestMouseEvent(WebInputEvent::kMouseDown, gfx::PointF(100, 100)));
 
   ASSERT_EQ(callback->mouseEventCount(), 0);
   ASSERT_EQ(callback->touchEventCount(), 0);
@@ -194,7 +194,7 @@
   ASSERT_EQ(callback->penEventCount(), 1);
 
   GetEventHandler().HandleMouseMoveEvent(
-      CreateTestMouseEvent(WebInputEvent::kMouseMove, WebFloatPoint(200, 200)),
+      CreateTestMouseEvent(WebInputEvent::kMouseMove, gfx::PointF(200, 200)),
       Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
 
   ASSERT_EQ(callback->mouseEventCount(), 1);
@@ -218,8 +218,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
       CreateTestPointerEvent(WebInputEvent::kPointerDown,
                              WebPointerProperties::PointerType::kTouch,
-                             WebFloatPoint(150, 200), WebFloatPoint(100, 50),
-                             10, 10, 16, 24),
+                             gfx::PointF(150, 200), gfx::PointF(100, 50), 10,
+                             10, 16, 24),
       {}, {}));
 
   ASSERT_EQ(callback->last_client_x_, 75);
@@ -253,8 +253,8 @@
     WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
         CreateTestPointerEvent(WebInputEvent::kPointerMove,
                                WebPointerProperties::PointerType::kMouse,
-                               WebFloatPoint(150, 210), WebFloatPoint(100, 50),
-                               10, 10),
+                               gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
+                               10),
         {}, {}));
     // The first pointermove event has movement_x/y 0.
     ASSERT_EQ(callback->last_screen_x_, 100);
@@ -265,8 +265,8 @@
     WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
         CreateTestPointerEvent(WebInputEvent::kPointerMove,
                                WebPointerProperties::PointerType::kMouse,
-                               WebFloatPoint(150, 200), WebFloatPoint(132, 29),
-                               10, 10),
+                               gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
+                               10),
         {}, {}));
     // pointermove event movement = event.screenX/Y - last_event.screenX/Y.
     ASSERT_EQ(callback->last_screen_x_, 132);
@@ -277,8 +277,8 @@
     WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
         CreateTestPointerEvent(WebInputEvent::kPointerMove,
                                WebPointerProperties::PointerType::kMouse,
-                               WebFloatPoint(150, 210),
-                               WebFloatPoint(113.8, 32.7), 10, 10),
+                               gfx::PointF(150, 210), gfx::PointF(113.8, 32.7),
+                               10, 10),
         {}, {}));
     // fractional screen coordinates result in fractional movement.
     ASSERT_FLOAT_EQ(callback->last_screen_x_, 113.8);
@@ -295,8 +295,8 @@
     WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
         CreateTestPointerEvent(WebInputEvent::kPointerMove,
                                WebPointerProperties::PointerType::kMouse,
-                               WebFloatPoint(150, 210),
-                               WebFloatPoint(100, 16.25), 1024, -8765),
+                               gfx::PointF(150, 210), gfx::PointF(100, 16.25),
+                               1024, -8765),
         {}, {}));
     ASSERT_EQ(callback->last_screen_x_, 100);
     ASSERT_EQ(callback->last_screen_y_, 16.25);
@@ -323,7 +323,7 @@
 
   WebPointerEvent pointer_event = CreateTestPointerEvent(
       WebInputEvent::kPointerMove, WebPointerProperties::PointerType::kMouse,
-      WebFloatPoint(150, 210), WebFloatPoint(113.8, 32.7), 0, 0);
+      gfx::PointF(150, 210), gfx::PointF(113.8, 32.7), 0, 0);
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(pointer_event));
   ASSERT_FLOAT_EQ(callback->last_movement_x_, 0);
@@ -368,8 +368,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
       CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
                              WebPointerProperties::PointerType::kMouse,
-                             WebFloatPoint(150, 210), WebFloatPoint(100, 50),
-                             10, 10),
+                             gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
+                             10),
       {}, {}));
   // The first pointerrawupdate event has movement_x/y 0.
   ASSERT_EQ(callback->last_screen_x_, 100);
@@ -380,8 +380,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
       CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
                              WebPointerProperties::PointerType::kMouse,
-                             WebFloatPoint(150, 200), WebFloatPoint(132, 29),
-                             10, 10),
+                             gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
+                             10),
       {}, {}));
   // pointerrawupdate event movement = event.screenX/Y - last_event.screenX/Y.
   ASSERT_EQ(callback->last_screen_x_, 132);
@@ -392,8 +392,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
       CreateTestPointerEvent(WebInputEvent::kPointerMove,
                              WebPointerProperties::PointerType::kMouse,
-                             WebFloatPoint(150, 200), WebFloatPoint(144, 30),
-                             10, 10),
+                             gfx::PointF(150, 200), gfx::PointF(144, 30), 10,
+                             10),
       {}, {}));
   // First pointermove, have 0 movements.
   ASSERT_EQ(callback->last_screen_x_, 144);
@@ -404,8 +404,8 @@
   WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
       CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
                              WebPointerProperties::PointerType::kMouse,
-                             WebFloatPoint(150, 200), WebFloatPoint(142, 32),
-                             10, 10),
+                             gfx::PointF(150, 200), gfx::PointF(142, 32), 10,
+                             10),
       {}, {}));
   // pointerrawupdate event's movement is independent from pointermoves.
   ASSERT_EQ(callback->last_screen_x_, 142);
@@ -428,7 +428,7 @@
 
   WebPointerEvent event = CreateTestPointerEvent(
       WebInputEvent::kPointerMove, WebPointerProperties::PointerType::kMouse,
-      WebFloatPoint(150, 210), WebFloatPoint(100, 50), 120, -321);
+      gfx::PointF(150, 210), gfx::PointF(100, 50), 120, -321);
   event.is_raw_movement_event = true;
   WebView().MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(event, {}, {}));
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc
index b994584..960906d 100644
--- a/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -1096,7 +1096,8 @@
     }
   } else if (gesture_event.GetType() == WebInputEvent::kGestureScrollUpdate) {
     if (resize_scrollable_area_ && resize_scrollable_area_->InResizeMode()) {
-      IntPoint pos = RoundedIntPoint(gesture_event.PositionInRootFrame());
+      IntPoint pos =
+          RoundedIntPoint(FloatPoint(gesture_event.PositionInRootFrame()));
       pos.Move(gesture_event.DeltaXInRootFrame(),
                gesture_event.DeltaYInRootFrame());
       resize_scrollable_area_->Resize(pos, offset_from_resize_corner_);
diff --git a/third_party/blink/renderer/core/input/scroll_snap_test.cc b/third_party/blink/renderer/core/input/scroll_snap_test.cc
index a27903a..b95f388a 100644
--- a/third_party/blink/renderer/core/input/scroll_snap_test.cc
+++ b/third_party/blink/renderer/core/input/scroll_snap_test.cc
@@ -93,8 +93,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollBegin,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(x, y));
-  event.SetPositionInScreen(WebFloatPoint(x, y));
+  event.SetPositionInWidget(gfx::PointF(x, y));
+  event.SetPositionInScreen(gfx::PointF(x, y));
   event.data.scroll_begin.delta_x_hint = hint_x;
   event.data.scroll_begin.delta_y_hint = hint_y;
   event.data.scroll_begin.pointer_count = 1;
@@ -110,8 +110,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollUpdate,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(x, y));
-  event.SetPositionInScreen(WebFloatPoint(x, y));
+  event.SetPositionInWidget(gfx::PointF(x, y));
+  event.SetPositionInScreen(gfx::PointF(x, y));
   event.data.scroll_update.delta_x = delta_x;
   event.data.scroll_update.delta_y = delta_y;
   if (is_in_inertial_phase) {
@@ -127,8 +127,8 @@
   WebGestureEvent event(WebInputEvent::kGestureScrollEnd,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                         WebGestureDevice::kTouchscreen);
-  event.SetPositionInWidget(WebFloatPoint(x, y));
-  event.SetPositionInScreen(WebFloatPoint(x, y));
+  event.SetPositionInWidget(gfx::PointF(x, y));
+  event.SetPositionInScreen(gfx::PointF(x, y));
   event.data.scroll_end.inertial_phase =
       is_in_inertial_phase ? WebGestureEvent::InertialPhaseState::kMomentum
                            : WebGestureEvent::InertialPhaseState::kNonMomentum;
diff --git a/third_party/blink/renderer/core/input/touch_action_test.cc b/third_party/blink/renderer/core/input/touch_action_test.cc
index 88333851..956c396e 100644
--- a/third_party/blink/renderer/core/input/touch_action_test.cc
+++ b/third_party/blink/renderer/core/input/touch_action_test.cc
@@ -382,8 +382,8 @@
       type,
       WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                            WebPointerProperties::Button::kLeft,
-                           WebFloatPoint(client_point.X(), client_point.Y()),
-                           WebFloatPoint(client_point.X(), client_point.Y())),
+                           gfx::PointF(client_point.X(), client_point.Y()),
+                           gfx::PointF(client_point.X(), client_point.Y())),
       10.0f, 10.0f);
   if (type == WebInputEvent::kPointerCancel)
     event.dispatch_type = WebInputEvent::kEventNonBlocking;
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.cc b/third_party/blink/renderer/core/input/touch_event_manager.cc
index 55751582..915201f 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.cc
+++ b/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -206,18 +206,19 @@
       point_attr->event_.WebPointerEventInRootFrame();
   float scale_factor = 1.0f / target_frame->PageZoomFactor();
 
-  FloatPoint document_point =
-      target_frame->View()
-          ->RootFrameToDocument(transformed_event.PositionInWidget())
-          .ScaledBy(scale_factor);
+  FloatPoint document_point = target_frame->View()
+                                  ->RootFrameToDocument(FloatPoint(
+                                      transformed_event.PositionInWidget()))
+                                  .ScaledBy(scale_factor);
   FloatSize adjusted_radius =
       FloatSize(transformed_event.width / 2.f, transformed_event.height / 2.f)
           .ScaledBy(scale_factor);
 
   return MakeGarbageCollected<Touch>(
       target_frame, touch_node, point_attr->event_.id,
-      transformed_event.PositionInScreen(), document_point, adjusted_radius,
-      transformed_event.rotation_angle, transformed_event.force, region_id);
+      FloatPoint(transformed_event.PositionInScreen()), document_point,
+      adjusted_radius, transformed_event.rotation_angle,
+      transformed_event.force, region_id);
 }
 
 WebCoalescedInputEvent TouchEventManager::GenerateWebCoalescedInputEvent() {
@@ -533,7 +534,7 @@
     if (touch_sequence_document_->GetFrame()) {
       HitTestLocation location(PhysicalOffset::FromFloatPointRound(
           touch_sequence_document_->GetFrame()->View()->ConvertFromRootFrame(
-              event.PositionInWidget())));
+              FloatPoint(event.PositionInWidget()))));
       result = event_handling_util::HitTestResultInFrame(
           touch_sequence_document_->GetFrame(), location, hit_type);
       Node* node = result.InnerNode();
diff --git a/third_party/blink/renderer/core/input/touch_event_manager_test.cc b/third_party/blink/renderer/core/input/touch_event_manager_test.cc
index f97b588..255b908 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager_test.cc
+++ b/third_party/blink/renderer/core/input/touch_event_manager_test.cc
@@ -28,7 +28,7 @@
         type,
         WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
                              WebPointerProperties::Button::kLeft,
-                             WebFloatPoint(100, 100), WebFloatPoint(100, 100)),
+                             gfx::PointF(100, 100), gfx::PointF(100, 100)),
         1, 1);
     event.SetFrameScale(1);
     return event;
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
index 5403152..cb94f1a 100644
--- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
+++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -106,8 +106,6 @@
           web_view->GetPage()->GetSettings().GetCookieEnabled()),
       document_cookie_disabled_(false) {}
 
-DevToolsEmulator::~DevToolsEmulator() = default;
-
 void DevToolsEmulator::Trace(blink::Visitor* visitor) {}
 
 void DevToolsEmulator::SetTextAutosizingEnabled(bool enabled) {
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
index 4d7da9b..8a9fff1 100644
--- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
+++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
@@ -25,7 +25,6 @@
     : public GarbageCollected<DevToolsEmulator> {
  public:
   explicit DevToolsEmulator(WebViewImpl*);
-  ~DevToolsEmulator();
   void Trace(blink::Visitor*);
 
   // Settings overrides.
diff --git a/third_party/blink/renderer/core/inspector/dom_patch_support.cc b/third_party/blink/renderer/core/inspector/dom_patch_support.cc
index 14cd83f..e2b1666 100644
--- a/third_party/blink/renderer/core/inspector/dom_patch_support.cc
+++ b/third_party/blink/renderer/core/inspector/dom_patch_support.cc
@@ -68,7 +68,7 @@
     new_document = XMLDocument::CreateSVG(init);
   else if (GetDocument().IsXHTMLDocument())
     new_document = XMLDocument::CreateXHTML(init);
-  else if (GetDocument().IsXMLDocument())
+  else if (IsA<XMLDocument>(GetDocument()))
     new_document = MakeGarbageCollected<XMLDocument>(init);
 
   DCHECK(new_document);
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc
index a0f0465..8be488b 100644
--- a/third_party/blink/renderer/core/inspector/inspect_tools.cc
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -73,17 +73,17 @@
 Node* HoveredNodeForEvent(LocalFrame* frame,
                           const WebGestureEvent& event,
                           bool ignore_pointer_events_none) {
-  return HoveredNodeForPoint(frame,
-                             RoundedIntPoint(event.PositionInRootFrame()),
-                             ignore_pointer_events_none);
+  return HoveredNodeForPoint(
+      frame, RoundedIntPoint(FloatPoint(event.PositionInRootFrame())),
+      ignore_pointer_events_none);
 }
 
 Node* HoveredNodeForEvent(LocalFrame* frame,
                           const WebMouseEvent& event,
                           bool ignore_pointer_events_none) {
-  return HoveredNodeForPoint(frame,
-                             RoundedIntPoint(event.PositionInRootFrame()),
-                             ignore_pointer_events_none);
+  return HoveredNodeForPoint(
+      frame, RoundedIntPoint(FloatPoint(event.PositionInRootFrame())),
+      ignore_pointer_events_none);
 }
 
 Node* HoveredNodeForEvent(LocalFrame* frame,
@@ -91,7 +91,7 @@
                           bool ignore_pointer_events_none) {
   WebPointerEvent transformed_point = event.WebPointerEventInRootFrame();
   return HoveredNodeForPoint(
-      frame, RoundedIntPoint(transformed_point.PositionInWidget()),
+      frame, RoundedIntPoint(FloatPoint(transformed_point.PositionInWidget())),
       ignore_pointer_events_none);
 }
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
index 5b9332d..e47540e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
@@ -116,9 +116,9 @@
           .setFill(computed_timing->fill())
           .setEasing(easing)
           .build();
-  if (effect->target()) {
+  if (effect->EffectTarget()) {
     animation_object->setBackendNodeId(
-        IdentifiersFactory::IntIdForNode(effect->target()));
+        IdentifiersFactory::IntIdForNode(effect->EffectTarget()));
   }
   return animation_object;
 }
@@ -301,7 +301,7 @@
     }
 
     auto* new_effect = MakeGarbageCollected<KeyframeEffect>(
-        old_effect->target(), new_model, old_effect->SpecifiedTiming());
+        old_effect->EffectTarget(), new_model, old_effect->SpecifiedTiming());
     is_cloning_ = true;
     blink::Animation* clone =
         blink::Animation::Create(new_effect, animation->timeline());
@@ -380,7 +380,8 @@
     return response;
   if (id_to_animation_clone_.at(animation_id))
     animation = id_to_animation_clone_.at(animation_id);
-  const Element* element = To<KeyframeEffect>(animation->effect())->target();
+  const Element* element =
+      To<KeyframeEffect>(animation->effect())->EffectTarget();
   Document* document = element->ownerDocument();
   LocalFrame* frame = document ? document->GetFrame() : nullptr;
   ScriptState* script_state =
@@ -432,7 +433,7 @@
     NOTREACHED();
   }
 
-  Element* element = effect->target();
+  Element* element = effect->EffectTarget();
   HeapVector<Member<CSSStyleDeclaration>> styles =
       css_agent_->MatchingStyles(element);
   Digestor digestor(kHashAlgorithmSha1);
diff --git a/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h b/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
index e4572b8..690a68b 100644
--- a/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h
@@ -40,12 +40,6 @@
 class CORE_EXPORT InspectorApplicationCacheAgent final
     : public InspectorBaseAgent<protocol::ApplicationCache::Metainfo> {
  public:
-  static InspectorApplicationCacheAgent* Create(
-      InspectedFrames* inspected_frames) {
-    return MakeGarbageCollected<InspectorApplicationCacheAgent>(
-        inspected_frames);
-  }
-
   explicit InspectorApplicationCacheAgent(InspectedFrames*);
   ~InspectorApplicationCacheAgent() override = default;
   void Trace(blink::Visitor*) override;
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 c3b49c0b..d439f54 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -1869,7 +1869,7 @@
       css_style_sheet_to_inspector_style_sheet_.at(style_sheet);
   if (!inspector_style_sheet) {
     Document* document = style_sheet->OwnerDocument();
-    inspector_style_sheet = InspectorStyleSheet::Create(
+    inspector_style_sheet = MakeGarbageCollected<InspectorStyleSheet>(
         network_agent_, style_sheet, DetectOrigin(style_sheet, document),
         InspectorDOMAgent::DocumentURLString(document), this,
         resource_container_);
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
index 6519f27..6332c4d 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -52,6 +52,7 @@
 #include "third_party/blink/renderer/core/dom/static_node_list.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/dom/v0_insertion_point.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/core/editing/serializers/serialization.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -899,7 +900,7 @@
 
   Document* document =
       IsA<Document>(node) ? To<Document>(node) : node->ownerDocument();
-  if (!document || (!document->IsHTMLDocument() && !document->IsXMLDocument()))
+  if (!document || (!document->IsHTMLDocument() && !IsA<XMLDocument>(document)))
     return Response::Error("Not an HTML/XML document");
 
   Node* new_node = nullptr;
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
index ea43902b..776fda5 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
@@ -26,13 +26,6 @@
 class CORE_EXPORT InspectorDOMSnapshotAgent final
     : public InspectorBaseAgent<protocol::DOMSnapshot::Metainfo> {
  public:
-  static InspectorDOMSnapshotAgent* Create(
-      InspectedFrames* inspected_frames,
-      InspectorDOMDebuggerAgent* dom_debugger_agent) {
-    return MakeGarbageCollected<InspectorDOMSnapshotAgent>(inspected_frames,
-                                                           dom_debugger_agent);
-  }
-
   InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*);
   ~InspectorDOMSnapshotAgent() override;
   void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/inspector/inspector_memory_agent.h b/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
index 264b9ca1..bfabd6ef 100644
--- a/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_memory_agent.h
@@ -43,10 +43,6 @@
 class CORE_EXPORT InspectorMemoryAgent final
     : public InspectorBaseAgent<protocol::Memory::Metainfo> {
  public:
-  static InspectorMemoryAgent* Create(InspectedFrames* frames) {
-    return MakeGarbageCollected<InspectorMemoryAgent>(frames);
-  }
-
   explicit InspectorMemoryAgent(InspectedFrames*);
   ~InspectorMemoryAgent() override;
   void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index 11b2fcf..0ae28ff 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -64,6 +64,7 @@
 #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
 #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -495,11 +496,20 @@
   bool hasPostData =
       FormDataToString(request.HttpBody(), max_body_size, &postData);
   KURL url = request.Url();
+  // protocol::Network::Request doesn't have a separate referrer string member
+  // like blink::ResourceRequest, so here we add ResourceRequest's referrer
+  // string to the protocol request's headers manually.
+  auto headers = request.HttpHeaderFields();
+
+  // The request's referrer must be generated at this point.
+  DCHECK_NE(request.ReferrerString(), Referrer::ClientReferrerString());
+  headers.Set(http_names::kReferer, AtomicString(request.ReferrerString()));
+
   std::unique_ptr<protocol::Network::Request> result =
       protocol::Network::Request::create()
           .setUrl(UrlWithoutFragment(url).GetString())
           .setMethod(request.HttpMethod())
-          .setHeaders(BuildObjectForHeaders(request.HttpHeaderFields()))
+          .setHeaders(BuildObjectForHeaders(headers))
           .setInitialPriority(ResourcePriorityJSON(request.Priority()))
           .setReferrerPolicy(GetReferrerPolicy(request.GetReferrerPolicy()))
           .build();
@@ -859,13 +869,11 @@
       AtomicString header_name = AtomicString(key);
       // When overriding referer, also override referrer policy
       // for this request to assure the request will be allowed.
-      // TODO(domfarolino): Stop setting the HTTPReferrer header, and instead
-      // use ResourceRequest::referrer_. See https://crbug.com/850813. This
-      // seems to require storing the referrer info that is currently stored
-      // inside state_'s kExtraRequestHeaders, somewhere else.
+      // TODO: Should we store the referrer header somewhere other than
+      // |extra_request_headers_|?
       if (header_name.LowerASCII() == http_names::kReferer.LowerASCII()) {
-        request.SetHttpReferrer(
-            Referrer(value, network::mojom::ReferrerPolicy::kAlways));
+        request.SetReferrerString(value);
+        request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
       } else {
         request.SetHttpHeaderField(header_name, AtomicString(value));
       }
@@ -1127,7 +1135,7 @@
                                         const HTTPHeaderMap& headers,
                                         bool include_credentials) {
   DCHECK(!pending_request_type_);
-  pending_xhr_replay_data_ = XHRReplayData::Create(
+  pending_xhr_replay_data_ = MakeGarbageCollected<XHRReplayData>(
       execution_context, method, UrlWithoutFragment(url), async,
       form_data ? form_data->DeepCopy() : nullptr, include_credentials);
   for (const auto& header : headers)
diff --git a/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc b/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
index 1fca67c..84dfda0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_resource_content_loader.cc
@@ -95,7 +95,8 @@
 
     ResourceFetcher* fetcher = document->Fetcher();
     if (base::FeatureList::IsEnabled(
-            features::kHtmlImportsRequestInitiatorLock)) {
+            features::kHtmlImportsRequestInitiatorLock) &&
+        document->ImportsController()) {
       // For @imports from HTML imported Documents, we use the
       // context document for getting origin and ResourceFetcher to use the
       // main Document's origin, while using the element document for
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
index 79d5913..21ad14e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -729,8 +729,6 @@
   DCHECK(style_);
 }
 
-InspectorStyle::~InspectorStyle() = default;
-
 std::unique_ptr<protocol::CSS::CSSStyle> InspectorStyle::BuildObjectForStyle() {
   std::unique_ptr<protocol::CSS::CSSStyle> result = StyleWithProperties();
   if (source_data_) {
@@ -947,18 +945,6 @@
   return true;
 }
 
-InspectorStyleSheet* InspectorStyleSheet::Create(
-    InspectorNetworkAgent* network_agent,
-    CSSStyleSheet* page_style_sheet,
-    const String& origin,
-    const String& document_url,
-    InspectorStyleSheetBase::Listener* listener,
-    InspectorResourceContainer* resource_container) {
-  return MakeGarbageCollected<InspectorStyleSheet>(
-      network_agent, page_style_sheet, origin, document_url, listener,
-      resource_container);
-}
-
 InspectorStyleSheet::InspectorStyleSheet(
     InspectorNetworkAgent* network_agent,
     CSSStyleSheet* page_style_sheet,
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.h b/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
index c59f456f..07a413f 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
@@ -57,7 +57,6 @@
   InspectorStyle(CSSStyleDeclaration*,
                  CSSRuleSourceData*,
                  InspectorStyleSheetBase* parent_style_sheet);
-  ~InspectorStyle();
 
   CSSStyleDeclaration* CssStyle() { return style_.Get(); }
   std::unique_ptr<protocol::CSS::CSSStyle> BuildObjectForStyle();
@@ -122,13 +121,6 @@
 
 class InspectorStyleSheet : public InspectorStyleSheetBase {
  public:
-  static InspectorStyleSheet* Create(InspectorNetworkAgent*,
-                                     CSSStyleSheet* page_style_sheet,
-                                     const String& origin,
-                                     const String& document_url,
-                                     InspectorStyleSheetBase::Listener*,
-                                     InspectorResourceContainer*);
-
   InspectorStyleSheet(InspectorNetworkAgent*,
                       CSSStyleSheet* page_style_sheet,
                       const String& origin,
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index 45ec808..beb7f22 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -1352,7 +1352,7 @@
   if (const AnimationEffect* effect = animation.effect()) {
     value->SetString("name", animation.id());
     if (auto* frame_effect = DynamicTo<KeyframeEffect>(effect)) {
-      if (Element* target = frame_effect->target())
+      if (Element* target = frame_effect->EffectTarget())
         SetNodeInfo(value.get(), target, "nodeId", "nodeName");
     }
   }
diff --git a/third_party/blink/renderer/core/inspector/network_resources_data.cc b/third_party/blink/renderer/core/inspector/network_resources_data.cc
index 1253713..2adfd13 100644
--- a/third_party/blink/renderer/core/inspector/network_resources_data.cc
+++ b/third_party/blink/renderer/core/inspector/network_resources_data.cc
@@ -41,18 +41,6 @@
   return status_code >= 400;
 }
 
-// static
-XHRReplayData* XHRReplayData::Create(ExecutionContext* execution_context,
-                                     const AtomicString& method,
-                                     const KURL& url,
-                                     bool async,
-                                     scoped_refptr<EncodedFormData> form_data,
-                                     bool include_credentials) {
-  return MakeGarbageCollected<XHRReplayData>(execution_context, method, url,
-                                             async, std::move(form_data),
-                                             include_credentials);
-}
-
 void XHRReplayData::AddHeader(const AtomicString& key,
                               const AtomicString& value) {
   headers_.Set(key, value);
diff --git a/third_party/blink/renderer/core/inspector/network_resources_data.h b/third_party/blink/renderer/core/inspector/network_resources_data.h
index a80765f..0157cc6 100644
--- a/third_party/blink/renderer/core/inspector/network_resources_data.h
+++ b/third_party/blink/renderer/core/inspector/network_resources_data.h
@@ -50,13 +50,6 @@
 
 class XHRReplayData final : public GarbageCollected<XHRReplayData> {
  public:
-  static XHRReplayData* Create(ExecutionContext*,
-                               const AtomicString& method,
-                               const KURL&,
-                               bool async,
-                               scoped_refptr<EncodedFormData>,
-                               bool include_credentials);
-
   XHRReplayData(ExecutionContext*,
                 const AtomicString& method,
                 const KURL&,
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
index ac40b7c..6cf51696 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -244,8 +244,6 @@
   ComputeGeometry(root_geometry, root, target, thresholds);
 }
 
-IntersectionGeometry::~IntersectionGeometry() = default;
-
 void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
                                            const LayoutObject* root,
                                            const LayoutObject* target,
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
index e912995..4f4a7f0 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h
@@ -69,7 +69,6 @@
                        unsigned flags);
 
   IntersectionGeometry(const IntersectionGeometry&) = default;
-  ~IntersectionGeometry();
 
   bool ShouldReportRootBounds() const {
     return flags_ & kShouldReportRootBounds;
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn
index fd932af..b1917337 100644
--- a/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -275,6 +275,8 @@
     "ng/custom/css_layout_definition.h",
     "ng/custom/css_layout_worklet.cc",
     "ng/custom/css_layout_worklet.h",
+    "ng/custom/custom_intrinsic_sizes.cc",
+    "ng/custom/custom_intrinsic_sizes.h",
     "ng/custom/custom_layout_child.cc",
     "ng/custom/custom_layout_child.h",
     "ng/custom/custom_layout_constraints.cc",
diff --git a/third_party/blink/renderer/core/layout/geometry/physical_rect.h b/third_party/blink/renderer/core/layout/geometry/physical_rect.h
index 3543629..58a3f51 100644
--- a/third_party/blink/renderer/core/layout/geometry/physical_rect.h
+++ b/third_party/blink/renderer/core/layout/geometry/physical_rect.h
@@ -107,10 +107,6 @@
            !size.width.HasFraction() && !size.height.HasFraction();
   }
 
-  PhysicalRect operator+(const PhysicalOffset&) const {
-    return {this->offset + offset, size};
-  }
-
   void Unite(const PhysicalRect&);
   void UniteIfNonZero(const PhysicalRect&);
   void UniteEvenIfEmpty(const PhysicalRect&);
diff --git a/third_party/blink/renderer/core/layout/hit_test_location.cc b/third_party/blink/renderer/core/layout/hit_test_location.cc
index e68cb3b..bae6baf 100644
--- a/third_party/blink/renderer/core/layout/hit_test_location.cc
+++ b/third_party/blink/renderer/core/layout/hit_test_location.cc
@@ -88,8 +88,6 @@
 
 HitTestLocation::HitTestLocation(const HitTestLocation& other) = default;
 
-HitTestLocation::~HitTestLocation() = default;
-
 HitTestLocation& HitTestLocation::operator=(const HitTestLocation& other) =
     default;
 
diff --git a/third_party/blink/renderer/core/layout/hit_test_location.h b/third_party/blink/renderer/core/layout/hit_test_location.h
index 08b8905..016b930 100644
--- a/third_party/blink/renderer/core/layout/hit_test_location.h
+++ b/third_party/blink/renderer/core/layout/hit_test_location.h
@@ -62,7 +62,6 @@
 
   HitTestLocation(const HitTestLocation&, const PhysicalOffset& offset);
   HitTestLocation(const HitTestLocation&);
-  ~HitTestLocation();
   HitTestLocation& operator=(const HitTestLocation&);
 
   const PhysicalOffset& Point() const { return point_; }
diff --git a/third_party/blink/renderer/core/layout/layout_counter.cc b/third_party/blink/renderer/core/layout/layout_counter.cc
index d7c8f9d..da69a853 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -474,23 +474,21 @@
 
 scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
   if (!counter_node_) {
-    LayoutObject* before_after_container = Parent();
+    LayoutObject* container = Parent();
     while (true) {
-      if (!before_after_container)
+      if (!container)
         return nullptr;
-      if (!before_after_container->IsAnonymous() &&
-          !before_after_container->IsPseudoElement())
-        return nullptr;  // LayoutCounters are restricted to before and after
-                         // pseudo elements
-      PseudoId container_style = before_after_container->StyleRef().StyleType();
+      if (!container->IsAnonymous() && !container->IsPseudoElement())
+        return nullptr;  // LayoutCounters are restricted to before, after and
+                         // marker pseudo elements
+      PseudoId container_style = container->StyleRef().StyleType();
       if ((container_style == kPseudoIdBefore) ||
           (container_style == kPseudoIdAfter) ||
           (container_style == kPseudoIdMarker))
         break;
-      before_after_container = before_after_container->Parent();
+      container = container->Parent();
     }
-    MakeCounterNodeIfNeeded(*before_after_container, counter_.Identifier(),
-                            true)
+    MakeCounterNodeIfNeeded(*container, counter_.Identifier(), true)
         ->AddLayoutObject(const_cast<LayoutCounter*>(this));
     DCHECK(counter_node_);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
index 3dbbe77..afd0afb 100644
--- a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
@@ -1021,6 +1021,8 @@
     // Children must be repositioned.
     LayoutUnit offset;
     if (StyleRef().BoxPack() == EBoxPack::kJustify) {
+      UseCounter::Count(GetDocument(),
+                        WebFeature::kWebkitBoxPackJustifyDoesSomething);
       // Determine the total number of children.
       int total_children = 0;
       for (LayoutBox* child = iterator.First(); child;
@@ -1054,10 +1056,15 @@
         }
       }
     } else {
-      if (StyleRef().BoxPack() == EBoxPack::kCenter)
+      if (StyleRef().BoxPack() == EBoxPack::kCenter) {
+        UseCounter::Count(GetDocument(),
+                          WebFeature::kWebkitBoxPackCenterDoesSomething);
         offset += remaining_space / 2;
-      else  // END
+      } else {  // END
+        UseCounter::Count(GetDocument(),
+                          WebFeature::kWebkitBoxPackEndDoesSomething);
         offset += remaining_space;
+      }
       for (LayoutBox* child = iterator.First(); child;
            child = iterator.Next()) {
         if (child->IsOutOfFlowPositioned())
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.cc b/third_party/blink/renderer/core/layout/layout_list_marker.cc
index fd203ff..0da65289 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -519,24 +519,13 @@
 }
 
 void LayoutListMarker::ListItemStyleDidChange() {
-  Node* list_item = list_item_->GetNode();
+  Element* list_item = To<Element>(list_item_->GetNode());
   const ComputedStyle* cached_marker_style =
-      list_item->IsPseudoElement()
-          ? nullptr
-          : To<Element>(list_item)->CachedStyleForPseudoElement(
-                kPseudoIdMarker);
-  scoped_refptr<ComputedStyle> new_style;
-  if (cached_marker_style) {
-    new_style = ComputedStyle::Clone(*cached_marker_style);
-  } else {
-    // The marker always inherits from the list item, regardless of where it
-    // might end up (e.g., in some deeply nested line box). See CSS3 spec.
-    new_style = ComputedStyle::Create();
-    new_style->InheritFrom(list_item_->StyleRef());
-    new_style->SetStyleType(kPseudoIdMarker);
-    new_style->SetUnicodeBidi(UnicodeBidi::kIsolate);
-    new_style->SetFontVariantNumericSpacing(FontVariantNumeric::kTabularNums);
-  }
+      list_item->CachedStyleForPseudoElement(kPseudoIdMarker);
+  scoped_refptr<ComputedStyle> new_style =
+      cached_marker_style ? ComputedStyle::Clone(*cached_marker_style)
+                          : list_item->StyleForPseudoElement(kPseudoIdMarker);
+  DCHECK(new_style);
   if (Style()) {
     // Reuse the current margins. Otherwise resetting the margins to initial
     // values would trigger unnecessary layout.
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
index 7d60704..6544cee 100644
--- a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
@@ -30,7 +30,7 @@
 
   void SimulateInput() {
     GetLayoutShiftTracker().NotifyInput(WebMouseEvent(
-        WebInputEvent::kMouseDown, WebFloatPoint(), WebFloatPoint(),
+        WebInputEvent::kMouseDown, gfx::PointF(), gfx::PointF(),
         WebPointerProperties::Button::kLeft, 0,
         WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now()));
   }
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h
index b6cfe7d..121a6e37 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
 #include "third_party/blink/renderer/platform/fonts/font_description.h"
 #include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
+#include "third_party/blink/renderer/platform/geometry/int_rect.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
 #include "third_party/blink/renderer/platform/geometry/length_box.h"
 #include "third_party/blink/renderer/platform/geometry/length_size.h"
diff --git a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
index 47bdaee8..8934fed2 100644
--- a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -961,8 +961,11 @@
   element->GetDocument().UpdateStyleAndLayout();
   WTF::TextStream stream;
   bool is_first_counter = true;
-  // The counter layoutObjects should be children of :before or :after
-  // pseudo-elements.
+  // The counter LayoutObjects should be children of ::marker, ::before or
+  // ::after pseudo-elements.
+  if (LayoutObject* marker =
+          element->PseudoElementLayoutObject(kPseudoIdMarker))
+    WriteCounterValuesFromChildren(stream, marker, is_first_counter);
   if (LayoutObject* before =
           element->PseudoElementLayoutObject(kPseudoIdBefore))
     WriteCounterValuesFromChildren(stream, before, is_first_counter);
diff --git a/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc b/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
index 3ac1c1f..00f8f37 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
@@ -13,6 +13,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_fragment_result_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_result_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h"
 #include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h"
@@ -24,6 +26,7 @@
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.h"
+#include "third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
@@ -33,10 +36,31 @@
 
 namespace blink {
 
+namespace {
+
+void GatherChildren(const NGBlockNode& node,
+                    CustomLayoutScope* custom_layout_scope,
+                    HeapVector<Member<CustomLayoutChild>>* children) {
+  // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
+  // time improves performance in any noticeable way.
+  for (NGLayoutInputNode child = node.FirstChild(); child;
+       child = child.NextSibling()) {
+    if (child.IsOutOfFlowPositioned())
+      continue;
+
+    CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
+    layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
+    DCHECK(layout_child);
+    children->push_back(layout_child);
+  }
+}
+
+}  // anonymous namespace
+
 CSSLayoutDefinition::CSSLayoutDefinition(
     ScriptState* script_state,
     V8NoArgumentConstructor* constructor,
-    V8Function* intrinsic_sizes,
+    V8IntrinsicSizesCallback* intrinsic_sizes,
     V8LayoutCallback* layout,
     const Vector<CSSPropertyID>& native_invalidation_properties,
     const Vector<AtomicString>& custom_invalidation_properties,
@@ -44,7 +68,7 @@
     const Vector<AtomicString>& child_custom_invalidation_properties)
     : script_state_(script_state),
       constructor_(constructor),
-      unused_intrinsic_sizes_(intrinsic_sizes),
+      intrinsic_sizes_(intrinsic_sizes),
       layout_(layout),
       native_invalidation_properties_(native_invalidation_properties),
       custom_invalidation_properties_(custom_invalidation_properties),
@@ -77,19 +101,8 @@
 
   ScriptState::Scope scope(script_state);
 
-  // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
-  // time improves performance in any noticeable way.
   HeapVector<Member<CustomLayoutChild>> children;
-  for (NGLayoutInputNode child = node.FirstChild(); child;
-       child = child.NextSibling()) {
-    if (child.IsOutOfFlowPositioned())
-      continue;
-
-    CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
-    layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
-    DCHECK(layout_child);
-    children.push_back(layout_child);
-  }
+  GatherChildren(node, custom_layout_scope, &children);
 
   CustomLayoutEdges* edges =
       MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
@@ -132,7 +145,7 @@
   // Run the work queue until exhaustion.
   while (!custom_layout_scope->Queue()->IsEmpty()) {
     for (auto& task : *custom_layout_scope->Queue())
-      task.Run(space, node.Style());
+      task.Run(node, space, node.Style(), border_scrollbar_padding);
     custom_layout_scope->Queue()->clear();
     {
       v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
@@ -199,6 +212,105 @@
   return true;
 }
 
+bool CSSLayoutDefinition::Instance::IntrinsicSizes(
+    const NGConstraintSpace& space,
+    const Document& document,
+    const NGBlockNode& node,
+    const LogicalSize& border_box_size,
+    const NGBoxStrut& border_scrollbar_padding,
+    CustomLayoutScope* custom_layout_scope,
+    IntrinsicSizesResultOptions* intrinsic_sizes_result_options) {
+  ScriptState* script_state = definition_->GetScriptState();
+  v8::Isolate* isolate = script_state->GetIsolate();
+
+  if (!script_state->ContextIsValid())
+    return false;
+
+  ScriptState::Scope scope(script_state);
+
+  HeapVector<Member<CustomLayoutChild>> children;
+  GatherChildren(node, custom_layout_scope, &children);
+
+  CustomLayoutEdges* edges =
+      MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
+
+  // TODO(ikilpatrick): Instead of creating a new style_map each time here,
+  // store on LayoutCustom, and update when the style changes.
+  StylePropertyMapReadOnly* style_map =
+      MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
+          document, node.Style(), definition_->native_invalidation_properties_,
+          definition_->custom_invalidation_properties_);
+
+  ScriptValue return_value;
+  if (!definition_->intrinsic_sizes_
+           ->Invoke(instance_.NewLocal(isolate), children, edges, style_map)
+           .To(&return_value))
+    return false;
+
+  ExecutionContext* execution_context = ExecutionContext::From(script_state);
+  v8::MicrotaskQueue* microtask_queue = ToMicrotaskQueue(execution_context);
+  DCHECK(microtask_queue);
+
+  ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
+                                 "CSSLayoutAPI", "IntrinsicSizes");
+
+  v8::Local<v8::Value> v8_return_value = return_value.V8Value();
+  if (v8_return_value.IsEmpty() || !v8_return_value->IsPromise()) {
+    execution_context->AddConsoleMessage(ConsoleMessage::Create(
+        mojom::ConsoleMessageSource::kJavaScript,
+        mojom::ConsoleMessageLevel::kInfo,
+        "The intrinsicSizes function must be async or return a "
+        "promise, falling back to block layout."));
+    return false;
+  }
+
+  // Run the work queue until exhaustion.
+  while (!custom_layout_scope->Queue()->IsEmpty()) {
+    for (auto& task : *custom_layout_scope->Queue())
+      task.Run(node, space, node.Style(), border_scrollbar_padding);
+    custom_layout_scope->Queue()->clear();
+    {
+      v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
+                                           v8::MicrotasksScope::kRunMicrotasks);
+    }
+  }
+
+  if (exception_state.HadException()) {
+    ReportException(&exception_state);
+    return false;
+  }
+
+  v8::Local<v8::Promise> v8_result_promise =
+      v8::Local<v8::Promise>::Cast(v8_return_value);
+
+  if (v8_result_promise->State() != v8::Promise::kFulfilled) {
+    execution_context->AddConsoleMessage(ConsoleMessage::Create(
+        mojom::ConsoleMessageSource::kJavaScript,
+        mojom::ConsoleMessageLevel::kInfo,
+        "The intrinsicSizes function promise must resolve, "
+        "falling back to block layout."));
+    return false;
+  }
+  v8::Local<v8::Value> inner_value = v8_result_promise->Result();
+
+  // Attempt to convert the result.
+  V8IntrinsicSizesResultOptions::ToImpl(
+      isolate, inner_value, intrinsic_sizes_result_options, exception_state);
+
+  if (exception_state.HadException()) {
+    V8ScriptRunner::ReportException(isolate, exception_state.GetException());
+    exception_state.ClearException();
+    execution_context->AddConsoleMessage(
+        ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
+                               mojom::ConsoleMessageLevel::kInfo,
+                               "Unable to parse the intrinsicSizes function "
+                               "result, falling back to block layout."));
+    return false;
+  }
+
+  return true;
+}
+
 void CSSLayoutDefinition::Instance::ReportException(
     ExceptionState* exception_state) {
   ScriptState* script_state = definition_->GetScriptState();
@@ -241,7 +353,7 @@
 
 void CSSLayoutDefinition::Trace(Visitor* visitor) {
   visitor->Trace(constructor_);
-  visitor->Trace(unused_intrinsic_sizes_);
+  visitor->Trace(intrinsic_sizes_);
   visitor->Trace(layout_);
   visitor->Trace(script_state_);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h b/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
index b8690a9..5ce7aa7 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
+++ b/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h
@@ -17,13 +17,14 @@
 
 class CustomLayoutScope;
 class FragmentResultOptions;
+class IntrinsicSizesResultOptions;
 struct LogicalSize;
 class NGBlockNode;
 struct NGBoxStrut;
 class NGConstraintSpace;
 class ScriptState;
 class SerializedScriptValue;
-class V8Function;
+class V8IntrinsicSizesCallback;
 class V8LayoutCallback;
 class V8NoArgumentConstructor;
 
@@ -36,7 +37,7 @@
   CSSLayoutDefinition(
       ScriptState*,
       V8NoArgumentConstructor* constructor,
-      V8Function* intrinsic_sizes,
+      V8IntrinsicSizesCallback* intrinsic_sizes,
       V8LayoutCallback* layout,
       const Vector<CSSPropertyID>& native_invalidation_properties,
       const Vector<AtomicString>& custom_invalidation_properties,
@@ -62,6 +63,16 @@
                 FragmentResultOptions*,
                 scoped_refptr<SerializedScriptValue>* fragment_result_data);
 
+    // Runs the web developer defined intrinsicSizes, returns true if everything
+    // succeeded. It populates the IntrinsicSizesResultOptions dictionary.
+    bool IntrinsicSizes(const NGConstraintSpace&,
+                        const Document&,
+                        const NGBlockNode&,
+                        const LogicalSize& border_box_size,
+                        const NGBoxStrut& border_scrollbar_padding,
+                        CustomLayoutScope*,
+                        IntrinsicSizesResultOptions*);
+
     void Trace(blink::Visitor*);
 
    private:
@@ -103,7 +114,7 @@
   // sizes function, and layout function alive. It participates in wrapper
   // tracing as it holds onto V8 wrappers.
   Member<V8NoArgumentConstructor> constructor_;
-  Member<V8Function> unused_intrinsic_sizes_;
+  Member<V8IntrinsicSizesCallback> intrinsic_sizes_;
   Member<V8LayoutCallback> layout_;
 
   // If a constructor call ever fails, we'll refuse to create any more
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
new file mode 100644
index 0000000..7dd9c99
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h"
+
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h"
+
+namespace blink {
+
+CustomIntrinsicSizes::CustomIntrinsicSizes(CustomLayoutChild* child,
+                                           CustomLayoutToken* token,
+                                           double min_content_size,
+                                           double max_content_size)
+    : child_(child),
+      token_(token),
+      min_content_size_(min_content_size),
+      max_content_size_(max_content_size) {}
+
+const NGLayoutInputNode& CustomIntrinsicSizes::GetLayoutNode() const {
+  return child_->GetLayoutNode();
+}
+
+void CustomIntrinsicSizes::Trace(Visitor* visitor) {
+  visitor->Trace(child_);
+  visitor->Trace(token_);
+  ScriptWrappable::Trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h b/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
new file mode 100644
index 0000000..4018706
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
+
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class NGLayoutInputNode;
+class CustomLayoutChild;
+
+// This represents the result of intrinsicSizes (on a LayoutChild).
+//
+// This should eventually mirror the information in a MinMaxSize, it has the
+// additional capability that it is exposed to web developers.
+class CustomIntrinsicSizes : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  CustomIntrinsicSizes(CustomLayoutChild*,
+                       CustomLayoutToken*,
+                       double min_content_size,
+                       double max_content_size);
+  ~CustomIntrinsicSizes() override = default;
+
+  CustomIntrinsicSizes(const CustomIntrinsicSizes&) = delete;
+  CustomIntrinsicSizes& operator=(const CustomIntrinsicSizes&) = delete;
+
+  double minContentSize() const { return min_content_size_; }
+  double maxContentSize() const { return max_content_size_; }
+
+  const NGLayoutInputNode& GetLayoutNode() const;
+
+  bool IsValid() const { return token_->IsValid(); }
+
+  void Trace(Visitor*) override;
+
+ private:
+  Member<CustomLayoutChild> child_;
+  Member<CustomLayoutToken> token_;
+
+  // The min and max content sizes on this object should never change.
+  const double min_content_size_;
+  const double max_content_size_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
index 043110a..bd6ca64 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
@@ -23,6 +23,25 @@
           definition.ChildNativeInvalidationProperties(),
           definition.ChildCustomInvalidationProperties())) {}
 
+ScriptPromise CustomLayoutChild::intrinsicSizes(
+    ScriptState* script_state,
+    ExceptionState& exception_state) {
+  // A layout child may be invalid if it has been removed from the tree (it is
+  // possible for a web developer to hold onto a LayoutChild object after its
+  // underlying LayoutObject has been destroyed).
+  if (!node_ || !token_->IsValid()) {
+    return ScriptPromise::RejectWithDOMException(
+        script_state,
+        MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
+                                           "The LayoutChild is not valid."));
+  }
+
+  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+  CustomLayoutScope::Current()->Queue()->emplace_back(
+      this, token_, resolver, CustomLayoutWorkTask::TaskType::kIntrinsicSizes);
+  return resolver->Promise();
+}
+
 ScriptPromise CustomLayoutChild::layoutNextFragment(
     ScriptState* script_state,
     const CustomLayoutConstraintsOptions* options,
@@ -54,7 +73,8 @@
 
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   CustomLayoutScope::Current()->Queue()->emplace_back(
-      this, token_, resolver, options, std::move(constraint_data));
+      this, token_, resolver, options, std::move(constraint_data),
+      CustomLayoutWorkTask::TaskType::kLayoutFragment);
   return resolver->Promise();
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
index 5b7c1c43..1703a5f 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h
@@ -32,6 +32,7 @@
 
   // LayoutChild.idl
   PrepopulatedComputedStylePropertyMap* styleMap() const { return style_map_; }
+  ScriptPromise intrinsicSizes(ScriptState*, ExceptionState&);
   ScriptPromise layoutNextFragment(ScriptState*,
                                    const CustomLayoutConstraintsOptions*,
                                    ExceptionState&);
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
index b23852b..60ce952 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
@@ -5,37 +5,66 @@
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints_options.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
 
 namespace blink {
 
+CustomLayoutWorkTask::CustomLayoutWorkTask(CustomLayoutChild* child,
+                                           CustomLayoutToken* token,
+                                           ScriptPromiseResolver* resolver,
+                                           const TaskType type)
+    : CustomLayoutWorkTask(child, token, resolver, nullptr, nullptr, type) {}
+
 CustomLayoutWorkTask::CustomLayoutWorkTask(
     CustomLayoutChild* child,
     CustomLayoutToken* token,
     ScriptPromiseResolver* resolver,
     const CustomLayoutConstraintsOptions* options,
-    scoped_refptr<SerializedScriptValue> constraint_data)
+    scoped_refptr<SerializedScriptValue> constraint_data,
+    const TaskType type)
     : child_(child),
       token_(token),
       resolver_(resolver),
       options_(options),
-      constraint_data_(std::move(constraint_data)) {}
+      constraint_data_(std::move(constraint_data)),
+      type_(type) {}
 
 CustomLayoutWorkTask::~CustomLayoutWorkTask() = default;
 
-void CustomLayoutWorkTask::Run(const NGConstraintSpace& parent_space,
-                               const ComputedStyle& parent_style) {
+void CustomLayoutWorkTask::Run(const NGBlockNode& parent,
+                               const NGConstraintSpace& parent_space,
+                               const ComputedStyle& parent_style,
+                               const NGBoxStrut& border_scrollbar_padding) {
   DCHECK(token_->IsValid());
-  NGLayoutInputNode node = child_->GetLayoutNode();
-  NGConstraintSpaceBuilder builder(parent_space, node.Style().GetWritingMode(),
+  NGLayoutInputNode child = child_->GetLayoutNode();
+
+  if (type_ == CustomLayoutWorkTask::TaskType::kIntrinsicSizes) {
+    RunIntrinsicSizesTask(parent, parent_space, parent_style,
+                          border_scrollbar_padding, child);
+  } else {
+    DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kLayoutFragment);
+    RunLayoutFragmentTask(parent_space, parent_style, child);
+  }
+}
+
+void CustomLayoutWorkTask::RunLayoutFragmentTask(
+    const NGConstraintSpace& parent_space,
+    const ComputedStyle& parent_style,
+    NGLayoutInputNode child) {
+  DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kLayoutFragment);
+  DCHECK(options_ && resolver_);
+
+  NGConstraintSpaceBuilder builder(parent_space, child.Style().GetWritingMode(),
                                    /* is_new_fc */ true);
-  SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, node, &builder);
+  SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, child, &builder);
 
   bool is_fixed_inline_size = false;
   bool is_fixed_block_size = false;
@@ -88,17 +117,17 @@
     percentage_size.block_size = kIndefiniteSize;
   }
 
-  builder.SetTextDirection(node.Style().Direction());
+  builder.SetTextDirection(child.Style().Direction());
   builder.SetAvailableSize(available_size);
   builder.SetPercentageResolutionSize(percentage_size);
   builder.SetReplacedPercentageResolutionSize(percentage_size);
-  builder.SetIsShrinkToFit(node.Style().LogicalWidth().IsAuto());
+  builder.SetIsShrinkToFit(child.Style().LogicalWidth().IsAuto());
   builder.SetIsFixedInlineSize(is_fixed_inline_size);
   builder.SetIsFixedBlockSize(is_fixed_block_size);
-  if (node.IsLayoutNGCustom())
+  if (child.IsLayoutNGCustom())
     builder.SetCustomLayoutData(std::move(constraint_data_));
   auto space = builder.ToConstraintSpace();
-  auto result = To<NGBlockNode>(node).Layout(space, nullptr /* break_token */);
+  auto result = To<NGBlockNode>(child).Layout(space, nullptr /* break_token */);
 
   LogicalSize size = result->PhysicalFragment().Size().ConvertToLogical(
       parent_space.GetWritingMode());
@@ -108,4 +137,27 @@
       resolver_->GetScriptState()->GetIsolate()));
 }
 
+void CustomLayoutWorkTask::RunIntrinsicSizesTask(
+    const NGBlockNode& parent,
+    const NGConstraintSpace& parent_space,
+    const ComputedStyle& parent_style,
+    const NGBoxStrut& border_scrollbar_padding,
+    NGLayoutInputNode child) {
+  DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kIntrinsicSizes);
+  DCHECK(resolver_);
+
+  // TODO(almaher) should use border_padding instead of
+  // border_scrollbar_padding.
+  LayoutUnit child_percentage_resolution_block_size =
+      CalculateChildPercentageBlockSizeForMinMax(
+          parent_space, parent, border_scrollbar_padding,
+          parent_space.PercentageResolutionBlockSize());
+
+  MinMaxSizeInput input(child_percentage_resolution_block_size);
+  MinMaxSize sizes =
+      ComputeMinAndMaxContentContribution(parent_style, child, input);
+  resolver_->Resolve(MakeGarbageCollected<CustomIntrinsicSizes>(
+      child_, token_, sizes.min_size, sizes.max_size));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
index 5038048..0c8ca60 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
@@ -14,24 +14,42 @@
 class ComputedStyle;
 class CustomLayoutChild;
 class CustomLayoutToken;
+class NGBlockNode;
 class NGConstraintSpace;
+class NGLayoutInputNode;
 class SerializedScriptValue;
 class ScriptPromiseResolver;
+struct NGBoxStrut;
 
 // Contains all the information needed to resolve a promise with a fragment or
 // intrinsic-sizes.
 class CustomLayoutWorkTask {
  public:
+  enum TaskType {
+    kLayoutFragment,
+    kIntrinsicSizes,
+  };
+
+  // Used when resolving a promise with intrinsic-sizes.
+  CustomLayoutWorkTask(CustomLayoutChild*,
+                       CustomLayoutToken*,
+                       ScriptPromiseResolver*,
+                       const TaskType type);
+
+  // Used when resolving a promise with a fragment.
   CustomLayoutWorkTask(CustomLayoutChild*,
                        CustomLayoutToken*,
                        ScriptPromiseResolver*,
                        const CustomLayoutConstraintsOptions*,
-                       scoped_refptr<SerializedScriptValue> constraint_data);
+                       scoped_refptr<SerializedScriptValue> constraint_data,
+                       const TaskType type);
   ~CustomLayoutWorkTask();
 
   // Runs this work task.
-  void Run(const NGConstraintSpace& parent_space,
-           const ComputedStyle& parent_style);
+  void Run(const NGBlockNode& parent,
+           const NGConstraintSpace& parent_space,
+           const ComputedStyle& parent_style,
+           const NGBoxStrut& border_scrollbar_padding);
 
  private:
   Persistent<CustomLayoutChild> child_;
@@ -39,6 +57,16 @@
   Persistent<ScriptPromiseResolver> resolver_;
   Persistent<const CustomLayoutConstraintsOptions> options_;
   scoped_refptr<SerializedScriptValue> constraint_data_;
+  TaskType type_;
+
+  void RunLayoutFragmentTask(const NGConstraintSpace& parent_space,
+                             const ComputedStyle& parent_style,
+                             NGLayoutInputNode child);
+  void RunIntrinsicSizesTask(const NGBlockNode& parent,
+                             const NGConstraintSpace& parent_space,
+                             const ComputedStyle& parent_style,
+                             const NGBoxStrut& border_scrollbar_padding,
+                             NGLayoutInputNode child);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl b/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl
new file mode 100644
index 0000000..5864a072
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://drafts.css-houdini.org/css-layout-api/#intrinsicsizes
+
+[
+  Exposed=LayoutWorklet,
+  ImplementedAs=CustomIntrinsicSizes,
+  RuntimeEnabled=CSSLayoutAPI
+]
+interface IntrinsicSizes {
+  readonly attribute double minContentSize;
+  readonly attribute double maxContentSize;
+};
diff --git a/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl b/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl
new file mode 100644
index 0000000..aa3ae7d
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://drafts.css-houdini.org/css-layout-api/#dictdef-intrinsicsizesresultoptions
+
+dictionary IntrinsicSizesResultOptions {
+  double minContentSize = 0;
+  double maxContentSize = 0;
+};
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl b/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
index 3940849..73be84d 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
+++ b/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
@@ -12,7 +12,7 @@
 interface LayoutChild {
   readonly attribute StylePropertyMapReadOnly styleMap;
 
-  // IntrinsicSizesRequest intrinsicSizes();
+  [CallWith=ScriptState, RaisesException] Promise<IntrinsicSizes> intrinsicSizes();
   [CallWith=ScriptState, RaisesException] Promise<LayoutFragment> layoutNextFragment(optional CustomLayoutConstraintsOptions options);
 };
 
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
index 9bad59c..fc3cb6b4c 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_parser.h"
@@ -126,7 +127,8 @@
       retriever.GetMethodOrThrow("intrinsicSizes", exception_state);
   if (exception_state.HadException())
     return;
-  V8Function* intrinsic_sizes = V8Function::Create(v8_intrinsic_sizes);
+  V8IntrinsicSizesCallback* intrinsic_sizes =
+      V8IntrinsicSizesCallback::Create(v8_intrinsic_sizes);
 
   v8::Local<v8::Function> v8_layout =
       retriever.GetMethodOrThrow("layout", exception_state);
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
index 5ce4982e..63a233f5 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
+++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
@@ -15,3 +15,7 @@
 // Blink-specific type for layout function
 // https://drafts.css-houdini.org/css-layout-api/#layout-definition-layout-function
 callback LayoutCallback = any (sequence<LayoutChild> children, LayoutEdges edges, LayoutConstraints constraints, StylePropertyMapReadOnly styleMap);
+
+// Blink-specific type for intrinsicSizes function
+// https://drafts.css-houdini.org/css-layout-api/#layout-definition-intrinsic-sizes-function
+callback IntrinsicSizesCallback = any (sequence<LayoutChild> children, LayoutEdges edges, StylePropertyMapReadOnly styleMap);
diff --git a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
index 2e7297a..bb29e8c 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.h"
+#include "third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h"
 #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
@@ -34,9 +35,49 @@
 
 base::Optional<MinMaxSize> NGCustomLayoutAlgorithm::ComputeMinMaxSize(
     const MinMaxSizeInput& input) const {
-  // TODO(ikilpatrick): Invoke the web-developer defined "intrinsicSizes"
-  // method.
-  return FallbackMinMaxSize(input);
+  if (!Node().IsCustomLayoutLoaded())
+    return FallbackMinMaxSize(input);
+
+  ScriptForbiddenScope::AllowUserAgentScript allow_script;
+  CustomLayoutScope scope;
+
+  const AtomicString& name = Style().DisplayLayoutCustomName();
+  const Document& document = Node().GetDocument();
+  LayoutWorklet* worklet = LayoutWorklet::From(*document.domWindow());
+  CSSLayoutDefinition* definition = worklet->Proxy()->FindDefinition(name);
+
+  // TODO(ikilpatrick): Cache the instance of the layout class.
+  CSSLayoutDefinition::Instance* instance = definition->CreateInstance();
+
+  if (!instance) {
+    // TODO(ikilpatrick): Report this error to the developer.
+    return FallbackMinMaxSize(input);
+  }
+
+  IntrinsicSizesResultOptions* intrinsic_sizes_result_options =
+      IntrinsicSizesResultOptions::Create();
+  if (!instance->IntrinsicSizes(ConstraintSpace(), document, Node(),
+                                container_builder_.InitialBorderBoxSize(),
+                                border_scrollbar_padding_, &scope,
+                                intrinsic_sizes_result_options)) {
+    // TODO(ikilpatrick): Report this error to the developer.
+    return FallbackMinMaxSize(input);
+  }
+
+  MinMaxSize sizes;
+  sizes.max_size = LayoutUnit::FromDoubleRound(
+      intrinsic_sizes_result_options->maxContentSize());
+  sizes.min_size = std::min(
+      sizes.max_size, LayoutUnit::FromDoubleRound(
+                          intrinsic_sizes_result_options->minContentSize()));
+
+  if (input.size_type == NGMinMaxSizeType::kContentBoxSize)
+    sizes -= border_padding_.InlineSum();
+
+  sizes.min_size.ClampNegativeToZero();
+  sizes.max_size.ClampNegativeToZero();
+
+  return sizes;
 }
 
 scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
index 3a9b6f7..0485ed7 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -22,6 +22,7 @@
 }  // namespace
 
 NGInlineBreakToken::NGInlineBreakToken(
+    PassKey key,
     NGInlineNode node,
     const ComputedStyle* style,
     unsigned item_index,
@@ -34,7 +35,7 @@
   flags_ = flags;
 }
 
-NGInlineBreakToken::NGInlineBreakToken(NGLayoutInputNode node)
+NGInlineBreakToken::NGInlineBreakToken(PassKey key, NGLayoutInputNode node)
     : NGBreakToken(kInlineBreakToken, kFinished, node),
       item_index_(0),
       text_offset_(0) {}
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
index fdf2ebd..6558270e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
@@ -31,13 +31,13 @@
       unsigned item_index,
       unsigned text_offset,
       unsigned flags /* NGInlineBreakTokenFlags */) {
-    return base::AdoptRef(
-        new NGInlineBreakToken(node, style, item_index, text_offset, flags));
+    return base::AdoptRef(new NGInlineBreakToken(
+        PassKey(), node, style, item_index, text_offset, flags));
   }
 
   // Creates a break token for a node which cannot produce any more fragments.
   static scoped_refptr<NGInlineBreakToken> Create(NGLayoutInputNode node) {
-    return base::AdoptRef(new NGInlineBreakToken(node));
+    return base::AdoptRef(new NGInlineBreakToken(PassKey(), node));
   }
 
   ~NGInlineBreakToken() override;
@@ -69,19 +69,21 @@
     return flags_ & kIsForcedBreak;
   }
 
-#if DCHECK_IS_ON()
-  String ToString() const override;
-#endif
-
- private:
-  NGInlineBreakToken(NGInlineNode node,
+  using PassKey = util::PassKey<NGInlineBreakToken>;
+  NGInlineBreakToken(PassKey,
+                     NGInlineNode node,
                      const ComputedStyle*,
                      unsigned item_index,
                      unsigned text_offset,
                      unsigned flags /* NGInlineBreakTokenFlags */);
 
-  explicit NGInlineBreakToken(NGLayoutInputNode node);
+  explicit NGInlineBreakToken(PassKey, NGLayoutInputNode node);
 
+#if DCHECK_IS_ON()
+  String ToString() const override;
+#endif
+
+ private:
   scoped_refptr<const ComputedStyle> style_;
   unsigned item_index_;
   unsigned text_offset_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
index 89ada7e..df7664e6 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -236,8 +236,12 @@
     const LayoutInline& layout_inline) const {
   const LayoutObject* const layout_object = CurrentLayoutObject();
   // We use |IsInline()| to exclude floating and out-of-flow objects.
-  if (!layout_object || !layout_object->IsInline())
+  if (!layout_object || !layout_object->IsInline() ||
+      layout_object->IsAtomicInlineLevel())
     return false;
+  DCHECK(!layout_object->IsFloatingOrOutOfFlowPositioned());
+  DCHECK(!CurrentBoxFragment() ||
+         !CurrentBoxFragment()->IsBlockFormattingContextRoot());
   return layout_object->IsDescendantOf(&layout_inline);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
index 9e5ef9dc..a17617b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -123,8 +123,6 @@
 #endif
 }
 
-NGOffsetMappingUnit::~NGOffsetMappingUnit() = default;
-
 const Node* NGOffsetMappingUnit::AssociatedNode() const {
   if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object_))
     return text_fragment->AssociatedTextNode();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
index 40ab1e6..13b2eb52 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
@@ -47,7 +47,6 @@
                       unsigned dom_end,
                       unsigned text_content_start,
                       unsigned text_content_end);
-  ~NGOffsetMappingUnit();
 
   // Returns associated node for this unit or null if this unit is associated
   // to generated content.
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
index 56d8a6a..e543dff 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
@@ -147,12 +147,9 @@
   }
 
   // Create a marker box if it does not exist yet.
-  Node* list_item = GetNode();
+  Element* list_item = To<Element>(GetNode());
   const ComputedStyle* cached_marker_style =
-      list_item->IsPseudoElement()
-          ? nullptr
-          : To<Element>(list_item)->CachedStyleForPseudoElement(
-                kPseudoIdMarker);
+      list_item->CachedStyleForPseudoElement(kPseudoIdMarker);
   if (cached_marker_style && cached_marker_style->GetContentData()) {
     // Don't create an anonymous layout for the marker, it will be generated
     // by the ::marker pseudo-element.
@@ -161,17 +158,10 @@
     is_marker_text_updated_ = true;
     return;
   }
-  scoped_refptr<ComputedStyle> marker_style;
-  if (cached_marker_style) {
-    marker_style = ComputedStyle::Clone(*cached_marker_style);
-  } else {
-    marker_style = ComputedStyle::Create();
-    marker_style->InheritFrom(style);
-    marker_style->SetStyleType(kPseudoIdMarker);
-    marker_style->SetUnicodeBidi(UnicodeBidi::kIsolate);
-    marker_style->SetFontVariantNumericSpacing(
-        FontVariantNumeric::kTabularNums);
-  }
+  scoped_refptr<ComputedStyle> marker_style =
+      cached_marker_style ? ComputedStyle::Clone(*cached_marker_style)
+                          : list_item->StyleForPseudoElement(kPseudoIdMarker);
+  DCHECK(marker_style);
   if (IsInside()) {
     if (marker_ && !marker_->IsLayoutInline())
       DestroyMarker();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
index 6e9781b..38a2104d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
@@ -21,6 +21,7 @@
 }  // namespace
 
 NGBlockBreakToken::NGBlockBreakToken(
+    PassKey key,
     NGLayoutInputNode node,
     LayoutUnit consumed_block_size,
     const NGBreakTokenVector& child_break_tokens,
@@ -37,7 +38,7 @@
   }
 }
 
-NGBlockBreakToken::NGBlockBreakToken(NGLayoutInputNode node)
+NGBlockBreakToken::NGBlockBreakToken(PassKey key, NGLayoutInputNode node)
     : NGBreakToken(kBlockBreakToken, kUnfinished, node), num_children_(0) {}
 
 const NGInlineBreakToken* NGBlockBreakToken::InlineBreakTokenFor(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
index fc5ab4b..70a864f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
@@ -37,8 +37,9 @@
         sizeof(NGBlockBreakToken) +
             child_break_tokens.size() * sizeof(NGBreakToken*),
         ::WTF::GetStringWithTypeName<NGBlockBreakToken>());
-    new (data) NGBlockBreakToken(node, consumed_block_size, child_break_tokens,
-                                 break_appeal, has_seen_all_children);
+    new (data) NGBlockBreakToken(PassKey(), node, consumed_block_size,
+                                 child_break_tokens, break_appeal,
+                                 has_seen_all_children);
     return base::AdoptRef(static_cast<NGBlockBreakToken*>(data));
   }
 
@@ -48,7 +49,7 @@
   static scoped_refptr<NGBlockBreakToken> CreateBreakBefore(
       NGLayoutInputNode node,
       bool is_forced_break) {
-    auto* token = new NGBlockBreakToken(node);
+    auto* token = new NGBlockBreakToken(PassKey(), node);
     token->is_break_before_ = true;
     token->is_forced_break_ = is_forced_break;
     return base::AdoptRef(token);
@@ -102,17 +103,20 @@
   String ToString() const override;
 #endif
 
- private:
+  using PassKey = util::PassKey<NGBlockBreakToken>;
+
   // Must only be called from Create(), because it assumes that enough space
   // has been allocated in the flexible array to store the children.
-  NGBlockBreakToken(NGLayoutInputNode node,
+  NGBlockBreakToken(PassKey,
+                    NGLayoutInputNode node,
                     LayoutUnit consumed_block_size,
                     const NGBreakTokenVector& child_break_tokens,
                     NGBreakAppeal break_appeal,
                     bool has_seen_all_children);
 
-  explicit NGBlockBreakToken(NGLayoutInputNode node);
+  explicit NGBlockBreakToken(PassKey, NGLayoutInputNode node);
 
+ private:
   LayoutUnit consumed_block_size_;
 
   wtf_size_t num_children_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
index 18907ea..0664562 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -907,8 +907,6 @@
              is_orthogonal_writing_mode_root ==
                  other.is_orthogonal_writing_mode_root &&
              is_intermediate_layout == other.is_intermediate_layout &&
-             is_fixed_block_size_indefinite ==
-                 other.is_fixed_block_size_indefinite &&
              is_restricted_block_size_table_cell ==
                  other.is_restricted_block_size_table_cell &&
              use_first_line_style == other.use_first_line_style &&
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
index 1b7b3f02..81294b33 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
@@ -1354,5 +1354,74 @@
   EXPECT_EQ(result.get(), nullptr);
 }
 
+TEST_F(NGLayoutResultCachingTest, HitIsFixedBlockSizeIndefinite) {
+  ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
+
+  SetBodyInnerHTML(R"HTML(
+    <div style="display: flex; width: 100px; height: 100px;">
+      <div id="test1" style="flex-grow: 1; min-height: 100px;">
+        <div style="height: 50px;">text</div>
+      </div>
+    </div>
+    <div style="display: flex; width: 100px; height: 100px; align-items: stretch;">
+      <div id="src1" style="flex-grow: 1; min-height: 100px;">
+        <div style="height: 50px;">text</div>
+      </div>
+    </div>
+  )HTML");
+
+  auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+  auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+
+  NGLayoutCacheStatus cache_status;
+  base::Optional<NGFragmentGeometry> fragment_geometry;
+
+  NGConstraintSpace space =
+      src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+      space, nullptr, nullptr, &fragment_geometry, &cache_status);
+
+  // Even though the "align-items: stretch" will make the final fixed
+  // block-size indefinite, we don't have any %-block-size children, so we can
+  // hit the cache.
+  EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+  EXPECT_NE(result.get(), nullptr);
+}
+
+TEST_F(NGLayoutResultCachingTest, MissIsFixedBlockSizeIndefinite) {
+  ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
+
+  SetBodyInnerHTML(R"HTML(
+    <!DOCTYPE html>
+    <div style="display: flex; width: 100px; height: 100px; align-items: start;">
+      <div id="src1" style="flex-grow: 1; min-height: 100px;">
+        <div style="height: 50%;">text</div>
+      </div>
+    </div>
+    <div style="display: flex; width: 100px; height: 100px; align-items: stretch;">
+      <div id="test1" style="flex-grow: 1; min-height: 100px;">
+        <div style="height: 50%;">text</div>
+      </div>
+    </div>
+  )HTML");
+
+  auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+  auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+
+  NGLayoutCacheStatus cache_status;
+  base::Optional<NGFragmentGeometry> fragment_geometry;
+
+  NGConstraintSpace space =
+      src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+      space, nullptr, nullptr, &fragment_geometry, &cache_status);
+
+  // The "align-items: stretch" will make the final fixed block-size
+  // indefinite, and we have a %-block-size child, so we need to miss the
+  // cache.
+  EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
+  EXPECT_EQ(result.get(), nullptr);
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc
index a84088bd..21f4c8f 100644
--- a/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -136,8 +136,8 @@
   }
 
   void HandleMouseMoveEvent(int x, int y) {
-    WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(x, y),
-                        WebFloatPoint(x, y),
+    WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(x, y),
+                        gfx::PointF(x, y),
                         WebPointerProperties::Button::kNoButton, 0,
                         WebInputEvent::kNoModifiers, base::TimeTicks::Now());
     event.SetFrameScale(1);
@@ -146,17 +146,17 @@
   }
 
   void HandleMousePressEvent(int x, int y) {
-    WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+                        gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kLeftButtonDown,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetEventHandler().HandleMousePressEvent(event);
   }
 
   void HandleContextMenuEvent(int x, int y) {
     WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
+        WebInputEvent::kMouseDown, gfx::PointF(x, y), gfx::PointF(x, y),
         WebPointerProperties::Button::kNoButton, 0,
         WebInputEvent::Modifiers::kNoModifiers, base::TimeTicks::Now());
     event.SetFrameScale(1);
@@ -164,17 +164,17 @@
   }
 
   void HandleMouseReleaseEvent(int x, int y) {
-    WebMouseEvent event(
-        WebInputEvent::kMouseUp, WebFloatPoint(x, y), WebFloatPoint(x, y),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kNoModifiers, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseUp, gfx::PointF(x, y),
+                        gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kNoModifiers,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetEventHandler().HandleMouseReleaseEvent(event);
   }
 
   void HandleMouseMiddlePressEvent(int x, int y) {
     WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
+        WebInputEvent::kMouseDown, gfx::PointF(x, y), gfx::PointF(x, y),
         WebPointerProperties::Button::kMiddle, 0,
         WebInputEvent::Modifiers::kMiddleButtonDown, base::TimeTicks::Now());
     event.SetFrameScale(1);
@@ -183,7 +183,7 @@
 
   void HandleMouseMiddleReleaseEvent(int x, int y) {
     WebMouseEvent event(
-        WebInputEvent::kMouseUp, WebFloatPoint(x, y), WebFloatPoint(x, y),
+        WebInputEvent::kMouseUp, gfx::PointF(x, y), gfx::PointF(x, y),
         WebPointerProperties::Button::kMiddle, 0,
         WebInputEvent::Modifiers::kMiddleButtonDown, base::TimeTicks::Now());
     event.SetFrameScale(1);
@@ -191,10 +191,10 @@
   }
 
   void HandleMouseLeaveEvent() {
-    WebMouseEvent event(
-        WebInputEvent::kMouseMove, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(1, 1),
+                        gfx::PointF(1, 1), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kLeftButtonDown,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetEventHandler().HandleMouseLeaveEvent(event);
   }
@@ -235,7 +235,7 @@
     WebGestureEvent event(type, WebInputEvent::kNoModifiers,
                           base::TimeTicks::Now(), device);
 
-    event.SetPositionInWidget(WebFloatPoint(position.X(), position.Y()));
+    event.SetPositionInWidget(gfx::PointF(position.X(), position.Y()));
 
     if (type == WebInputEvent::kGestureScrollUpdate) {
       event.data.scroll_update.delta_x = offset.Width();
@@ -603,11 +603,11 @@
       WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now(), WebGestureDevice::kTouchpad);
   scroll_begin.SetPositionInWidget(
-      WebFloatPoint(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
-                    scrollable->OffsetTop()));
+      gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
+                  scrollable->OffsetTop()));
   scroll_begin.SetPositionInScreen(
-      WebFloatPoint(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
-                    scrollable->OffsetTop()));
+      gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
+                  scrollable->OffsetTop()));
   scroll_begin.data.scroll_begin.delta_x_hint = 0;
   scroll_begin.data.scroll_begin.delta_y_hint = 10;
   scroll_begin.SetFrameScale(1);
@@ -2315,9 +2315,9 @@
   EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart);
 
   // Move mouse out of scrollbar with press.
-  WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(5, 5),
-                      WebFloatPoint(5, 5), WebPointerProperties::Button::kLeft,
-                      0, WebInputEvent::Modifiers::kLeftButtonDown,
+  WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(5, 5),
+                      gfx::PointF(5, 5), WebPointerProperties::Button::kLeft, 0,
+                      WebInputEvent::Modifiers::kLeftButtonDown,
                       base::TimeTicks::Now());
   event.SetFrameScale(1);
   GetEventHandler().HandleMouseLeaveEvent(event);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index 534abb8..a39d5b6 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -130,7 +130,7 @@
   // (border-image/background-image/<html:img>/...) we're forced to resize to a
   // specific size.
   if (!container_size_.IsEmpty())
-    return LayoutUnit(container_size_.Width());
+    return container_size_.Width();
 
   if (IsEmbeddedThroughFrameContainingSVGDocument())
     return ContainingBlock()->AvailableLogicalWidth();
@@ -144,7 +144,7 @@
   // (border-image/background-image/<html:img>/...) we're forced to resize to a
   // specific size.
   if (!container_size_.IsEmpty())
-    return LayoutUnit(container_size_.Height());
+    return container_size_.Height();
 
   if (IsEmbeddedThroughFrameContainingSVGDocument())
     return ContainingBlock()->AvailableLogicalHeight(
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
index 3246ac26..4bba76f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
@@ -65,8 +65,8 @@
     needs_boundaries_or_transform_update_ = true;
   }
 
-  IntSize ContainerSize() const { return container_size_; }
-  void SetContainerSize(const IntSize& container_size) {
+  LayoutSize ContainerSize() const { return container_size_; }
+  void SetContainerSize(const LayoutSize& container_size) {
     // SVGImage::draw() does a view layout prior to painting,
     // and we need that layout to know of the new size otherwise
     // the layout may be incorrectly using the old size.
@@ -162,7 +162,7 @@
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const final;
 
   LayoutObjectChildList children_;
-  IntSize container_size_;
+  LayoutSize container_size_;
   FloatRect object_bounding_box_;
   bool object_bounding_box_valid_;
   FloatRect stroke_bounding_box_;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index a6d70f1..7c3cf19 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -926,11 +926,10 @@
       frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
   }
 
-  // If we have a provisional request for a different document, a fragment
+  // If we have a client navigation for a different document, a fragment
   // scroll should cancel it.
   // Note: see fragment-change-does-not-cancel-pending-navigation, where
   // this does not actually happen.
-  GetFrameLoader().DetachProvisionalDocumentLoader();
   GetFrameLoader().DidFinishNavigation(
       FrameLoader::NavigationFinishState::kSuccess);
 
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
index 58a07d37..3a87286 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -181,10 +181,11 @@
 
   void SetFilterPolicy(WebDocumentSubresourceFilter::LoadPolicy policy,
                        bool is_associated_with_ad_subframe = false) {
-    document->Loader()->SetSubresourceFilter(SubresourceFilter::Create(
-        *document, std::make_unique<FixedPolicySubresourceFilter>(
-                       policy, &filtered_load_callback_counter_,
-                       is_associated_with_ad_subframe)));
+    document->Loader()->SetSubresourceFilter(
+        MakeGarbageCollected<SubresourceFilter>(
+            document, std::make_unique<FixedPolicySubresourceFilter>(
+                          policy, &filtered_load_callback_counter_,
+                          is_associated_with_ad_subframe)));
   }
 
   base::Optional<ResourceRequestBlockedReason> CanRequest() {
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc
index 270ec3c..652ac72 100644
--- a/third_party/blink/renderer/core/loader/frame_load_request.cc
+++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -36,9 +36,8 @@
   Referrer referrer = SecurityPolicy::GenerateReferrer(
       referrer_policy_to_use, request.Url(), referrer_to_use);
 
-  // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
-  // header and instead use a separate member. See https://crbug.com/850813.
-  request.SetHttpReferrer(referrer);
+  request.SetReferrerString(referrer.referrer);
+  request.SetReferrerPolicy(referrer.referrer_policy);
   request.SetHTTPOriginToMatchReferrerIfNeeded();
 }
 
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.h b/third_party/blink/renderer/core/loader/frame_load_request.h
index a68c671..f37a056b 100644
--- a/third_party/blink/renderer/core/loader/frame_load_request.h
+++ b/third_party/blink/renderer/core/loader/frame_load_request.h
@@ -27,6 +27,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOAD_REQUEST_H_
 
 #include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
 #include "third_party/blink/public/common/navigation/triggering_event_info.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
@@ -37,6 +38,7 @@
 #include "third_party/blink/renderer/core/loader/navigation_policy.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
+#include "third_party/blink/renderer/platform/weborigin/referrer.h"
 
 namespace blink {
 
@@ -136,7 +138,8 @@
   void SetNoOpener() { window_features_.noopener = true; }
   void SetNoReferrer() {
     should_send_referrer_ = kNeverSendReferrer;
-    resource_request_.ClearHTTPReferrer();
+    resource_request_.SetReferrerString(Referrer::NoReferrer());
+    resource_request_.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
     resource_request_.ClearHTTPOrigin();
   }
 
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 9fce8cf..192c02c 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -159,13 +159,13 @@
   // document. If this reload is a client redirect (e.g., location.reload()), it
   // was initiated by something in the current document and should therefore
   // show the current document's url as the referrer.
-  // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
-  // header and instead use a separate member. See https://crbug.com/850813.
   if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) {
-    request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
+    Referrer referrer = SecurityPolicy::GenerateReferrer(
         frame_->GetDocument()->GetReferrerPolicy(),
         frame_->GetDocument()->Url(),
-        frame_->GetDocument()->OutgoingReferrer()));
+        frame_->GetDocument()->OutgoingReferrer());
+    request.SetReferrerString(referrer.referrer);
+    request.SetReferrerPolicy(referrer.referrer_policy);
   }
 
   request.SetSkipServiceWorker(frame_load_type ==
@@ -198,7 +198,6 @@
   visitor->Trace(frame_);
   visitor->Trace(progress_tracker_);
   visitor->Trace(document_loader_);
-  visitor->Trace(provisional_document_loader_);
   visitor->Trace(last_origin_document_csp_);
 }
 
@@ -211,14 +210,14 @@
       frame_->Owner() ? base::make_optional(frame_->Owner()->GetFramePolicy())
                       : base::nullopt;
 
-  provisional_document_loader_ = Client()->CreateDocumentLoader(
+  DocumentLoader* new_document_loader = Client()->CreateDocumentLoader(
       frame_, kWebNavigationTypeOther,
       MakeGarbageCollected<ContentSecurityPolicy>(),
       std::move(navigation_params), nullptr /* extra_data */);
 
-  CommitDocumentLoader(provisional_document_loader_.Release(), base::nullopt,
-                       nullptr, true /* is_initialization */,
-                       base::DoNothing::Once(), false /* is_javascript_url */);
+  CommitDocumentLoader(new_document_loader, base::nullopt, nullptr,
+                       true /* is_initialization */, base::DoNothing::Once(),
+                       false /* is_javascript_url */);
 
   frame_->GetDocument()->CancelParsing();
 
@@ -243,8 +242,6 @@
     frame_->GetDocument()->Fetcher()->SetDefersLoading(defers);
   if (document_loader_)
     document_loader_->SetDefersLoading(defers);
-  if (provisional_document_loader_)
-    provisional_document_loader_->SetDefersLoading(defers);
 }
 
 void FrameLoader::SaveScrollAnchor() {
@@ -596,6 +593,23 @@
   return mojom::RequestContextType::HYPERLINK;
 }
 
+static network::mojom::RequestDestination
+DetermineRequestDestinationFromNavigationType(
+    const WebNavigationType navigation_type) {
+  switch (navigation_type) {
+    case kWebNavigationTypeLinkClicked:
+    case kWebNavigationTypeOther:
+    case kWebNavigationTypeFormResubmitted:
+    case kWebNavigationTypeFormSubmitted:
+      return network::mojom::RequestDestination::kDocument;
+    case kWebNavigationTypeBackForward:
+    case kWebNavigationTypeReload:
+      return network::mojom::RequestDestination::kEmpty;
+  }
+  NOTREACHED();
+  return network::mojom::RequestDestination::kDocument;
+}
+
 void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
                                   WebFrameLoadType frame_load_type) {
   CHECK(!IsBackForwardLoadType(frame_load_type));
@@ -676,6 +690,8 @@
     request_context_type = mojom::RequestContextType::IFRAME;
   }
   resource_request.SetRequestContext(request_context_type);
+  resource_request.SetRequestDestination(
+      DetermineRequestDestinationFromNavigationType(navigation_type));
   request.SetFrameType(frame_->IsMainFrame()
                            ? network::mojom::RequestContextFrameType::kTopLevel
                            : network::mojom::RequestContextFrameType::kNested);
@@ -962,12 +978,11 @@
 
   // TODO(dgozman): get rid of provisional document loader and most of the code
   // below. We should probably call DocumentLoader::CommitNavigation directly.
-  DocumentLoader* provisional_document_loader = Client()->CreateDocumentLoader(
+  DocumentLoader* new_document_loader = Client()->CreateDocumentLoader(
       frame_, navigation_type, content_security_policy,
       std::move(navigation_params), std::move(extra_data));
-  provisional_document_loader_ = provisional_document_loader;
 
-  CommitDocumentLoader(provisional_document_loader_.Release(), unload_timing,
+  CommitDocumentLoader(new_document_loader, unload_timing,
                        previous_history_item, false /* is_initialization */,
                        std::move(call_before_attaching_new_document),
                        is_javascript_url);
@@ -1012,7 +1027,6 @@
   frame_->GetDocument()->CancelParsing();
   if (document_loader_)
     document_loader_->StopLoading();
-  DetachDocumentLoader(provisional_document_loader_);
   CancelClientNavigation();
   DidFinishNavigation(FrameLoader::NavigationFinishState::kSuccess);
 
@@ -1033,7 +1047,7 @@
     SecurityOrigin* committing_origin,
     base::Optional<Document::UnloadEventTiming>* timing) {
   PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
-  DocumentLoader* pdl = provisional_document_loader_;
+  ClientNavigationState* client_navigation = client_navigation_.get();
 
   // Don't allow this frame to navigate anymore. This line is needed for
   // navigation triggered from children's unload handlers. Blocking navigations
@@ -1059,7 +1073,7 @@
   if (!frame_->Client())
     return false;
   // FrameNavigationDisabler should prevent another load from starting.
-  DCHECK_EQ(provisional_document_loader_, pdl);
+  DCHECK_EQ(client_navigation_.get(), client_navigation);
   // detachFromFrame() will abort XHRs that haven't completed, which can trigger
   // event listeners for 'abort'. These event listeners might call
   // window.stop(), which will in turn detach the provisional document loader.
@@ -1072,7 +1086,7 @@
   if (!frame_->Client())
     return false;
   // FrameNavigationDisabler should prevent another load from starting.
-  DCHECK_EQ(provisional_document_loader_, pdl);
+  DCHECK_EQ(client_navigation_.get(), client_navigation);
 
   // No more events will be dispatched so detach the Document.
   // TODO(yoav): Should we also be nullifying domWindow's document (or
@@ -1278,13 +1292,6 @@
 void FrameLoader::Detach() {
   frame_->GetDocument()->CancelParsing();
   DetachDocumentLoader(document_loader_);
-  if (provisional_document_loader_) {
-    // Suppress client notification about failed provisional
-    // load - it does not bring any value when the frame is
-    // being detached anyway.
-    provisional_document_loader_->SetSentDidFinishLoad();
-    DetachDocumentLoader(provisional_document_loader_);
-  }
   ClearClientNavigation();
   committing_navigation_ = false;
   DidFinishNavigation(FrameLoader::NavigationFinishState::kSuccess);
@@ -1321,10 +1328,6 @@
   return true;
 }
 
-void FrameLoader::DetachProvisionalDocumentLoader() {
-  DetachDocumentLoader(provisional_document_loader_);
-}
-
 bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission,
                                                   const String& http_method,
                                                   WebFrameLoadType load_type,
@@ -1459,7 +1462,7 @@
 
 void FrameLoader::MarkAsLoading() {
   // This should only be called for initial history navigation in child frame.
-  DCHECK(!provisional_document_loader_ && !client_navigation_);
+  DCHECK(!client_navigation_);
   DCHECK(frame_->GetDocument()->IsLoadCompleted());
   DCHECK(frame_->GetDocument()->HasFinishedParsing());
   progress_tracker_->ProgressStarted();
@@ -1499,13 +1502,6 @@
   if (!frame_->GetPage())
     return false;
 
-  DetachDocumentLoader(provisional_document_loader_);
-  // Detaching the provisional DocumentLoader above may leave the frame without
-  // any loading DocumentLoader. It can causes the 'load' event to fire, which
-  // can be used to detach this frame.
-  if (!frame_->GetPage())
-    return false;
-
   // For client navigations, don't send failure callbacks when simply
   // replacing client navigation with a DocumentLoader.
   ClearClientNavigation();
@@ -1707,10 +1703,6 @@
   traced_value->EndDictionary();
   traced_value->SetBoolean("isLoadingMainFrame", frame_->IsMainFrame());
   traced_value->SetString("stateMachine", state_machine_.ToString());
-  traced_value->SetString("provisionalDocumentLoaderURL",
-                          provisional_document_loader_
-                              ? provisional_document_loader_->Url().GetString()
-                              : String());
   traced_value->SetString(
       "documentLoaderURL",
       document_loader_ ? document_loader_->Url().GetString() : String());
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h
index b4a96383..39d265b 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -224,7 +224,6 @@
   // Like ClearClientNavigation, but also notifies the client to actually cancel
   // the navigation.
   void CancelClientNavigation();
-  void DetachProvisionalDocumentLoader();
 
   void Trace(blink::Visitor*);
 
@@ -301,13 +300,8 @@
 
   Member<ProgressTracker> progress_tracker_;
 
-  // Document loaders for the three phases of frame loading. Note that while a
-  // new request is being loaded, the old document loader may still be
-  // referenced. E.g. while a new request is in the "policy" state, the old
-  // document loader may be consulted in particular as it makes sense to imply
-  // certain settings on the new loader.
+  // Document loader for frame loading.
   Member<DocumentLoader> document_loader_;
-  Member<DocumentLoader> provisional_document_loader_;
 
   // This struct holds information about a navigation, which is being
   // initiated by the client through the browser process, until the navigation
diff --git a/third_party/blink/renderer/core/loader/history_item.h b/third_party/blink/renderer/core/loader/history_item.h
index 5d29c48f..552c458 100644
--- a/third_party/blink/renderer/core/loader/history_item.h
+++ b/third_party/blink/renderer/core/loader/history_item.h
@@ -50,8 +50,6 @@
 
 class CORE_EXPORT HistoryItem final : public GarbageCollected<HistoryItem> {
  public:
-  static HistoryItem* Create() { return MakeGarbageCollected<HistoryItem>(); }
-
   HistoryItem();
   ~HistoryItem();
 
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc
index 17d84a4..fd8d347 100644
--- a/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -491,10 +491,16 @@
     if (IsA<HTMLPictureElement>(GetElement()->parentNode()) ||
         !GetElement()->FastGetAttribute(html_names::kSrcsetAttr).IsNull()) {
       resource_request.SetRequestContext(mojom::RequestContextType::IMAGE_SET);
+      resource_request.SetRequestDestination(
+          network::mojom::RequestDestination::kImage);
     } else if (IsA<HTMLObjectElement>(GetElement())) {
       resource_request.SetRequestContext(mojom::RequestContextType::OBJECT);
+      resource_request.SetRequestDestination(
+          network::mojom::RequestDestination::kObject);
     } else if (IsA<HTMLEmbedElement>(GetElement())) {
       resource_request.SetRequestContext(mojom::RequestContextType::EMBED);
+      resource_request.SetRequestDestination(
+          network::mojom::RequestDestination::kEmbed);
     }
 
     bool page_is_being_dismissed =
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc
index f1128cb..153c986 100644
--- a/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -76,11 +76,6 @@
 
 }  // namespace
 
-LinkLoader* LinkLoader::Create(LinkLoaderClient* client) {
-  return MakeGarbageCollected<LinkLoader>(client,
-                                          client->GetLoadingTaskRunner());
-}
-
 class LinkLoader::FinishObserver final
     : public GarbageCollected<LinkLoader::FinishObserver>,
       public ResourceFinishObserver {
@@ -229,7 +224,8 @@
                                 ResourceClient* link_client) {
   Document* document_for_origin = &document;
   if (base::FeatureList::IsEnabled(
-          features::kHtmlImportsRequestInitiatorLock)) {
+          features::kHtmlImportsRequestInitiatorLock) &&
+      document.ImportsController()) {
     // For stylesheets loaded from HTML imported Documents, we use
     // context document for getting origin and ResourceFetcher to use the main
     // Document's origin, while using element document for CompleteURL() to use
diff --git a/third_party/blink/renderer/core/loader/link_loader.h b/third_party/blink/renderer/core/loader/link_loader.h
index 10d0724..11d0d96 100644
--- a/third_party/blink/renderer/core/loader/link_loader.h
+++ b/third_party/blink/renderer/core/loader/link_loader.h
@@ -53,8 +53,6 @@
   USING_GARBAGE_COLLECTED_MIXIN(LinkLoader);
 
  public:
-  static LinkLoader* Create(LinkLoaderClient*);
-
   LinkLoader(LinkLoaderClient*, scoped_refptr<base::SingleThreadTaskRunner>);
   ~LinkLoader() override;
 
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc
index e7233d6..35caae3 100644
--- a/third_party/blink/renderer/core/loader/link_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
 #include "third_party/blink/renderer/core/testing/dummy_modulator.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
@@ -113,7 +114,8 @@
     Persistent<MockLinkLoaderClient> loader_client =
         MakeGarbageCollected<MockLinkLoaderClient>(
             expected.link_loader_should_load_value);
-    LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+    auto* loader = MakeGarbageCollected<LinkLoader>(
+        loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
     // TODO(crbug.com/751425): We should use the mock functionality
     // via |dummy_page_holder_|.
     url_test_helpers::RegisterMockedErrorURLLoad(params.href);
@@ -511,7 +513,8 @@
       modulator);
   Persistent<MockLinkLoaderClient> loader_client =
       MakeGarbageCollected<MockLinkLoaderClient>(true);
-  LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+  auto* loader = MakeGarbageCollected<LinkLoader>(
+      loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
   KURL href_url = KURL(NullURL(), test_case.href);
   LinkLoadParameters params(
       LinkRelAttribute("modulepreload"), test_case.cross_origin,
@@ -560,7 +563,8 @@
   dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true);
   Persistent<MockLinkLoaderClient> loader_client =
       MakeGarbageCollected<MockLinkLoaderClient>(true);
-  LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+  auto* loader = MakeGarbageCollected<LinkLoader>(
+      loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
   KURL href_url = KURL(NullURL(), "http://example.test/cat.jpg");
   // TODO(crbug.com/751425): We should use the mock functionality
   // via |dummy_page_holder|.
@@ -625,7 +629,8 @@
     Persistent<MockLinkLoaderClient> loader_client =
         MakeGarbageCollected<MockLinkLoaderClient>(
             test_case.link_loader_should_load_value);
-    LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+    auto* loader = MakeGarbageCollected<LinkLoader>(
+        loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
     KURL href_url = KURL(NullURL(), test_case.href);
     // TODO(crbug.com/751425): We should use the mock functionality
     // via |dummy_page_holder|.
@@ -678,7 +683,8 @@
         dummy_page_holder->GetFrame().PrescientNetworking());
     Persistent<MockLinkLoaderClient> loader_client =
         MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load);
-    LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+    auto* loader = MakeGarbageCollected<LinkLoader>(
+        loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
     LinkLoadParameters params(
         LinkRelAttribute("dns-prefetch"), kCrossOriginAttributeNotSet, String(),
@@ -717,7 +723,8 @@
         dummy_page_holder->GetFrame().PrescientNetworking());
     Persistent<MockLinkLoaderClient> loader_client =
         MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load);
-    LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+    auto* loader = MakeGarbageCollected<LinkLoader>(
+        loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
     LinkLoadParameters params(
         LinkRelAttribute("preconnect"), test_case.cross_origin, String(),
@@ -744,7 +751,8 @@
   dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true);
   Persistent<MockLinkLoaderClient> loader_client =
       MakeGarbageCollected<MockLinkLoaderClient>(true);
-  LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+  auto* loader = MakeGarbageCollected<LinkLoader>(
+      loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
   KURL href_url = KURL(KURL(), "https://www.example.com/");
   // TODO(crbug.com/751425): We should use the mock functionality
   // via |dummy_page_holder|.
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h b/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
index 5727288..e746bc0c 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
@@ -22,11 +22,13 @@
   // Referrer is set only for internal module script fetch algorithms triggered
   // from ModuleTreeLinker to fetch descendant module scripts.
   ModuleScriptFetchRequest(const KURL& url,
-                           mojom::RequestContextType destination,
+                           mojom::RequestContextType context_type,
+                           network::mojom::RequestDestination destination,
                            const ScriptFetchOptions& options,
                            const String& referrer_string,
                            const TextPosition& referrer_position)
       : url_(url),
+        context_type_(context_type),
         destination_(destination),
         options_(options),
         referrer_string_(referrer_string),
@@ -34,20 +36,25 @@
 
   static ModuleScriptFetchRequest CreateForTest(const KURL& url) {
     return ModuleScriptFetchRequest(
-        url, mojom::RequestContextType::SCRIPT, ScriptFetchOptions(),
+        url, mojom::RequestContextType::SCRIPT,
+        network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
         Referrer::ClientReferrerString(), TextPosition::MinimumPosition());
   }
   ~ModuleScriptFetchRequest() = default;
 
   const KURL& Url() const { return url_; }
-  mojom::RequestContextType Destination() const { return destination_; }
+  mojom::RequestContextType ContextType() const { return context_type_; }
+  network::mojom::RequestDestination Destination() const {
+    return destination_;
+  }
   const ScriptFetchOptions& Options() const { return options_; }
   const String& ReferrerString() const { return referrer_string_; }
   const TextPosition& GetReferrerPosition() const { return referrer_position_; }
 
  private:
   const KURL url_;
-  const mojom::RequestContextType destination_;
+  const mojom::RequestContextType context_type_;
+  const network::mojom::RequestDestination destination_;
   const ScriptFetchOptions options_;
   const String referrer_string_;
   const TextPosition referrer_position_;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
index f9e8026..a0bea475 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
@@ -117,7 +117,8 @@
 #endif
 
   // <spec step="5">... destination is destination, ...</spec>
-  resource_request.SetRequestContext(module_request.Destination());
+  resource_request.SetRequestContext(module_request.ContextType());
+  resource_request.SetRequestDestination(module_request.Destination());
 
   ResourceLoaderOptions options;
 
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
index e2c000bc..a890cda 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -34,15 +34,16 @@
 void ModuleTreeLinker::Fetch(
     const KURL& url,
     ResourceFetcher* fetch_client_settings_object_fetcher,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     const ScriptFetchOptions& options,
     Modulator* modulator,
     ModuleScriptCustomFetchType custom_fetch_type,
     ModuleTreeLinkerRegistry* registry,
     ModuleTreeClient* client) {
   ModuleTreeLinker* fetcher = MakeGarbageCollected<ModuleTreeLinker>(
-      fetch_client_settings_object_fetcher, destination, modulator,
-      custom_fetch_type, registry, client);
+      fetch_client_settings_object_fetcher, context_type, destination,
+      modulator, custom_fetch_type, registry, client);
   registry->AddFetcher(fetcher);
   fetcher->FetchRoot(url, options);
   DCHECK(fetcher->IsFetching());
@@ -51,15 +52,16 @@
 void ModuleTreeLinker::FetchDescendantsForInlineScript(
     ModuleScript* module_script,
     ResourceFetcher* fetch_client_settings_object_fetcher,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     Modulator* modulator,
     ModuleScriptCustomFetchType custom_fetch_type,
     ModuleTreeLinkerRegistry* registry,
     ModuleTreeClient* client) {
   DCHECK(module_script);
   ModuleTreeLinker* fetcher = MakeGarbageCollected<ModuleTreeLinker>(
-      fetch_client_settings_object_fetcher, destination, modulator,
-      custom_fetch_type, registry, client);
+      fetch_client_settings_object_fetcher, context_type, destination,
+      modulator, custom_fetch_type, registry, client);
   registry->AddFetcher(fetcher);
   fetcher->FetchRootInline(module_script);
   DCHECK(fetcher->IsFetching());
@@ -67,13 +69,15 @@
 
 ModuleTreeLinker::ModuleTreeLinker(
     ResourceFetcher* fetch_client_settings_object_fetcher,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     Modulator* modulator,
     ModuleScriptCustomFetchType custom_fetch_type,
     ModuleTreeLinkerRegistry* registry,
     ModuleTreeClient* client)
     : fetch_client_settings_object_fetcher_(
           fetch_client_settings_object_fetcher),
+      context_type_(context_type),
       destination_(destination),
       modulator_(modulator),
       custom_fetch_type_(custom_fetch_type),
@@ -229,7 +233,7 @@
   // module script given url, fetch client settings object, destination,
   // options, module map settings object, "client", and with the top-level
   // module fetch flag set. ...</spec>
-  ModuleScriptFetchRequest request(url, destination_, options,
+  ModuleScriptFetchRequest request(url, context_type_, destination_, options,
                                    Referrer::ClientReferrerString(),
                                    TextPosition::MinimumPosition());
   ++num_incomplete_fetches_;
@@ -448,9 +452,9 @@
     // procedure given url, fetch client settings object, destination, options,
     // module script's settings object, visited set, and module script's base
     // URL. ...</spec>
-    ModuleScriptFetchRequest request(urls[i], destination_, options,
-                                     module_script->BaseURL().GetString(),
-                                     positions[i]);
+    ModuleScriptFetchRequest request(
+        urls[i], context_type_, destination_, options,
+        module_script->BaseURL().GetString(), positions[i]);
 
     // <spec label="IMSGF" step="1">Assert: visited set contains url.</spec>
     DCHECK(visited_set_.Contains(request.Url()));
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
index aaa9566..58f323e 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
@@ -33,7 +33,8 @@
   // https://html.spec.whatwg.org/C/#fetch-an-import()-module-script-graph
   static void Fetch(const KURL&,
                     ResourceFetcher* fetch_client_settings_object_fetcher,
-                    mojom::RequestContextType destination,
+                    mojom::RequestContextType context_type,
+                    network::mojom::RequestDestination destination,
                     const ScriptFetchOptions&,
                     Modulator*,
                     ModuleScriptCustomFetchType,
@@ -44,14 +45,16 @@
   static void FetchDescendantsForInlineScript(
       ModuleScript*,
       ResourceFetcher* fetch_client_settings_object_fetcher,
-      mojom::RequestContextType destination,
+      mojom::RequestContextType context_type,
+      network::mojom::RequestDestination destination,
       Modulator*,
       ModuleScriptCustomFetchType,
       ModuleTreeLinkerRegistry*,
       ModuleTreeClient*);
 
   ModuleTreeLinker(ResourceFetcher* fetch_client_settings_object_fetcher,
-                   mojom::RequestContextType destination,
+                   mojom::RequestContextType context_type,
+                   network::mojom::RequestDestination destination,
                    Modulator*,
                    ModuleScriptCustomFetchType,
                    ModuleTreeLinkerRegistry*,
@@ -99,7 +102,8 @@
 
   const Member<ResourceFetcher> fetch_client_settings_object_fetcher_;
 
-  const mojom::RequestContextType destination_;
+  const mojom::RequestContextType context_type_;
+  const network::mojom::RequestDestination destination_;
   const Member<Modulator> modulator_;
   const ModuleScriptCustomFetchType custom_fetch_type_;
   HashSet<KURL> visited_set_;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
index bc61848..1d72253 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
@@ -215,10 +215,10 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -238,10 +238,10 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -265,10 +265,10 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -293,10 +293,10 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -334,10 +334,10 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -394,10 +394,10 @@
 
   KURL url("http://example.com/depth1.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -421,10 +421,10 @@
 
   KURL url("http://example.com/a.js");
   TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
-  ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
-                          mojom::RequestContextType::SCRIPT,
-                          ScriptFetchOptions(), GetModulator(),
-                          ModuleScriptCustomFetchType::kNone, registry, client);
+  ModuleTreeLinker::Fetch(
+      url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+      GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc
index 242fe0441..3e6a7da 100644
--- a/third_party/blink/renderer/core/loader/ping_loader.cc
+++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -253,6 +253,7 @@
   request.SetHttpBody(std::move(report));
   request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin);
   request.SetRequestContext(mojom::RequestContextType::CSP_REPORT);
+  request.SetRequestDestination(network::mojom::RequestDestination::kReport);
   request.SetRequestorOrigin(frame->GetDocument()->GetSecurityOrigin());
   request.SetRedirectMode(network::mojom::RedirectMode::kError);
   FetchParameters params(request);
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc
index 96fe865..0636636 100644
--- a/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -284,6 +284,8 @@
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
       resource_type.value(), ResourceFetcher::kImageNotImageSet));
+  resource_request.SetRequestDestination(
+      ResourceFetcher::DetermineRequestDestination(resource_type.value()));
 
   resource_request.SetReferrerPolicy(params.referrer_policy);
 
@@ -393,7 +395,9 @@
     }
     return;
   }
-  mojom::RequestContextType destination = mojom::RequestContextType::SCRIPT;
+  mojom::RequestContextType context_type = mojom::RequestContextType::SCRIPT;
+  network::mojom::RequestDestination destination =
+      network::mojom::RequestDestination::kScript;
 
   // Step 4. "Parse the URL given by the href attribute, relative to the
   // element's node document. If that fails, then return. Otherwise, let url be
@@ -447,7 +451,7 @@
   // metadata is "not-parser-inserted", credentials mode is credentials mode,
   // and referrer policy is referrer policy." [spec text]
   ModuleScriptFetchRequest request(
-      params.href, destination,
+      params.href, context_type, destination,
       ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
                          kNotParserInserted, credentials_mode,
                          params.referrer_policy,
@@ -633,6 +637,7 @@
       break;
     case ResourceType::kScript:
       params.SetRequestContext(mojom::RequestContextType::SCRIPT);
+      params.SetRequestDestination(network::mojom::RequestDestination::kScript);
       resource = ScriptResource::Fetch(params, resource_fetcher, nullptr,
                                        ScriptResource::kAllowStreaming);
       break;
diff --git a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
index 7973376..9870c56e 100644
--- a/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc
@@ -47,6 +47,7 @@
                                                     ResourceFetcher* fetcher,
                                                     ResourceClient* client) {
   params.SetRequestContext(mojom::RequestContextType::STYLE);
+  params.SetRequestDestination(network::mojom::RequestDestination::kStyle);
   CSSStyleSheetResource* resource = ToCSSStyleSheetResource(
       fetcher->RequestResource(params, CSSStyleSheetResourceFactory(), client));
   return resource;
diff --git a/third_party/blink/renderer/core/loader/resource/document_resource.cc b/third_party/blink/renderer/core/loader/resource/document_resource.cc
index b1d14480..b647251 100644
--- a/third_party/blink/renderer/core/loader/resource/document_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/document_resource.cc
@@ -40,6 +40,7 @@
   DCHECK_EQ(params.GetResourceRequest().GetMode(),
             network::mojom::RequestMode::kSameOrigin);
   params.SetRequestContext(mojom::RequestContextType::IMAGE);
+  params.SetRequestDestination(network::mojom::RequestDestination::kImage);
   return ToDocumentResource(
       fetcher->RequestResource(params, SVGDocumentResourceFactory(), client));
 }
diff --git a/third_party/blink/renderer/core/loader/resource/font_resource.cc b/third_party/blink/renderer/core/loader/resource/font_resource.cc
index e5bc075..d64d4bb 100644
--- a/third_party/blink/renderer/core/loader/resource/font_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/font_resource.cc
@@ -82,6 +82,7 @@
                                   ResourceFetcher* fetcher,
                                   FontResourceClient* client) {
   params.SetRequestContext(mojom::RequestContextType::FONT);
+  params.SetRequestDestination(network::mojom::RequestDestination::kFont);
   return ToFontResource(
       fetcher->RequestResource(params, FontResourceFactory(), client));
 }
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource.cc b/third_party/blink/renderer/core/loader/resource/image_resource.cc
index 47f73bf1..6457409 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/image_resource.cc
@@ -133,7 +133,8 @@
       const KURL& url,
       const AtomicString& initiator_name) override {
     fetcher->EmulateLoadStartedForInspector(
-        resource_.Get(), url, mojom::RequestContextType::IMAGE, initiator_name);
+        resource_.Get(), url, mojom::RequestContextType::IMAGE,
+        network::mojom::RequestDestination::kImage, initiator_name);
   }
 
   void LoadDeferredImage(ResourceFetcher* fetcher) override {
@@ -173,6 +174,7 @@
   if (params.GetResourceRequest().GetRequestContext() ==
       mojom::RequestContextType::UNSPECIFIED) {
     params.SetRequestContext(mojom::RequestContextType::IMAGE);
+    params.SetRequestDestination(network::mojom::RequestDestination::kImage);
   }
 
   ImageResource* resource = ToImageResource(
diff --git a/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc b/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
index ce39f0a..3620d86 100644
--- a/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
@@ -36,6 +36,7 @@
 
 static void ApplyXSLRequestProperties(FetchParameters& params) {
   params.SetRequestContext(mojom::RequestContextType::XSLT);
+  params.SetRequestDestination(network::mojom::RequestDestination::kXslt);
   // TODO(japhet): Accept: headers can be set manually on XHRs from script, in
   // the browser process, and... here. The browser process can't tell the
   // difference between an XSL stylesheet and a CSS stylesheet, so it assumes
diff --git a/third_party/blink/renderer/core/loader/subresource_filter.cc b/third_party/blink/renderer/core/loader/subresource_filter.cc
index 5b9982f..b332b3c 100644
--- a/third_party/blink/renderer/core/loader/subresource_filter.cc
+++ b/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -34,14 +34,6 @@
 
 }  // namespace
 
-// static
-SubresourceFilter* SubresourceFilter::Create(
-    ExecutionContext& execution_context,
-    std::unique_ptr<WebDocumentSubresourceFilter> filter) {
-  return MakeGarbageCollected<SubresourceFilter>(&execution_context,
-                                                 std::move(filter));
-}
-
 SubresourceFilter::SubresourceFilter(
     ExecutionContext* execution_context,
     std::unique_ptr<WebDocumentSubresourceFilter> subresource_filter)
diff --git a/third_party/blink/renderer/core/loader/subresource_filter.h b/third_party/blink/renderer/core/loader/subresource_filter.h
index d8c9a2ce..1347ce1 100644
--- a/third_party/blink/renderer/core/loader/subresource_filter.h
+++ b/third_party/blink/renderer/core/loader/subresource_filter.h
@@ -26,10 +26,6 @@
 class CORE_EXPORT SubresourceFilter final
     : public GarbageCollected<SubresourceFilter> {
  public:
-  static SubresourceFilter* Create(
-      ExecutionContext&,
-      std::unique_ptr<WebDocumentSubresourceFilter>);
-
   SubresourceFilter(ExecutionContext*,
                     std::unique_ptr<WebDocumentSubresourceFilter>);
   ~SubresourceFilter();
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc
index ca59878..c760dc2 100644
--- a/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -230,7 +230,8 @@
 void ThreadableLoader::Start(const ResourceRequest& request) {
   original_security_origin_ = security_origin_ = request.RequestorOrigin();
   // Setting an outgoing referer is only supported in the async code path.
-  DCHECK(async_ || request.HttpReferrer().IsEmpty());
+  DCHECK(async_ ||
+         request.ReferrerString() == Referrer::ClientReferrerString());
 
   bool cors_enabled = cors::IsCorsEnabledRequestMode(request.GetMode());
 
@@ -672,10 +673,8 @@
 
     // Save the referrer to use when following the redirect.
     override_referrer_ = true;
-    // TODO(domfarolino): Use ReferrerString() once https://crbug.com/850813 is
-    // closed and we stop storing the referrer string as a `Referer` header.
     referrer_after_redirect_ =
-        Referrer(new_request.HttpReferrer(), new_request.GetReferrerPolicy());
+        Referrer(new_request.ReferrerString(), new_request.GetReferrerPolicy());
   }
   // We're initiating a new request (for redirect), so update
   // |last_request_url_| by destroying |assign_on_scope_exit|.
@@ -685,7 +684,9 @@
 
   // Remove any headers that may have been added by the network layer that cause
   // access control to fail.
-  cross_origin_request.ClearHTTPReferrer();
+  cross_origin_request.SetReferrerString(Referrer::NoReferrer());
+  cross_origin_request.SetReferrerPolicy(
+      network::mojom::ReferrerPolicy::kDefault);
   cross_origin_request.ClearHTTPOrigin();
   cross_origin_request.ClearHTTPUserAgent();
   // Add any request headers which we previously saved from the
diff --git a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
index 5e6af15..b6ec121 100644
--- a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
+++ b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
@@ -37,6 +37,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
+#include "services/network/public/cpp/request_destination.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -61,6 +62,7 @@
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/weborigin/referrer.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -368,7 +370,18 @@
       new_request.SetHttpMethod(FetchUtils::NormalizeMethod(method));
       HTTPRequestHeaderValidator validator;
       new_request.VisitHttpHeaderFields(&validator);
-      allow_load = validator.IsSafe();
+
+      // The request's referrer string is not stored as a header, so we must
+      // consult it separately, if set.
+      if (request.ReferrerString() !=
+          blink::WebString(Referrer::ClientReferrerString())) {
+        DCHECK(cors::IsForbiddenHeaderName("Referer"));
+        // `Referer` is a forbidden header name, so we must disallow this to
+        // load.
+        allow_load = false;
+      }
+
+      allow_load = allow_load && validator.IsSafe();
     }
   }
   new_request.ToMutableResourceRequest().SetCorsPreflightPolicy(
@@ -413,6 +426,8 @@
       // (P2PPortAllocatorSession::AllocateLegacyRelaySession, for example).
       // Remove this once those places are patched up.
       new_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
+      new_request.SetRequestDestination(
+          network::mojom::RequestDestination::kEmpty);
     } else if (context == mojom::RequestContextType::VIDEO) {
       resource_loader_options.initiator_info.name =
           fetch_initiator_type_names::kVideo;
diff --git a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
index be5939b..2fd0e74 100644
--- a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
+++ b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
@@ -185,8 +185,8 @@
     request.SetMode(network::mojom::RequestMode::kSameOrigin);
     request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
     if (EqualIgnoringASCIICase(WebString::FromUTF8(header_field), "referer")) {
-      request.SetHttpReferrer(WebString::FromUTF8(header_value),
-                              network::mojom::ReferrerPolicy::kDefault);
+      request.SetReferrerString(WebString::FromUTF8(header_value));
+      request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault);
     } else {
       request.SetHttpHeaderField(WebString::FromUTF8(header_field),
                                  WebString::FromUTF8(header_value));
@@ -617,6 +617,7 @@
   CheckHeaderFails("keep-alive");
   CheckHeaderFails("origin");
   CheckHeaderFails("referer", "http://example.com/");
+  CheckHeaderFails("referer", "");  // no-referrer.
   CheckHeaderFails("te");
   CheckHeaderFails("trailer");
   CheckHeaderFails("transfer-encoding");
diff --git a/third_party/blink/renderer/core/mathml/mathml_element.cc b/third_party/blink/renderer/core/mathml/mathml_element.cc
index 52bb3e3f..1b92d53 100644
--- a/third_party/blink/renderer/core/mathml/mathml_element.cc
+++ b/third_party/blink/renderer/core/mathml/mathml_element.cc
@@ -19,17 +19,17 @@
 MathMLElement::~MathMLElement() {}
 
 static inline bool IsValidDirAttribute(const AtomicString& value) {
-  return DeprecatedEqualIgnoringCase(value, "ltr") ||
-         DeprecatedEqualIgnoringCase(value, "rtl");
+  return EqualIgnoringASCIICase(value, "ltr") ||
+         EqualIgnoringASCIICase(value, "rtl");
 }
 
 // Keywords from MathML3 and CSS font-size are skipped.
 static inline bool IsDisallowedMathSizeAttribute(const AtomicString& value) {
-  return DeprecatedEqualIgnoringCase(value, "medium") ||
+  return EqualIgnoringASCIICase(value, "medium") ||
          value.EndsWith("large", kTextCaseASCIIInsensitive) ||
          value.EndsWith("small", kTextCaseASCIIInsensitive) ||
-         DeprecatedEqualIgnoringCase(value, "smaller") ||
-         DeprecatedEqualIgnoringCase(value, "larger");
+         EqualIgnoringASCIICase(value, "smaller") ||
+         EqualIgnoringASCIICase(value, "larger");
 }
 
 bool MathMLElement::IsPresentationAttribute(const QualifiedName& name) const {
diff --git a/third_party/blink/renderer/core/page/autoscroll_controller_test.cc b/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
index 33593bf8..27c3c134 100644
--- a/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
+++ b/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
@@ -58,9 +58,9 @@
   DCHECK(scrollable);
   DCHECK(scrollable->GetLayoutObject());
 
-  WebMouseEvent event(WebInputEvent::kMouseDown, WebFloatPoint(5, 5),
-                      WebFloatPoint(5, 5), WebPointerProperties::Button::kLeft,
-                      0, WebInputEvent::Modifiers::kLeftButtonDown,
+  WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(5, 5),
+                      gfx::PointF(5, 5), WebPointerProperties::Button::kLeft, 0,
+                      WebInputEvent::Modifiers::kLeftButtonDown,
                       base::TimeTicks::Now());
   event.SetFrameScale(1);
 
diff --git a/third_party/blink/renderer/core/page/context_menu_controller_test.cc b/third_party/blink/renderer/core/page/context_menu_controller_test.cc
index 894def7..c10f8b02 100644
--- a/third_party/blink/renderer/core/page/context_menu_controller_test.cc
+++ b/third_party/blink/renderer/core/page/context_menu_controller_test.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/public/platform/web_menu_source_type.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/web/web_context_menu_data.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -22,6 +23,7 @@
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 using testing::Return;
 
@@ -532,7 +534,7 @@
   )XML");
 
   Document* document = GetDocument();
-  ASSERT_TRUE(document->IsXMLDocument());
+  ASSERT_TRUE(IsA<XMLDocument>(document));
   ASSERT_FALSE(document->IsHTMLDocument());
 
   Element* text_element = document->getElementById("t");
@@ -562,7 +564,7 @@
   WebGestureEvent gesture_event(
       WebInputEvent::kGestureLongPress, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now(), WebGestureDevice::kTouchscreen);
-  gesture_event.SetPositionInWidget(WebFloatPoint(rect->left(), rect->top()));
+  gesture_event.SetPositionInWidget(gfx::PointF(rect->left(), rect->top()));
   GetWebView()->MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(gesture_event));
 
@@ -607,7 +609,7 @@
   WebGestureEvent gesture_event(
       WebInputEvent::kGestureLongPress, WebInputEvent::kNoModifiers,
       base::TimeTicks::Now(), WebGestureDevice::kTouchscreen);
-  gesture_event.SetPositionInWidget(WebFloatPoint(rect->left(), rect->top()));
+  gesture_event.SetPositionInWidget(gfx::PointF(rect->left(), rect->top()));
   GetWebView()->MainFrameWidget()->HandleInputEvent(
       WebCoalescedInputEvent(gesture_event));
 
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc
index 0d43067f..aded053 100644
--- a/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1191,35 +1191,27 @@
   return nullptr;
 }
 
+// This is an implementation of step 2 of the "shadow host" branch of
+// https://html.spec.whatwg.org/C/#get-the-focusable-area
 Element* FocusController::FindFocusableElementInShadowHost(
     const Element& shadow_host) {
   DCHECK(shadow_host.AuthorShadowRoot());
-  OwnerMap owner_map;
-  ScopedFocusNavigation scope =
-      ScopedFocusNavigation::OwnedByShadowHost(shadow_host, owner_map);
-  Element* result = FindFocusableElementAcrossFocusScopes(kWebFocusTypeForward,
-                                                          scope, owner_map);
-  if (!result)
-    return nullptr;
-  // Check if |found| is the first focusable element under |element|, and count
-  // if it's not.
-  const Node* current = &shadow_host;
-  while ((current = FlatTreeTraversal::Next(*current))) {
-    if (!current->IsElementNode())
-      continue;
-    if (current == result) {
-      // We've reached |found|, which means |found| is the first focusable
-      // element so we don't count this.
-      break;
-    }
-    if (To<Element>(current)->IsFocusable()) {
-      UseCounter::Count(shadow_host.GetDocument(),
-                        WebFeature::kDelegateFocusNotFirstInFlatTree);
-      break;
+  // We have no behavior difference by focus trigger. Skip step 2.1.
+
+  // 2.2. Otherwise, let possible focus delegates be the list of all
+  //   focusable areas whose DOM anchor is a descendant of focus target
+  //   in the flat tree.
+  // 2.3. Return the first focusable area in tree order of their DOM
+  //   anchors in possible focus delegates, or null if possible focus
+  //   delegates is empty.
+  Node* current = const_cast<Element*>(&shadow_host);
+  while ((current = FlatTreeTraversal::Next(*current, &shadow_host))) {
+    if (auto* current_element = DynamicTo<Element>(current)) {
+      if (current_element->IsFocusable())
+        return current_element;
     }
   }
-
-  return result;
+  return nullptr;
 }
 
 Element* FocusController::FindFocusableElementAfter(Element& element,
diff --git a/third_party/blink/renderer/core/page/focus_controller.h b/third_party/blink/renderer/core/page/focus_controller.h
index 22c6067..66db18aa 100644
--- a/third_party/blink/renderer/core/page/focus_controller.h
+++ b/third_party/blink/renderer/core/page/focus_controller.h
@@ -83,7 +83,7 @@
       RemoteFrame* from,
       LocalFrame* to,
       InputDeviceCapabilities* source_capabilities = nullptr);
-  Element* FindFocusableElementInShadowHost(const Element& shadow_host);
+  static Element* FindFocusableElementInShadowHost(const Element& shadow_host);
   Element* NextFocusableElementInForm(Element*, WebFocusType);
   Element* FindFocusableElementAfter(Element& element, WebFocusType);
 
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 90c4ea4..ac1213a 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -1036,8 +1036,6 @@
 
 Page::PageClients::PageClients() : chrome_client(nullptr) {}
 
-Page::PageClients::~PageClients() = default;
-
 template class CORE_TEMPLATE_EXPORT Supplement<Page>;
 
 const char InternalSettingsPageSupplementBase::kSupplementName[] =
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h
index e968b10..7af9cce 100644
--- a/third_party/blink/renderer/core/page/page.h
+++ b/third_party/blink/renderer/core/page/page.h
@@ -103,7 +103,6 @@
 
    public:
     PageClients();
-    ~PageClients();
 
     Member<ChromeClient> chrome_client;
     DISALLOW_COPY_AND_ASSIGN(PageClients);
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index f67f9f54..57a3bfe 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -164,7 +164,7 @@
                                               int delta_y) {
     WebGestureEvent event(type, WebInputEvent::kNoModifiers,
                           WebInputEvent::GetStaticTimeStampForTests(), device);
-    event.SetPositionInWidget(WebFloatPoint(100, 100));
+    event.SetPositionInWidget(gfx::PointF(100, 100));
     if (type == WebInputEvent::kGestureScrollUpdate) {
       event.data.scroll_update.delta_x = delta_x;
       event.data.scroll_update.delta_y = delta_y;
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
index d26d801e..8b10fce4 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
@@ -33,7 +33,10 @@
   size_t end_pos = 0;
   while (end_pos != kNotFound) {
     if (fragment.Find(kTextFragmentIdentifierPrefix, start_pos) != start_pos) {
-      return false;
+      // If this is not a text directive, continue to the next directive
+      end_pos = fragment.find('&', start_pos + 1);
+      start_pos = end_pos + 1;
+      continue;
     }
 
     start_pos += kTextFragmentIdentifierPrefixStringLength;
@@ -46,10 +49,13 @@
       target_text = fragment.Substring(start_pos, end_pos - start_pos);
       start_pos = end_pos + 1;
     }
-    out_selectors->push_back(TextFragmentSelector::Create(target_text));
+
+    TextFragmentSelector selector = TextFragmentSelector::Create(target_text);
+    if (selector.Type() != TextFragmentSelector::kInvalid)
+      out_selectors->push_back(selector);
   }
 
-  return true;
+  return out_selectors->size() > 0;
 }
 
 bool CheckSecurityRestrictions(LocalFrame& frame,
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
index 6a68f12d..f3cbba8 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
@@ -35,10 +35,10 @@
   }
 
   void SimulateClick(int x, int y) {
-    WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+                        gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kLeftButtonDown,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
   }
@@ -298,7 +298,7 @@
       {"#foo:~:bar", kCounted},
       {"#:~:utext=foo", kCounted},
       {"#:~:text=foo", kUncounted},
-      {"#:~:text=foo&invalid", kCounted},
+      {"#:~:text=foo&invalid", kUncounted},
       {"#foo:~:text=foo", kUncounted}};
 
   for (auto test_case : test_cases) {
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
index aa00bcf..8743493 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -56,10 +56,10 @@
   }
 
   void SimulateClick(int x, int y) {
-    WebMouseEvent event(
-        WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
-        WebPointerProperties::Button::kLeft, 0,
-        WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+    WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+                        gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+                        0, WebInputEvent::Modifiers::kLeftButtonDown,
+                        base::TimeTicks::Now());
     event.SetFrameScale(1);
     GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
   }
@@ -68,8 +68,8 @@
     WebGestureEvent event(WebInputEvent::kGestureTap,
                           WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                           WebGestureDevice::kTouchscreen);
-    event.SetPositionInWidget(FloatPoint(x, y));
-    event.SetPositionInScreen(FloatPoint(x, y));
+    event.SetPositionInWidget(gfx::PointF(x, y));
+    event.SetPositionInScreen(gfx::PointF(x, y));
     event.SetFrameScale(1);
     GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(event);
   }
@@ -1583,6 +1583,43 @@
   EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
 }
 
+// Ensure that we can have text directives combined with non-text directives
+TEST_F(TextFragmentAnchorTest, NonTextDirectives) {
+  SimRequest request(
+      "https://example.com/test.html#:~:text=test&directive&text=more",
+      "text/html");
+  LoadURL("https://example.com/test.html#:~:text=test&directive&text=more");
+  request.Complete(R"HTML(
+    <!DOCTYPE html>
+    <style>
+      body {
+        height: 2200px;
+      }
+      #first {
+        position: absolute;
+        top: 1000px;
+      }
+      #second {
+        position: absolute;
+        top: 2000px;
+      }
+    </style>
+    <p id="first">This is a test page</p>
+    <p id="second">This is some more text</p>
+  )HTML");
+  Compositor().BeginFrame();
+
+  RunAsyncMatchingTasks();
+
+  Element& first = *GetDocument().getElementById("first");
+
+  EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(first)))
+      << "First <p> wasn't scrolled into view, viewport's scroll offset: "
+      << LayoutViewport()->GetScrollOffset().ToString();
+
+  EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+}
+
 }  // namespace
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
index 57f61ae..42c93d9 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
@@ -50,6 +50,11 @@
 
   size_t comma_pos = target_text.find(',');
 
+  // If there are more commas, this is an invalid text fragment selector.
+  size_t next_comma_pos = target_text.find(',', comma_pos + 1);
+  if (next_comma_pos != kNotFound)
+    return TextFragmentSelector(kInvalid);
+
   if (comma_pos == kNotFound) {
     type = kExact;
     start = target_text;
@@ -74,4 +79,6 @@
                                            const String& suffix)
     : type_(type), start_(start), end_(end), prefix_(prefix), suffix_(suffix) {}
 
+TextFragmentSelector::TextFragmentSelector(SelectorType type) : type_(type) {}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
index d0f16a6..536cdb59 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
@@ -17,6 +17,8 @@
   static TextFragmentSelector Create(String target_text);
 
   enum SelectorType {
+    // An invalid text selector.
+    kInvalid,
     // An exact selector on the string start_.
     kExact,
     // A range selector on a text range start_ to end_.
@@ -28,6 +30,7 @@
                        const String& end,
                        const String& prefix,
                        const String& suffix);
+  TextFragmentSelector(SelectorType type);
   ~TextFragmentSelector() = default;
 
   SelectorType Type() const { return type_; }
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc
new file mode 100644
index 0000000..3cf54d1a
--- /dev/null
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc
@@ -0,0 +1,95 @@
+// 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/page/scrolling/text_fragment_selector.h"
+
+#include <gtest/gtest.h>
+
+namespace blink {
+
+class TextFragmentSelectorTest : public testing::Test {
+ protected:
+  bool Equals(TextFragmentSelector a, TextFragmentSelector b) {
+    return a.Type() == b.Type() && a.Start() == b.Start() &&
+           a.End() == b.End() && a.Prefix() == b.Prefix() &&
+           a.Suffix() == b.Suffix();
+  }
+};
+
+TEST_F(TextFragmentSelectorTest, ExactText) {
+  TextFragmentSelector selector = TextFragmentSelector::Create("test");
+  TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "", "",
+                                "");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithPrefix) {
+  TextFragmentSelector selector = TextFragmentSelector::Create("prefix-,test");
+  TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "",
+                                "prefix", "");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithSuffix) {
+  TextFragmentSelector selector = TextFragmentSelector::Create("test,-suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "", "",
+                                "suffix");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithContext) {
+  TextFragmentSelector selector =
+      TextFragmentSelector::Create("prefix-,test,-suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "",
+                                "prefix", "suffix");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRange) {
+  TextFragmentSelector selector = TextFragmentSelector::Create("test,page");
+  TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+                                "", "");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithPrefix) {
+  TextFragmentSelector selector =
+      TextFragmentSelector::Create("prefix-,test,page");
+  TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+                                "prefix", "");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithSuffix) {
+  TextFragmentSelector selector =
+      TextFragmentSelector::Create("test,page,-suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+                                "", "suffix");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithContext) {
+  TextFragmentSelector selector =
+      TextFragmentSelector::Create("prefix-,test,page,-suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+                                "prefix", "suffix");
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, InvalidContext) {
+  TextFragmentSelector selector =
+      TextFragmentSelector::Create("prefix,test,page,suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kInvalid);
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TooManyParameters) {
+  TextFragmentSelector selector = TextFragmentSelector::Create(
+      "prefix-,exact text, that has commas, which are not percent "
+      "encoded,-suffix");
+  TextFragmentSelector expected(TextFragmentSelector::kInvalid);
+  EXPECT_TRUE(Equals(selector, expected));
+}
+
+}  // namespace blink
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 5248b8f4..b99cf22 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
@@ -201,9 +201,6 @@
 }
 
 CompositedLayerMapping::~CompositedLayerMapping() {
-  // Hits in compositing/squashing/squash-onto-nephew.html.
-  DisableCompositingQueryAsserts disabler;
-
   // Do not leave the destroyed pointer dangling on any Layers that painted to
   // this mapping's squashing layer.
   for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
@@ -222,7 +219,6 @@
   UpdateMaskLayer(false);
   UpdateScrollingLayers(false);
   UpdateSquashingLayers(false);
-  DestroyGraphicsLayers();
 }
 
 std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
@@ -248,18 +244,6 @@
   graphics_layer_->SetHitTestable(true);
 }
 
-void CompositedLayerMapping::DestroyGraphicsLayers() {
-  if (graphics_layer_)
-    graphics_layer_->RemoveFromParent();
-
-  graphics_layer_ = nullptr;
-  foreground_layer_ = nullptr;
-  mask_layer_ = nullptr;
-
-  scrolling_layer_ = nullptr;
-  scrolling_contents_layer_ = nullptr;
-}
-
 void CompositedLayerMapping::UpdateBackgroundPaintsOntoScrollingContentsLayer(
     bool& invalidate_graphics_layer,
     bool& invalidate_scrolling_contents_layer) {
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
index 4d96ad6a..83253fe 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -323,7 +323,6 @@
   void UpdateScrollingLayerGeometry();
 
   void CreatePrimaryGraphicsLayer();
-  void DestroyGraphicsLayers();
 
   std::unique_ptr<GraphicsLayer> CreateGraphicsLayer(
       CompositingReasons,
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 a70e6ff..2200209 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
@@ -45,8 +45,6 @@
     PaintLayerCompositor* compositor)
     : compositor_(compositor), layers_changed_(false) {}
 
-CompositingLayerAssigner::~CompositingLayerAssigner() = default;
-
 void CompositingLayerAssigner::Assign(
     PaintLayer* update_root,
     Vector<PaintLayer*>& layers_needing_paint_invalidation) {
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 e4e34b37..557f5572 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
@@ -43,7 +43,6 @@
 
  public:
   explicit CompositingLayerAssigner(PaintLayerCompositor*);
-  ~CompositingLayerAssigner();
 
   void Assign(PaintLayer* update_root,
               Vector<PaintLayer*>& layers_needing_paint_invalidation);
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
index 3dc431d..0b9f70b8 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -210,8 +210,6 @@
     LayoutView& layout_view)
     : layout_view_(layout_view) {}
 
-CompositingRequirementsUpdater::~CompositingRequirementsUpdater() = default;
-
 void CompositingRequirementsUpdater::Update(
     PaintLayer* root,
     CompositingReasonsStats& compositing_reasons_stats) {
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
index dcb9464a..6f1d051d 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
@@ -42,7 +42,6 @@
 
  public:
   CompositingRequirementsUpdater(LayoutView&);
-  ~CompositingRequirementsUpdater();
 
   //  Recurse through the layers in z-index and overflow order (which is
   //  equivalent to painting order)
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
index bceebbc..6e5eaa16 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
@@ -38,8 +38,6 @@
 
 GraphicsLayerTreeBuilder::GraphicsLayerTreeBuilder() = default;
 
-GraphicsLayerTreeBuilder::~GraphicsLayerTreeBuilder() = default;
-
 static bool ShouldAppendLayer(const PaintLayer& layer) {
   auto* video_element =
       DynamicTo<HTMLVideoElement>(layer.GetLayoutObject().GetNode());
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
index 88e607b9..b1ef0a4 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
@@ -39,7 +39,6 @@
 
  public:
   GraphicsLayerTreeBuilder();
-  ~GraphicsLayerTreeBuilder();
 
   void Rebuild(PaintLayer&, GraphicsLayerVector&);
 
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 e1df9970..3026c27 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
@@ -104,8 +104,6 @@
 
 GraphicsLayerUpdater::GraphicsLayerUpdater() : needs_rebuild_tree_(false) {}
 
-GraphicsLayerUpdater::~GraphicsLayerUpdater() = default;
-
 void GraphicsLayerUpdater::Update(
     PaintLayer& layer,
     Vector<PaintLayer*>& layers_needing_paint_invalidation) {
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
index 9a98a93..54c765cc 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
@@ -39,7 +39,6 @@
 
  public:
   GraphicsLayerUpdater();
-  ~GraphicsLayerUpdater();
 
   enum UpdateType {
     kDoNotForceUpdate,
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
index 3b0ff3b..c9fe232c 100644
--- a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
+++ b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -141,14 +141,14 @@
 
   // The coordinates below are linked to absolute positions in the referenced
   // .html file.
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 20));
 
   ASSERT_TRUE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
 
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 40));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 40));
   EXPECT_FALSE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
 
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 20));
   // Shouldn't crash.
   web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
 
@@ -158,7 +158,7 @@
   EXPECT_TRUE(highlight->LayerForTesting(0));
 
   // Find a target inside a scrollable div
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 100));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 100));
   web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
   ASSERT_TRUE(highlight);
 
@@ -167,11 +167,11 @@
 
   // Don't highlight if no "hand cursor"
   touch_event.SetPositionInWidget(
-      WebFloatPoint(20, 220));  // An A-link with cross-hair cursor.
+      gfx::PointF(20, 220));  // An A-link with cross-hair cursor.
   web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
   EXPECT_FALSE(GetLinkHighlightImpl());
 
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 260));  // A text input box.
+  touch_event.SetPositionInWidget(gfx::PointF(20, 260));  // A text input box.
   web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
   EXPECT_FALSE(GetLinkHighlightImpl());
 }
@@ -188,7 +188,7 @@
                               WebInputEvent::kNoModifiers,
                               WebInputEvent::GetStaticTimeStampForTests(),
                               WebGestureDevice::kTouchscreen);
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 20));
 
   GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
   Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -220,7 +220,7 @@
                               WebInputEvent::kNoModifiers,
                               WebInputEvent::GetStaticTimeStampForTests(),
                               WebGestureDevice::kTouchscreen);
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 20));
 
   GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
   Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -245,7 +245,7 @@
                               WebInputEvent::kNoModifiers,
                               WebInputEvent::GetStaticTimeStampForTests(),
                               WebGestureDevice::kTouchscreen);
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 20));
 
   GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
   Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -309,7 +309,7 @@
                               WebInputEvent::GetStaticTimeStampForTests(),
                               WebGestureDevice::kTouchscreen);
   // This will touch the link under multicol.
-  touch_event.SetPositionInWidget(WebFloatPoint(20, 300));
+  touch_event.SetPositionInWidget(gfx::PointF(20, 300));
 
   GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
   Node* touch_node = web_view_impl->BestTapNode(targeted_event);
diff --git a/third_party/blink/renderer/core/paint/theme_painter.cc b/third_party/blink/renderer/core/paint/theme_painter.cc
index 8535fc1..ad3d89b 100644
--- a/third_party/blink/renderer/core/paint/theme_painter.cc
+++ b/third_party/blink/renderer/core/paint/theme_painter.cc
@@ -192,6 +192,10 @@
       auto* input = DynamicTo<HTMLInputElement>(node);
       if (!input || input->type() != input_type_names::kCheckbox)
         DEPRECATE_APPEARANCE(doc, CheckboxForOthers);
+      // Count usage of non-rectangular checkbox and radio buttons.
+      if (r.Width() != r.Height()) {
+        UseCounter::Count(doc, WebFeature::kInputTypeCheckboxRenderedNonSquare);
+      }
       return PaintCheckbox(node, o.GetDocument(), style, paint_info, r);
     }
     case kRadioPart: {
@@ -199,6 +203,10 @@
       auto* input = DynamicTo<HTMLInputElement>(node);
       if (!input || input->type() != input_type_names::kRadio)
         DEPRECATE_APPEARANCE(doc, RadioForOthers);
+      // Count usage of non-rectangular checkbox and radio buttons.
+      if (r.Width() != r.Height()) {
+        UseCounter::Count(doc, WebFeature::kInputTypeRadioRenderedNonSquare);
+      }
       return PaintRadio(node, o.GetDocument(), style, paint_info, r);
     }
     case kPushButtonPart: {
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
index cb2a726..d0eb4560 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
@@ -265,7 +265,8 @@
   if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context))
     scope->EnsureFetcher();
   modulator_->FetchTree(url, execution_context->Fetcher(),
-                        mojom::RequestContextType::SCRIPT, options,
+                        mojom::RequestContextType::SCRIPT,
+                        network::mojom::RequestDestination::kScript, options,
                         ModuleScriptCustomFetchType::kNone, tree_client);
 
   // Steps 6-9 are implemented at
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index 5ccf159d..bc58f76 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -74,6 +74,7 @@
   void FetchTree(const KURL& url,
                  ResourceFetcher*,
                  mojom::RequestContextType,
+                 network::mojom::RequestDestination,
                  const ScriptFetchOptions&,
                  ModuleScriptCustomFetchType custom_fetch_type,
                  ModuleTreeClient* client) final {
diff --git a/third_party/blink/renderer/core/script/modulator.h b/third_party/blink/renderer/core/script/modulator.h
index 39b6255..10bee917 100644
--- a/third_party/blink/renderer/core/script/modulator.h
+++ b/third_party/blink/renderer/core/script/modulator.h
@@ -132,7 +132,8 @@
   // used in the "fetch a module worker script graph" algorithm.
   virtual void FetchTree(const KURL&,
                          ResourceFetcher* fetch_client_settings_object_fetcher,
-                         mojom::RequestContextType destination,
+                         mojom::RequestContextType context_type,
+                         network::mojom::RequestDestination destination,
                          const ScriptFetchOptions&,
                          ModuleScriptCustomFetchType,
                          ModuleTreeClient*) = 0;
@@ -154,7 +155,8 @@
   virtual void FetchDescendantsForInlineScript(
       ModuleScript*,
       ResourceFetcher* fetch_client_settings_object_fetcher,
-      mojom::RequestContextType destination,
+      mojom::RequestContextType context_type,
+      network::mojom::RequestDestination destination,
       ModuleTreeClient*) = 0;
 
   // Synchronously retrieves a single module script from existing module map
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.cc b/third_party/blink/renderer/core/script/modulator_impl_base.cc
index b32a3ee..fa3f472 100644
--- a/third_party/blink/renderer/core/script/modulator_impl_base.cc
+++ b/third_party/blink/renderer/core/script/modulator_impl_base.cc
@@ -136,23 +136,26 @@
 void ModulatorImplBase::FetchTree(
     const KURL& url,
     ResourceFetcher* fetch_client_settings_object_fetcher,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     const ScriptFetchOptions& options,
     ModuleScriptCustomFetchType custom_fetch_type,
     ModuleTreeClient* client) {
   ModuleTreeLinker::Fetch(url, fetch_client_settings_object_fetcher,
-                          destination, options, this, custom_fetch_type,
-                          tree_linker_registry_, client);
+                          context_type, destination, options, this,
+                          custom_fetch_type, tree_linker_registry_, client);
 }
 
 void ModulatorImplBase::FetchDescendantsForInlineScript(
     ModuleScript* module_script,
     ResourceFetcher* fetch_client_settings_object_fetcher,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     ModuleTreeClient* client) {
   ModuleTreeLinker::FetchDescendantsForInlineScript(
-      module_script, fetch_client_settings_object_fetcher, destination, this,
-      ModuleScriptCustomFetchType::kNone, tree_linker_registry_, client);
+      module_script, fetch_client_settings_object_fetcher, context_type,
+      destination, this, ModuleScriptCustomFetchType::kNone,
+      tree_linker_registry_, client);
 }
 
 void ModulatorImplBase::FetchSingle(
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.h b/third_party/blink/renderer/core/script/modulator_impl_base.h
index ce0267f4..a7097b2 100644
--- a/third_party/blink/renderer/core/script/modulator_impl_base.h
+++ b/third_party/blink/renderer/core/script/modulator_impl_base.h
@@ -57,14 +57,16 @@
 
   void FetchTree(const KURL&,
                  ResourceFetcher* fetch_client_settings_object_fetcher,
-                 mojom::RequestContextType destination,
+                 mojom::RequestContextType context_type,
+                 network::mojom::RequestDestination destination,
                  const ScriptFetchOptions&,
                  ModuleScriptCustomFetchType,
                  ModuleTreeClient*) override;
   void FetchDescendantsForInlineScript(
       ModuleScript*,
       ResourceFetcher* fetch_client_settings_object_fetcher,
-      mojom::RequestContextType destination,
+      mojom::RequestContextType context_type,
+      network::mojom::RequestDestination destination,
       ModuleTreeClient*) override;
   void FetchSingle(const ModuleScriptFetchRequest&,
                    ResourceFetcher* fetch_client_settings_object_fetcher,
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc
index 7311339..4d09c84e9 100644
--- a/third_party/blink/renderer/core/script/script_loader.cc
+++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -581,7 +581,8 @@
       // script CORS setting, and encoding.</spec>
       Document* document_for_origin = &element_document;
       if (base::FeatureList::IsEnabled(
-              features::kHtmlImportsRequestInitiatorLock)) {
+              features::kHtmlImportsRequestInitiatorLock) &&
+          element_document.ImportsController()) {
         document_for_origin = context_document;
       }
       FetchClassicScript(url, *document_for_origin, options, cross_origin,
@@ -717,7 +718,8 @@
             MakeGarbageCollected<ModulePendingScriptTreeClient>();
         modulator->FetchDescendantsForInlineScript(
             module_script, fetch_client_settings_object_fetcher,
-            mojom::RequestContextType::SCRIPT, module_tree_client);
+            mojom::RequestContextType::SCRIPT,
+            network::mojom::RequestDestination::kScript, module_tree_client);
         prepared_pending_script_ = MakeGarbageCollected<ModulePendingScript>(
             element_, module_tree_client, is_external_script_);
         break;
@@ -934,7 +936,8 @@
   auto* module_tree_client =
       MakeGarbageCollected<ModulePendingScriptTreeClient>();
   modulator->FetchTree(url, fetch_client_settings_object_fetcher,
-                       mojom::RequestContextType::SCRIPT, options,
+                       mojom::RequestContextType::SCRIPT,
+                       network::mojom::RequestDestination::kScript, options,
                        ModuleScriptCustomFetchType::kNone, module_tree_client);
   prepared_pending_script_ = MakeGarbageCollected<ModulePendingScript>(
       element_, module_tree_client, is_external_script_);
diff --git a/third_party/blink/renderer/core/streams/queue_with_sizes.cc b/third_party/blink/renderer/core/streams/queue_with_sizes.cc
index 1fcd96a..d46e3d88 100644
--- a/third_party/blink/renderer/core/streams/queue_with_sizes.cc
+++ b/third_party/blink/renderer/core/streams/queue_with_sizes.cc
@@ -42,7 +42,6 @@
 };
 
 QueueWithSizes::QueueWithSizes() = default;
-QueueWithSizes::~QueueWithSizes() = default;
 
 v8::Local<v8::Value> QueueWithSizes::DequeueValue(v8::Isolate* isolate) {
   DCHECK(!queue_.empty());
diff --git a/third_party/blink/renderer/core/streams/queue_with_sizes.h b/third_party/blink/renderer/core/streams/queue_with_sizes.h
index c114ea7..fee10c34 100644
--- a/third_party/blink/renderer/core/streams/queue_with_sizes.h
+++ b/third_party/blink/renderer/core/streams/queue_with_sizes.h
@@ -25,7 +25,6 @@
     : public GarbageCollected<QueueWithSizes> {
  public:
   QueueWithSizes();
-  ~QueueWithSizes();
 
   // https://streams.spec.whatwg.org/#dequeue-value
   v8::Local<v8::Value> DequeueValue(v8::Isolate*);
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
index fb08984..98d0ff0 100644
--- a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
@@ -41,8 +41,6 @@
                 v8::Promise::Resolver::New(script_state->GetContext())
                     .ToLocalChecked()) {}
 
-StreamPromiseResolver::~StreamPromiseResolver() = default;
-
 void StreamPromiseResolver::Resolve(ScriptState* script_state,
                                     v8::Local<v8::Value> value) {
   DCHECK(!resolver_.IsEmpty());
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.h b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
index 02a7014..500ecd7b 100644
--- a/third_party/blink/renderer/core/streams/stream_promise_resolver.h
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.h
@@ -47,7 +47,6 @@
 
   // Creates an initialised promise.
   explicit StreamPromiseResolver(ScriptState*);
-  ~StreamPromiseResolver();
 
   // Resolves the promise with |value|. Does nothing if the promise is already
   // settled.
diff --git a/third_party/blink/renderer/core/style/BUILD.gn b/third_party/blink/renderer/core/style/BUILD.gn
index 34c2906a..d4694d742 100644
--- a/third_party/blink/renderer/core/style/BUILD.gn
+++ b/third_party/blink/renderer/core/style/BUILD.gn
@@ -94,6 +94,8 @@
     "style_variables.cc",
     "style_variables.h",
     "text_size_adjust.h",
+    "ua_style.cc",
+    "ua_style.h",
   ]
 }
 
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 7f502c6..5552ab05 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -1967,17 +1967,6 @@
   GetFont().Update(current_font_selector);
 }
 
-void ComputedStyle::SetFontVariantNumericSpacing(
-    FontVariantNumeric::NumericSpacing numeric_spacing) {
-  FontSelector* current_font_selector = GetFont().GetFontSelector();
-  FontDescription desc(GetFontDescription());
-  FontVariantNumeric variant_numeric = desc.VariantNumeric();
-  variant_numeric.SetNumericSpacing(numeric_spacing);
-  desc.SetVariantNumeric(variant_numeric);
-  SetFontDescription(desc);
-  GetFont().Update(current_font_selector);
-}
-
 void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
   SetTextAutosizingMultiplierInternal(multiplier);
 
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index fbb92eb..5156dec 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -106,6 +106,11 @@
 class Fill;
 class Float;
 class FloodColor;
+class InternalUaBackgroundColor;
+class InternalUaBorderBottomColor;
+class InternalUaBorderLeftColor;
+class InternalUaBorderRightColor;
+class InternalUaBorderTopColor;
 class InternalVisitedBackgroundColor;
 class InternalVisitedBorderBottomColor;
 class InternalVisitedBorderLeftColor;
@@ -211,6 +216,11 @@
   friend class css_longhand::Fill;
   friend class css_longhand::Float;
   friend class css_longhand::FloodColor;
+  friend class css_longhand::InternalUaBackgroundColor;
+  friend class css_longhand::InternalUaBorderBottomColor;
+  friend class css_longhand::InternalUaBorderLeftColor;
+  friend class css_longhand::InternalUaBorderRightColor;
+  friend class css_longhand::InternalUaBorderTopColor;
   friend class css_longhand::InternalVisitedBackgroundColor;
   friend class css_longhand::InternalVisitedBorderBottomColor;
   friend class css_longhand::InternalVisitedBorderLeftColor;
@@ -237,6 +247,7 @@
   // Access to private Appearance() and HasAppearance().
   friend class LayoutTheme;
   friend class StyleAdjuster;
+  friend class StyleCascade;
   friend class css_longhand::WebkitAppearance;
   // Editing has to only reveal unvisited info.
   friend class ApplyStyleCommand;
@@ -248,6 +259,7 @@
   friend class StyleBuilderFunctions;
   // Saves Border/Background information for later comparison.
   friend class CachedUAStyle;
+  friend class UAStyle;
   // Accesses visited and unvisited colors.
   friend class ColorPropertyFunctions;
   // Edits the background for media controls.
@@ -1075,9 +1087,6 @@
   float WordSpacing() const { return GetFontDescription().WordSpacing(); }
   void SetWordSpacing(float);
 
-  // font-variant-numeric spacing
-  void SetFontVariantNumericSpacing(FontVariantNumeric::NumericSpacing);
-
   // orphans
   void SetOrphans(int16_t o) { SetOrphansInternal(clampTo<int16_t>(o, 1)); }
 
diff --git a/third_party/blink/renderer/core/style/nine_piece_image.h b/third_party/blink/renderer/core/style/nine_piece_image.h
index e50133b..5faaecae 100644
--- a/third_party/blink/renderer/core/style/nine_piece_image.h
+++ b/third_party/blink/renderer/core/style/nine_piece_image.h
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/style/border_image_length_box.h"
+#include "third_party/blink/renderer/core/style/data_equivalency.h"
 #include "third_party/blink/renderer/core/style/data_ref.h"
 #include "third_party/blink/renderer/core/style/style_image.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
@@ -98,6 +99,10 @@
     return data_ != other.data_;
   }
 
+  bool DataEquals(const NinePieceImage& other) const {
+    return DataEquivalent(data_.Get(), other.data_.Get());
+  }
+
   bool HasImage() const { return data_->image; }
   StyleImage* GetImage() const { return data_->image.Get(); }
   void SetImage(StyleImage* image) { data_.Access()->image = image; }
diff --git a/third_party/blink/renderer/core/style/ua_style.cc b/third_party/blink/renderer/core/style/ua_style.cc
new file mode 100644
index 0000000..3697aa06
--- /dev/null
+++ b/third_party/blink/renderer/core/style/ua_style.cc
@@ -0,0 +1,99 @@
+// 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/style/ua_style.h"
+
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/style/computed_style_initial_values.h"
+
+namespace blink {
+
+namespace {
+
+LayoutUnit BorderWidth(LayoutUnit width, EBorderStyle style) {
+  if (style == EBorderStyle::kNone || style == EBorderStyle::kHidden) {
+    return LayoutUnit(0);
+  }
+  return width;
+}
+
+}  // namespace
+
+UAStyle::UAStyle()
+    : top_left_(ComputedStyleInitialValues::InitialBorderTopLeftRadius()),
+      top_right_(ComputedStyleInitialValues::InitialBorderTopRightRadius()),
+      bottom_left_(ComputedStyleInitialValues::InitialBorderBottomLeftRadius()),
+      bottom_right_(
+          ComputedStyleInitialValues::InitialBorderBottomRightRadius()),
+      border_left_color_(ComputedStyleInitialValues::InitialBorderColor()),
+      border_right_color_(ComputedStyleInitialValues::InitialBorderColor()),
+      border_top_color_(ComputedStyleInitialValues::InitialBorderColor()),
+      border_bottom_color_(ComputedStyleInitialValues::InitialBorderColor()),
+      border_left_style_(ComputedStyleInitialValues::InitialBorderLeftStyle()),
+      border_right_style_(
+          ComputedStyleInitialValues::InitialBorderRightStyle()),
+      border_top_style_(ComputedStyleInitialValues::InitialBorderTopStyle()),
+      border_bottom_style_(
+          ComputedStyleInitialValues::InitialBorderBottomStyle()),
+      border_left_width_(ComputedStyleInitialValues::InitialBorderLeftWidth()),
+      border_right_width_(
+          ComputedStyleInitialValues::InitialBorderRightWidth()),
+      border_top_width_(ComputedStyleInitialValues::InitialBorderTopWidth()),
+      border_bottom_width_(
+          ComputedStyleInitialValues::InitialBorderBottomWidth()),
+      border_image_(ComputedStyleInitialValues::InitialBorderImage()),
+      background_layers_(ComputedStyleInitialValues::InitialBackground()),
+      background_color_(ComputedStyleInitialValues::InitialBackgroundColor()) {}
+
+bool UAStyle::HasDifferentBackground(const ComputedStyle& other) const {
+  FillLayer other_background_layers = other.BackgroundLayers();
+  // Exclude background-repeat from comparison by resetting it.
+  other_background_layers.SetRepeatX(
+      FillLayer::InitialFillRepeatX(EFillLayerType::kBackground));
+  other_background_layers.SetRepeatY(
+      FillLayer::InitialFillRepeatY(EFillLayerType::kBackground));
+
+  return (!background_layers_.VisuallyEqual(other_background_layers) ||
+          background_color_ != other.BackgroundColor());
+}
+
+bool UAStyle::HasDifferentBorder(const ComputedStyle& other) const {
+  return !border_image_.DataEquals(other.BorderImage()) ||
+         !BorderColorEquals(other) || !BorderWidthEquals(other) ||
+         !BorderRadiiEquals(other) || !BorderStyleEquals(other);
+}
+
+bool UAStyle::BorderColorEquals(const ComputedStyle& other) const {
+  return border_left_color_ == other.BorderLeftColor() &&
+         border_right_color_ == other.BorderRightColor() &&
+         border_top_color_ == other.BorderTopColor() &&
+         border_bottom_color_ == other.BorderBottomColor();
+}
+
+bool UAStyle::BorderWidthEquals(const ComputedStyle& other) const {
+  return (BorderWidth(border_left_width_, border_left_style_) ==
+              other.BorderLeftWidth() &&
+          BorderWidth(border_right_width_, border_right_style_) ==
+              other.BorderRightWidth() &&
+          BorderWidth(border_top_width_, border_top_style_) ==
+              other.BorderTopWidth() &&
+          BorderWidth(border_bottom_width_, border_bottom_style_) ==
+              other.BorderBottomWidth());
+}
+
+bool UAStyle::BorderRadiiEquals(const ComputedStyle& other) const {
+  return top_left_ == other.BorderTopLeftRadius() &&
+         top_right_ == other.BorderTopRightRadius() &&
+         bottom_left_ == other.BorderBottomLeftRadius() &&
+         bottom_right_ == other.BorderBottomRightRadius();
+}
+
+bool UAStyle::BorderStyleEquals(const ComputedStyle& other) const {
+  return (border_left_style_ == other.BorderLeftStyle() &&
+          border_right_style_ == other.BorderRightStyle() &&
+          border_top_style_ == other.BorderTopStyle() &&
+          border_bottom_style_ == other.BorderBottomStyle());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/ua_style.h b/third_party/blink/renderer/core/style/ua_style.h
new file mode 100644
index 0000000..2ea06e6e6
--- /dev/null
+++ b/third_party/blink/renderer/core/style/ua_style.h
@@ -0,0 +1,86 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_UA_STYLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_UA_STYLE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "third_party/blink/renderer/core/css/style_color.h"
+#include "third_party/blink/renderer/core/style/fill_layer.h"
+#include "third_party/blink/renderer/core/style/nine_piece_image.h"
+#include "third_party/blink/renderer/platform/geometry/length_size.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class ComputedStyle;
+
+// This class represents the computed values we _would_ have had for background
+// and border properties had no user or author declarations existed. It is used
+// by LayoutTheme::AdjustStyle to figure out if the author has styled a given
+// form element.
+class CORE_EXPORT UAStyle {
+  USING_FAST_MALLOC(UAStyle);
+
+ public:
+  UAStyle();
+
+  bool HasDifferentBackground(const ComputedStyle& other) const;
+  bool HasDifferentBorder(const ComputedStyle& other) const;
+
+  bool BorderColorEquals(const ComputedStyle& other) const;
+  bool BorderWidthEquals(const ComputedStyle& other) const;
+  bool BorderRadiiEquals(const ComputedStyle& other) const;
+  bool BorderStyleEquals(const ComputedStyle& other) const;
+
+  FillLayer& AccessBackgroundLayers() { return background_layers_; }
+  void SetBackgroundColor(StyleColor c) { background_color_ = c; }
+  void SetBorderBottomColor(StyleColor v) { border_bottom_color_ = v; }
+  void SetBorderLeftColor(StyleColor v) { border_left_color_ = v; }
+  void SetBorderRightColor(StyleColor v) { border_right_color_ = v; }
+  void SetBorderTopColor(StyleColor v) { border_top_color_ = v; }
+  void SetBorderBottomStyle(EBorderStyle s) { border_bottom_style_ = s; }
+  void SetBorderLeftStyle(EBorderStyle s) { border_left_style_ = s; }
+  void SetBorderRightStyle(EBorderStyle s) { border_right_style_ = s; }
+  void SetBorderTopStyle(EBorderStyle s) { border_top_style_ = s; }
+  void SetBorderBottomWidth(float w) { border_bottom_width_ = LayoutUnit(w); }
+  void SetBorderLeftWidth(float w) { border_left_width_ = LayoutUnit(w); }
+  void SetBorderRightWidth(float w) { border_right_width_ = LayoutUnit(w); }
+  void SetBorderTopWidth(float w) { border_top_width_ = LayoutUnit(w); }
+  void SetBorderTopLeftRadius(const LengthSize& v) { top_left_ = v; }
+  void SetBorderTopRightRadius(const LengthSize& v) { top_right_ = v; }
+  void SetBorderBottomLeftRadius(const LengthSize& v) { bottom_left_ = v; }
+  void SetBorderBottomRightRadius(const LengthSize& v) { bottom_right_ = v; }
+  const NinePieceImage& BorderImage() const { return border_image_; }
+  void SetBorderImage(const NinePieceImage& v) { border_image_ = v; }
+
+ private:
+  LengthSize top_left_;
+  LengthSize top_right_;
+  LengthSize bottom_left_;
+  LengthSize bottom_right_;
+  StyleColor border_left_color_;
+  StyleColor border_right_color_;
+  StyleColor border_top_color_;
+  StyleColor border_bottom_color_;
+  EBorderStyle border_left_style_;
+  EBorderStyle border_right_style_;
+  EBorderStyle border_top_style_;
+  EBorderStyle border_bottom_style_;
+  LayoutUnit border_left_width_;
+  LayoutUnit border_right_width_;
+  LayoutUnit border_top_width_;
+  LayoutUnit border_bottom_width_;
+  NinePieceImage border_image_;
+  FillLayer background_layers_;
+  StyleColor background_color_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_UA_STYLE_H_
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index fab634f7..47771fca 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -183,18 +183,18 @@
   return frame->GetDocument()->AccessSVGExtensions().rootElement();
 }
 
-IntSize SVGImage::ContainerSize() const {
+LayoutSize SVGImage::ContainerSize() const {
   SVGSVGElement* root_element = SvgRootElement(page_.Get());
   if (!root_element)
-    return IntSize();
+    return LayoutSize();
 
   LayoutSVGRoot* layout_object =
       ToLayoutSVGRoot(root_element->GetLayoutObject());
   if (!layout_object)
-    return IntSize();
+    return LayoutSize();
 
   // If a container size is available it has precedence.
-  IntSize container_size = layout_object->ContainerSize();
+  LayoutSize container_size = layout_object->ContainerSize();
   if (!container_size.IsEmpty())
     return container_size;
 
@@ -205,6 +205,10 @@
   return intrinsic_size_;
 }
 
+IntSize SVGImage::Size() const {
+  return RoundedIntSize(intrinsic_size_);
+}
+
 static float ResolveWidthForRatio(float height,
                                   const FloatSize& intrinsic_ratio) {
   return height * intrinsic_ratio.Width() / intrinsic_ratio.Height();
@@ -303,7 +307,7 @@
   // re-laying out the image.
   ImageObserverDisabler image_observer_disabler(this);
 
-  IntSize rounded_container_size = RoundedIntSize(container_size);
+  LayoutSize rounded_container_size = RoundedLayoutSize(container_size);
 
   if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) {
     if (LayoutSVGRoot* layout_object =
@@ -448,12 +452,11 @@
 bool SVGImage::ApplyShaderInternal(PaintFlags& flags,
                                    const SkMatrix& local_matrix,
                                    const KURL& url) {
-  const IntSize size(ContainerSize());
+  const FloatSize size(ContainerSize());
   if (size.IsEmpty())
     return false;
 
-  IntRect bounds(IntPoint(), size);
-
+  FloatRect bounds(FloatPoint(), size);
   flags.setShader(PaintShader::MakePaintRecord(
       PaintRecordForCurrentFrame(url), bounds, SkTileMode::kRepeat,
       SkTileMode::kRepeat, &local_matrix));
@@ -505,8 +508,9 @@
 sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const KURL& url) {
   DCHECK(page_);
   LocalFrameView* view = To<LocalFrame>(page_->MainFrame())->View();
-  view->Resize(ContainerSize());
-  page_->GetVisualViewport().SetSize(ContainerSize());
+  IntSize rounded_container_size = RoundedIntSize(ContainerSize());
+  view->Resize(rounded_container_size);
+  page_->GetVisualViewport().SetSize(rounded_container_size);
 
   // Always call processUrlFragment, even if the url is empty, because
   // there may have been a previous url/fragment that needs to be reset.
@@ -816,7 +820,7 @@
   frame->GetDocument()->UpdateStyleAndLayoutTree();
 
   // Set the concrete object size before a container size is available.
-  intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize(
+  intrinsic_size_ = RoundedLayoutSize(ConcreteObjectSize(FloatSize(
       LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight)));
 
   DCHECK(page_);
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.h b/third_party/blink/renderer/core/svg/graphics/svg_image.h
index 8dd7b4a..8fce541 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.h
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.h
@@ -29,6 +29,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/geometry/layout_size.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -66,7 +67,7 @@
   static bool IsInSVGImage(const Node*);
 
   bool IsSVGImage() const override { return true; }
-  IntSize Size() const override { return intrinsic_size_; }
+  IntSize Size() const override;
 
   void CheckLoaded() const;
   bool CurrentFrameHasSingleSecurityOrigin() const override;
@@ -144,7 +145,7 @@
 
   String FilenameExtension() const override;
 
-  IntSize ContainerSize() const;
+  LayoutSize ContainerSize() const;
 
   SizeAvailability DataChanged(bool all_data_received) override;
 
@@ -227,7 +228,7 @@
   // belong to multiple containers so the final image size can't be known in
   // SVGImage. SVGImageForContainer carries the final image size, also called
   // the "concrete object size". For more, see: SVGImageForContainer.h
-  IntSize intrinsic_size_;
+  LayoutSize intrinsic_size_;
   bool has_pending_timeline_rewind_;
 
   enum LoadState {
diff --git a/third_party/blink/renderer/core/svg/properties/svg_animated_property.h b/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
index 3dd5b4a3..f5fc614 100644
--- a/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
+++ b/third_party/blink/renderer/core/svg/properties/svg_animated_property.h
@@ -101,7 +101,7 @@
  private:
   static_assert(kNumberOfAnimatedPropertyTypes <= (1u << 5),
                 "enough bits for AnimatedPropertyType (type_)");
-  static constexpr int kCssPropertyBits = 9;
+  static constexpr int kCssPropertyBits = 10;
   static_assert((1u << kCssPropertyBits) - 1 >= kIntLastCSSProperty,
                 "enough bits for CSS property ids");
 
diff --git a/third_party/blink/renderer/core/svg/svg_svg_element.cc b/third_party/blink/renderer/core/svg/svg_svg_element.cc
index 84514df..af8fa1e 100644
--- a/third_party/blink/renderer/core/svg/svg_svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_svg_element.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
 #include "third_party/blink/renderer/core/dom/events/event_listener.h"
 #include "third_party/blink/renderer/core/dom/static_node_list.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -511,7 +512,7 @@
     ContainerNode& root_parent) {
   if (root_parent.isConnected()) {
     UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInDocument);
-    if (root_parent.GetDocument().IsXMLDocument())
+    if (IsA<XMLDocument>(root_parent.GetDocument()))
       UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInXMLDocument);
 
     GetDocument().AccessSVGExtensions().AddTimeContainer(this);
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
index aa90abb..277bb59b4b 100644
--- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
+++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
@@ -14,8 +14,6 @@
 SVGTreeScopeResources::SVGTreeScopeResources(TreeScope* tree_scope)
     : tree_scope_(tree_scope) {}
 
-SVGTreeScopeResources::~SVGTreeScopeResources() = default;
-
 LocalSVGResource* SVGTreeScopeResources::ResourceForId(const AtomicString& id) {
   if (id.IsEmpty())
     return nullptr;
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
index 6cde646..f0273986 100644
--- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
+++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.h
@@ -22,7 +22,6 @@
     : public GarbageCollected<SVGTreeScopeResources> {
  public:
   explicit SVGTreeScopeResources(TreeScope*);
-  ~SVGTreeScopeResources();
 
   LocalSVGResource* ResourceForId(const AtomicString& id);
   LocalSVGResource* ExistingResourceForId(const AtomicString& id) const;
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.cc b/third_party/blink/renderer/core/svg/svg_use_element.cc
index a42bc30..dbb0018 100644
--- a/third_party/blink/renderer/core/svg/svg_use_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_use_element.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/id_target_observer.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h"
 #include "third_party/blink/renderer/core/svg/svg_g_element.h"
 #include "third_party/blink/renderer/core/svg/svg_length_context.h"
@@ -107,7 +108,7 @@
 
 #if DCHECK_IS_ON()
 static inline bool IsWellFormedDocument(const Document& document) {
-  if (document.IsXMLDocument())
+  if (IsA<XMLDocument>(document))
     return static_cast<XMLDocumentParser*>(document.Parser())->WellFormed();
   return true;
 }
@@ -206,7 +207,8 @@
       network::mojom::RequestMode::kSameOrigin);
   ResourceFetcher* fetcher = GetDocument().Fetcher();
   if (base::FeatureList::IsEnabled(
-          features::kHtmlImportsRequestInitiatorLock)) {
+          features::kHtmlImportsRequestInitiatorLock) &&
+      GetDocument().ImportsController()) {
     // For @imports from HTML imported Documents, we use the
     // context document for getting origin and ResourceFetcher to use the
     // main Document's origin, while using the element document for
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.cc b/third_party/blink/renderer/core/testing/dummy_modulator.cc
index c9db16d..00a03ce 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.cc
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -85,6 +85,7 @@
 void DummyModulator::FetchTree(const KURL&,
                                ResourceFetcher*,
                                mojom::RequestContextType,
+                               network::mojom::RequestDestination,
                                const ScriptFetchOptions&,
                                ModuleScriptCustomFetchType,
                                ModuleTreeClient*) {
@@ -99,10 +100,12 @@
   NOTREACHED();
 }
 
-void DummyModulator::FetchDescendantsForInlineScript(ModuleScript*,
-                                                     ResourceFetcher*,
-                                                     mojom::RequestContextType,
-                                                     ModuleTreeClient*) {
+void DummyModulator::FetchDescendantsForInlineScript(
+    ModuleScript*,
+    ResourceFetcher*,
+    mojom::RequestContextType,
+    network::mojom::RequestDestination,
+    ModuleTreeClient*) {
   NOTREACHED();
 }
 
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.h b/third_party/blink/renderer/core/testing/dummy_modulator.h
index 8b862e3..f12fa4f 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.h
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -42,7 +42,8 @@
 
   void FetchTree(const KURL&,
                  ResourceFetcher*,
-                 mojom::RequestContextType destination,
+                 mojom::RequestContextType context_type,
+                 network::mojom::RequestDestination destination,
                  const ScriptFetchOptions&,
                  ModuleScriptCustomFetchType,
                  ModuleTreeClient*) override;
@@ -51,10 +52,12 @@
                    ModuleGraphLevel,
                    ModuleScriptCustomFetchType,
                    SingleModuleClient*) override;
-  void FetchDescendantsForInlineScript(ModuleScript*,
-                                       ResourceFetcher*,
-                                       mojom::RequestContextType destination,
-                                       ModuleTreeClient*) override;
+  void FetchDescendantsForInlineScript(
+      ModuleScript*,
+      ResourceFetcher*,
+      mojom::RequestContextType context_type,
+      network::mojom::RequestDestination destination,
+      ModuleTreeClient*) override;
   ModuleScript* GetFetchedModuleScript(const KURL&) override;
   KURL ResolveModuleSpecifier(const String&, const KURL&, String*) override;
   bool HasValidContext() override;
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 7570b3a3..75bc1372 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2225,7 +2225,7 @@
     }
   }
 
-  return DOMRectList::Create(layer_non_fast_scrollable_rects);
+  return MakeGarbageCollected<DOMRectList>(layer_non_fast_scrollable_rects);
 }
 
 void Internals::evictAllResources() const {
@@ -2583,7 +2583,7 @@
   if (!document->View()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
                                       "The document provided is invalid.");
-    return DOMRectList::Create();
+    return MakeGarbageCollected<DOMRectList>();
   }
 
   document->UpdateStyleAndLayout();
@@ -2595,7 +2595,7 @@
     if (region.draggable == draggable)
       quads.push_back(FloatQuad(FloatRect(region.bounds)));
   }
-  return DOMRectList::Create(quads);
+  return MakeGarbageCollected<DOMRectList>(quads);
 }
 
 static const char* CursorTypeToString(ui::CursorType cursor_type) {
diff --git a/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h b/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
index 619ecaea..6a3ce6e 100644
--- a/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
+++ b/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
@@ -46,11 +46,6 @@
     return IsFull() ? full_->BaseAddressMaybeShared() : small_data_;
   }
 
-  unsigned ByteOffset() const {
-    DCHECK(!IsEmpty());
-    return IsFull() ? full_->deprecatedByteOffsetAsUnsigned() : 0;
-  }
-
   size_t ByteLengthAsSizeT() const {
     DCHECK(!IsEmpty());
     return IsFull() ? full_->byteLengthAsSizeT() : small_length_;
diff --git a/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h b/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
index cd48086..62438ed 100644
--- a/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
+++ b/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
@@ -25,9 +25,9 @@
     return static_cast<ValueType*>(BaseAddressMaybeOnStack());
   }
 
-  unsigned length() const {
-    DCHECK_EQ(DeprecatedByteLengthAsUnsigned() % sizeof(ValueType), 0u);
-    return DeprecatedByteLengthAsUnsigned() / sizeof(ValueType);
+  size_t lengthAsSizeT() const {
+    DCHECK_EQ(ByteLengthAsSizeT() % sizeof(ValueType), 0u);
+    return ByteLengthAsSizeT() / sizeof(ValueType);
   }
 
  private:
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc
index 35af0a0dc0..07c0aec 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -267,6 +267,7 @@
     classic_script_loader_->LoadTopLevelScriptAsynchronously(
         *GetExecutionContext(), GetExecutionContext()->Fetcher(),
         script_request_url_, mojom::RequestContextType::WORKER,
+        network::mojom::RequestDestination::kWorker,
         network::mojom::RequestMode::kSameOrigin,
         network::mojom::CredentialsMode::kSameOrigin,
         WTF::Bind(&DedicatedWorker::OnResponse, WrapPersistent(this)),
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index 7abd6add..c57e5cc 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -175,7 +175,9 @@
 
   // Step 12. "Fetch a classic worker script given url, outside settings,
   // destination, and inside settings."
-  auto destination = mojom::RequestContextType::WORKER;
+  mojom::RequestContextType context_type = mojom::RequestContextType::WORKER;
+  network::mojom::RequestDestination destination =
+      network::mojom::RequestDestination::kWorker;
 
   // Step 12.1. "Set request's reserved client to inside settings."
   // The browesr process takes care of this.
@@ -188,7 +190,8 @@
       *this,
       CreateOutsideSettingsFetcher(outside_settings_object,
                                    outside_resource_timing_notifier),
-      script_url, destination, network::mojom::RequestMode::kSameOrigin,
+      script_url, context_type, destination,
+      network::mojom::RequestMode::kSameOrigin,
       network::mojom::CredentialsMode::kSameOrigin,
       WTF::Bind(&DedicatedWorkerGlobalScope::DidReceiveResponseForClassicScript,
                 WrapWeakPersistent(this),
@@ -206,13 +209,15 @@
     network::mojom::CredentialsMode credentials_mode) {
   // Step 12: "Let destination be "sharedworker" if is shared is true, and
   // "worker" otherwise."
-  mojom::RequestContextType destination = mojom::RequestContextType::WORKER;
+  mojom::RequestContextType context_type = mojom::RequestContextType::WORKER;
+  network::mojom::RequestDestination destination =
+      network::mojom::RequestDestination::kWorker;
 
   // Step 13: "... Fetch a module worker script graph given url, outside
   // settings, destination, the value of the credentials member of options, and
   // inside settings."
   FetchModuleScript(module_url_record, outside_settings_object,
-                    outside_resource_timing_notifier, destination,
+                    outside_resource_timing_notifier, context_type, destination,
                     credentials_mode,
                     ModuleScriptCustomFetchType::kWorkerConstructor,
                     MakeGarbageCollected<WorkerModuleTreeClient>(
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
index b5f7fbbc..e75c4a6 100644
--- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -121,7 +121,9 @@
 
   // Step 12. "Fetch a classic worker script given url, outside settings,
   // destination, and inside settings."
-  auto destination = mojom::RequestContextType::SHARED_WORKER;
+  auto context_type = mojom::RequestContextType::SHARED_WORKER;
+  network::mojom::RequestDestination destination =
+      network::mojom::RequestDestination::kSharedWorker;
 
   // Step 12.1. "Set request's reserved client to inside settings."
   // The browesr process takes care of this.
@@ -134,7 +136,8 @@
       *this,
       CreateOutsideSettingsFetcher(outside_settings_object,
                                    outside_resource_timing_notifier),
-      script_url, destination, network::mojom::RequestMode::kSameOrigin,
+      script_url, context_type, destination,
+      network::mojom::RequestMode::kSameOrigin,
       network::mojom::CredentialsMode::kSameOrigin,
       WTF::Bind(&SharedWorkerGlobalScope::DidReceiveResponseForClassicScript,
                 WrapWeakPersistent(this),
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 1f8273a7..d490f57 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
@@ -103,7 +103,8 @@
     ExecutionContext& execution_context,
     ResourceFetcher* fetch_client_settings_object_fetcher,
     const KURL& url,
-    mojom::RequestContextType request_context) {
+    mojom::RequestContextType request_context,
+    network::mojom::RequestDestination destination) {
   DCHECK(fetch_client_settings_object_fetcher);
   url_ = url;
   fetch_client_settings_object_fetcher_ = fetch_client_settings_object_fetcher;
@@ -115,6 +116,7 @@
           .GetFetchClientSettingsObject()
           .GetAddressSpace());
   request.SetRequestContext(request_context);
+  request.SetRequestDestination(destination);
 
   SECURITY_DCHECK(execution_context.IsWorkerGlobalScope());
 
@@ -134,6 +136,7 @@
     ResourceFetcher* fetch_client_settings_object_fetcher,
     const KURL& url,
     mojom::RequestContextType request_context,
+    network::mojom::RequestDestination destination,
     network::mojom::RequestMode request_mode,
     network::mojom::CredentialsMode credentials_mode,
     base::OnceClosure response_callback,
@@ -153,6 +156,7 @@
           .GetFetchClientSettingsObject()
           .GetAddressSpace());
   request.SetRequestContext(request_context);
+  request.SetRequestDestination(destination);
   request.SetMode(request_mode);
   request.SetCredentialsMode(credentials_mode);
 
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 7574f30..2b58df20 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
@@ -64,7 +64,8 @@
   void LoadSynchronously(ExecutionContext&,
                          ResourceFetcher* fetch_client_settings_object_fetcher,
                          const KURL&,
-                         mojom::RequestContextType);
+                         mojom::RequestContextType,
+                         network::mojom::RequestDestination);
 
   // Note that callbacks could be invoked before
   // LoadTopLevelScriptAsynchronously() returns.
@@ -76,6 +77,7 @@
       ResourceFetcher* fetch_client_settings_object_fetcher,
       const KURL&,
       mojom::RequestContextType,
+      network::mojom::RequestDestination,
       network::mojom::RequestMode,
       network::mojom::CredentialsMode,
       base::OnceClosure response_callback,
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
index 8e08129..6cda9a0b 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -288,9 +288,10 @@
   WorkerClassicScriptLoader* classic_script_loader =
       MakeGarbageCollected<WorkerClassicScriptLoader>();
   EnsureFetcher();
-  classic_script_loader->LoadSynchronously(*execution_context, Fetcher(),
-                                           script_url,
-                                           mojom::RequestContextType::SCRIPT);
+  classic_script_loader->LoadSynchronously(
+      *execution_context, Fetcher(), script_url,
+      mojom::RequestContextType::SCRIPT,
+      network::mojom::RequestDestination::kScript);
   if (classic_script_loader->Failed())
     return false;
   *out_response_url = classic_script_loader->ResponseURL();
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index 068689a..3d70491 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -24,6 +24,7 @@
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
 #include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
 #include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h"
@@ -272,7 +273,7 @@
       web_worker_fetch_context_->TakeSubresourceFilter();
   if (web_filter) {
     subresource_filter_ =
-        SubresourceFilter::Create(*this, std::move(web_filter));
+        MakeGarbageCollected<SubresourceFilter>(this, std::move(web_filter));
   }
 }
 
@@ -447,7 +448,8 @@
     const KURL& module_url_record,
     const FetchClientSettingsObjectSnapshot& fetch_client_settings_object,
     WorkerResourceTimingNotifier& resource_timing_notifier,
-    mojom::RequestContextType destination,
+    mojom::RequestContextType context_type,
+    network::mojom::RequestDestination destination,
     network::mojom::CredentialsMode credentials_mode,
     ModuleScriptCustomFetchType custom_fetch_type,
     ModuleTreeClient* client) {
@@ -476,7 +478,7 @@
       module_url_record,
       CreateOutsideSettingsFetcher(fetch_client_settings_object,
                                    resource_timing_notifier),
-      destination, options, custom_fetch_type, client);
+      context_type, destination, options, custom_fetch_type, client);
 }
 
 void WorkerOrWorkletGlobalScope::SetDefersLoadingForResourceFetchers(
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index b008b65..45b0c5c 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -160,7 +160,8 @@
   void FetchModuleScript(const KURL& module_url_record,
                          const FetchClientSettingsObjectSnapshot&,
                          WorkerResourceTimingNotifier&,
-                         mojom::RequestContextType destination,
+                         mojom::RequestContextType context_type,
+                         network::mojom::RequestDestination destination,
                          network::mojom::CredentialsMode,
                          ModuleScriptCustomFetchType,
                          ModuleTreeClient*);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
index 8076e3c..19fe55e 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -240,6 +240,7 @@
   auto destination = mojom::RequestContextType::SCRIPT;
   FetchModuleScript(module_url_record, outside_settings_object,
                     outside_resource_timing_notifier, destination,
+                    network::mojom::RequestDestination::kScript,
                     credentials_mode,
                     ModuleScriptCustomFetchType::kWorkletAddModule, client);
 }
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
index 2398ecd..9c5e5223 100644
--- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
+++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -47,6 +47,7 @@
 #include "third_party/blink/renderer/core/dom/document_type.h"
 #include "third_party/blink/renderer/core/dom/processing_instruction.h"
 #include "third_party/blink/renderer/core/dom/transform_source.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/html/html_html_element.h"
@@ -743,7 +744,7 @@
       script_start_position_(TextPosition::BelowRangePosition()),
       parsing_fragment_(false) {
   // This is XML being used as a document resource.
-  if (frame_view && document.IsXMLDocument())
+  if (frame_view && IsA<XMLDocument>(document))
     UseCounter::Count(document, WebFeature::kXMLDocument);
 }
 
diff --git a/third_party/blink/renderer/core/xml/xpath_grammar.y b/third_party/blink/renderer/core/xml/xpath_grammar.y
index 187d54c..a88d822f1 100644
--- a/third_party/blink/renderer/core/xml/xpath_grammar.y
+++ b/third_party/blink/renderer/core/xml/xpath_grammar.y
@@ -66,7 +66,8 @@
 using blink::xpath::Step;
 %}
 
-%define api.parser.class { YyParser }
+%define api.namespace {xpathyy}
+%define api.parser.class {YyParser}
 %parse-param { blink::xpath::Parser* parser_ }
 
 %define api.value.type variant
@@ -111,7 +112,7 @@
 
 %code {
 
-static int xpathyylex(xpathyy::YyParser::semantic_type* yylval) {
+static int yylex(xpathyy::YyParser::semantic_type* yylval) {
   return blink::xpath::Parser::Current()->Lex(yylval);
 }
 
diff --git a/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc b/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc
index c3b0deba..1934f5aa 100644
--- a/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc
+++ b/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc
@@ -35,8 +35,6 @@
 // are private implementation details.  Do not rely on them.
 
 
-// Take the name prefix into account.
-#define yylex   xpathyylex
 
 // First part of user prologue.
 #line 52 "third_party/blink/renderer/core/xml/xpath_grammar.y"
@@ -56,17 +54,17 @@
 
 using blink::xpath::Step;
 
-#line 59 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 57 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
 
 
 #include "xpath_grammar_generated.h"
 
 
 // Unqualified %code blocks.
-#line 112 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 113 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 
 
-static int xpathyylex(xpathyy::YyParser::semantic_type* yylval) {
+static int yylex(xpathyy::YyParser::semantic_type* yylval) {
   return blink::xpath::Parser::Current()->Lex(yylval);
 }
 
@@ -75,7 +73,7 @@
 }
 
 
-#line 78 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 76 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
 
 
 #ifndef YY_
@@ -146,12 +144,13 @@
 #define YYERROR         goto yyerrorlab
 #define YYRECOVERING()  (!!yyerrstatus_)
 
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 namespace xpathyy {
-#line 150 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 149 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
 
 
   /// Build a parser object.
-   YyParser :: YyParser  (blink::xpath::Parser* parser__yyarg)
+  YyParser::YyParser (blink::xpath::Parser* parser__yyarg)
     :
 #if YYDEBUG
       yydebug_ (false),
@@ -160,10 +159,10 @@
       parser_ (parser__yyarg)
   {}
 
-   YyParser ::~ YyParser  ()
+  YyParser::~YyParser ()
   {}
 
-   YyParser ::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+  YyParser::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
   {}
 
   /*---------------.
@@ -173,7 +172,7 @@
   // basic_symbol.
 #if 201103L <= YY_CPLUSPLUS
   template <typename Base>
-   YyParser ::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
+  YyParser::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
     : Base (std::move (that))
     , value ()
   {
@@ -254,7 +253,7 @@
 #endif
 
   template <typename Base>
-   YyParser ::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
+  YyParser::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
     : Base (that)
     , value ()
   {
@@ -337,14 +336,14 @@
 
   template <typename Base>
   bool
-   YyParser ::basic_symbol<Base>::empty () const YY_NOEXCEPT
+  YyParser::basic_symbol<Base>::empty () const YY_NOEXCEPT
   {
     return Base::type_get () == empty_symbol;
   }
 
   template <typename Base>
   void
-   YyParser ::basic_symbol<Base>::move (basic_symbol& s)
+  YyParser::basic_symbol<Base>::move (basic_symbol& s)
   {
     super_type::move (s);
     switch (this->type_get ())
@@ -423,74 +422,74 @@
   }
 
   // by_type.
-   YyParser ::by_type::by_type ()
+  YyParser::by_type::by_type ()
     : type (empty_symbol)
   {}
 
 #if 201103L <= YY_CPLUSPLUS
-   YyParser ::by_type::by_type (by_type&& that)
+  YyParser::by_type::by_type (by_type&& that)
     : type (that.type)
   {
     that.clear ();
   }
 #endif
 
-   YyParser ::by_type::by_type (const by_type& that)
+  YyParser::by_type::by_type (const by_type& that)
     : type (that.type)
   {}
 
-   YyParser ::by_type::by_type (token_type t)
+  YyParser::by_type::by_type (token_type t)
     : type (yytranslate_ (t))
   {}
 
   void
-   YyParser ::by_type::clear ()
+  YyParser::by_type::clear ()
   {
     type = empty_symbol;
   }
 
   void
-   YyParser ::by_type::move (by_type& that)
+  YyParser::by_type::move (by_type& that)
   {
     type = that.type;
     that.clear ();
   }
 
   int
-   YyParser ::by_type::type_get () const YY_NOEXCEPT
+  YyParser::by_type::type_get () const YY_NOEXCEPT
   {
     return type;
   }
 
 
   // by_state.
-   YyParser ::by_state::by_state () YY_NOEXCEPT
+  YyParser::by_state::by_state () YY_NOEXCEPT
     : state (empty_state)
   {}
 
-   YyParser ::by_state::by_state (const by_state& that) YY_NOEXCEPT
+  YyParser::by_state::by_state (const by_state& that) YY_NOEXCEPT
     : state (that.state)
   {}
 
   void
-   YyParser ::by_state::clear () YY_NOEXCEPT
+  YyParser::by_state::clear () YY_NOEXCEPT
   {
     state = empty_state;
   }
 
   void
-   YyParser ::by_state::move (by_state& that)
+  YyParser::by_state::move (by_state& that)
   {
     state = that.state;
     that.clear ();
   }
 
-   YyParser ::by_state::by_state (state_type s) YY_NOEXCEPT
+  YyParser::by_state::by_state (state_type s) YY_NOEXCEPT
     : state (s)
   {}
 
-   YyParser ::symbol_number_type
-   YyParser ::by_state::type_get () const YY_NOEXCEPT
+  YyParser::symbol_number_type
+  YyParser::by_state::type_get () const YY_NOEXCEPT
   {
     if (state == empty_state)
       return empty_symbol;
@@ -498,10 +497,10 @@
       return yystos_[state];
   }
 
-   YyParser ::stack_symbol_type::stack_symbol_type ()
+  YyParser::stack_symbol_type::stack_symbol_type ()
   {}
 
-   YyParser ::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
+  YyParser::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
     : super_type (YY_MOVE (that.state))
   {
     switch (that.type_get ())
@@ -583,7 +582,7 @@
 #endif
   }
 
-   YyParser ::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
+  YyParser::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
     : super_type (s)
   {
     switch (that.type_get ())
@@ -664,8 +663,8 @@
   }
 
 #if YY_CPLUSPLUS < 201103L
-   YyParser ::stack_symbol_type&
-   YyParser ::stack_symbol_type::operator= (stack_symbol_type& that)
+  YyParser::stack_symbol_type&
+  YyParser::stack_symbol_type::operator= (stack_symbol_type& that)
   {
     state = that.state;
     switch (that.type_get ())
@@ -749,7 +748,7 @@
 
   template <typename Base>
   void
-   YyParser ::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+  YyParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
   {
     if (yymsg)
       YY_SYMBOL_PRINT (yymsg, yysym);
@@ -758,7 +757,7 @@
 #if YYDEBUG
   template <typename Base>
   void
-   YyParser ::yy_print_ (std::ostream& yyo,
+  YyParser::yy_print_ (std::ostream& yyo,
                                      const basic_symbol<Base>& yysym) const
   {
     std::ostream& yyoutput = yyo;
@@ -778,7 +777,7 @@
 #endif
 
   void
-   YyParser ::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
+  YyParser::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
   {
     if (m)
       YY_SYMBOL_PRINT (m, sym);
@@ -786,7 +785,7 @@
   }
 
   void
-   YyParser ::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
+  YyParser::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
   {
 #if 201103L <= YY_CPLUSPLUS
     yypush_ (m, stack_symbol_type (s, std::move (sym)));
@@ -797,40 +796,40 @@
   }
 
   void
-   YyParser ::yypop_ (int n)
+  YyParser::yypop_ (int n)
   {
     yystack_.pop (n);
   }
 
 #if YYDEBUG
   std::ostream&
-   YyParser ::debug_stream () const
+  YyParser::debug_stream () const
   {
     return *yycdebug_;
   }
 
   void
-   YyParser ::set_debug_stream (std::ostream& o)
+  YyParser::set_debug_stream (std::ostream& o)
   {
     yycdebug_ = &o;
   }
 
 
-   YyParser ::debug_level_type
-   YyParser ::debug_level () const
+  YyParser::debug_level_type
+  YyParser::debug_level () const
   {
     return yydebug_;
   }
 
   void
-   YyParser ::set_debug_level (debug_level_type l)
+  YyParser::set_debug_level (debug_level_type l)
   {
     yydebug_ = l;
   }
 #endif // YYDEBUG
 
-   YyParser ::state_type
-   YyParser ::yy_lr_goto_state_ (state_type yystate, int yysym)
+  YyParser::state_type
+  YyParser::yy_lr_goto_state_ (state_type yystate, int yysym)
   {
     int yyr = yypgoto_[yysym - yyntokens_] + yystate;
     if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
@@ -840,25 +839,25 @@
   }
 
   bool
-   YyParser ::yy_pact_value_is_default_ (int yyvalue)
+  YyParser::yy_pact_value_is_default_ (int yyvalue)
   {
     return yyvalue == yypact_ninf_;
   }
 
   bool
-   YyParser ::yy_table_value_is_error_ (int yyvalue)
+  YyParser::yy_table_value_is_error_ (int yyvalue)
   {
     return yyvalue == yytable_ninf_;
   }
 
   int
-   YyParser ::operator() ()
+  YyParser::operator() ()
   {
     return parse ();
   }
 
   int
-   YyParser ::parse ()
+  YyParser::parse ()
   {
     // State.
     int yyn;
@@ -1062,98 +1061,98 @@
           switch (yyn)
             {
   case 2:
-#line 128 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 129 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       parser_->top_expr_ = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ();
     }
-#line 1070 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1069 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 3:
-#line 136 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 137 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(false);
     }
-#line 1079 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1078 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 4:
-#line 142 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 143 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
     }
-#line 1088 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1087 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 5:
-#line 150 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 151 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = blink::MakeGarbageCollected<blink::xpath::LocationPath>();
     }
-#line 1096 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1095 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 6:
-#line 155 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 156 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
     }
-#line 1104 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1103 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 7:
-#line 160 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 161 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->InsertFirstStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
     }
-#line 1113 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1112 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 8:
-#line 168 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 169 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = blink::MakeGarbageCollected<blink::xpath::LocationPath>();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
     }
-#line 1122 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1121 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 9:
-#line 174 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 175 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[2].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
     }
-#line 1131 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1130 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 10:
-#line 180 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 181 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[2].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
       yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
     }
-#line 1141 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1140 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 11:
-#line 189 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 190 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
       else
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > ());
     }
-#line 1152 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1151 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 12:
-#line 197 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 198 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       AtomicString local_name;
       AtomicString namespace_uri;
@@ -1167,22 +1166,22 @@
       else
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
     }
-#line 1170 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1169 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 13:
-#line 212 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 213 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
       else
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > ());
     }
-#line 1181 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1180 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 14:
-#line 220 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 221 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       AtomicString local_name;
       AtomicString namespace_uri;
@@ -1196,31 +1195,31 @@
       else
         yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
     }
-#line 1199 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1198 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 15:
-#line 234 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 235 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > (); }
-#line 1205 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1204 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 16:
-#line 238 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 239 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::xpath::Step::Axis > () = yystack_[0].value.as < blink::xpath::Step::Axis > (); }
-#line 1211 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1210 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 17:
-#line 241 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 242 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::xpath::Step::Axis > () = Step::kAttributeAxis;
     }
-#line 1219 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1218 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 18:
-#line 248 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 249 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       if (yystack_[2].value.as < String > () == "node")
         yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kAnyNodeTest);
@@ -1229,345 +1228,345 @@
       else if (yystack_[2].value.as < String > () == "comment")
         yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kCommentNodeTest);
     }
-#line 1232 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1231 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 19:
-#line 258 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 259 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest);
     }
-#line 1240 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1239 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 20:
-#line 263 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 264 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest, yystack_[1].value.as < String > ().StripWhiteSpace());
     }
-#line 1248 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1247 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 21:
-#line 270 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 271 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = 0;
     }
-#line 1256 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1255 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 22:
-#line 275 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 276 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
     }
-#line 1264 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1263 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 23:
-#line 282 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 283 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = blink::MakeGarbageCollected<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>();
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ()->push_back(blink::MakeGarbageCollected<blink::xpath::Predicate>(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ()));
     }
-#line 1273 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1272 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 24:
-#line 288 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 289 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = yystack_[1].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ()->push_back(blink::MakeGarbageCollected<blink::xpath::Predicate>(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ()));
     }
-#line 1282 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1281 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 25:
-#line 296 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 297 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > ();
     }
-#line 1290 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1289 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 26:
-#line 303 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 304 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kDescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
     }
-#line 1298 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1297 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 27:
-#line 310 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 311 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
     }
-#line 1306 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1305 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 28:
-#line 315 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 316 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kParentAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
     }
-#line 1314 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1313 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 29:
-#line 322 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 323 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::VariableReference>(yystack_[0].value.as < String > ());
     }
-#line 1322 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1321 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 30:
-#line 327 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 328 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > ();
     }
-#line 1330 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1329 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 31:
-#line 332 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 333 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::StringExpression>(yystack_[0].value.as < String > ());
     }
-#line 1338 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1337 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 32:
-#line 337 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 338 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Number>(yystack_[0].value.as < String > ().ToDouble());
     }
-#line 1346 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1345 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 33:
-#line 341 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 342 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1352 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1351 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 34:
-#line 346 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 347 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::xpath::CreateFunction(yystack_[2].value.as < String > ());
       if (!yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ())
         YYABORT;
     }
-#line 1362 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1361 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 35:
-#line 353 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 354 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::xpath::CreateFunction(yystack_[3].value.as < String > (), *yystack_[1].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ());
       if (!yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ())
         YYABORT;
     }
-#line 1372 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1371 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 36:
-#line 362 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 363 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > () = blink::MakeGarbageCollected<blink::HeapVector<blink::Member<blink::xpath::Expression>>>();
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ()->push_back(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1381 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1380 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 37:
-#line 368 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 369 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > () = yystack_[2].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ();
       yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ()->push_back(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1390 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1389 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 38:
-#line 375 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 376 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1396 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1395 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 39:
-#line 379 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 380 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1402 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1401 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 40:
-#line 382 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 383 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Union>();
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > ());
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1412 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1411 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 41:
-#line 391 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 392 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
     }
-#line 1420 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1419 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 42:
-#line 395 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 396 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1426 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1425 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 43:
-#line 398 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 399 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Path>(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ());
     }
-#line 1435 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1434 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 44:
-#line 404 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 405 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->InsertFirstStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
       yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Path>(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ());
     }
-#line 1445 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1444 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 45:
-#line 412 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 413 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1451 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1450 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 46:
-#line 415 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 416 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Filter>(yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
     }
-#line 1459 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1458 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 47:
-#line 421 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 422 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1465 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1464 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 48:
-#line 424 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 425 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_Or, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1473 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1472 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 49:
-#line 430 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 431 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1479 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1478 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 50:
-#line 433 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 434 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_And, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1487 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1486 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 51:
-#line 439 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 440 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1493 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1492 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 52:
-#line 442 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 443 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::EqTestOp>(yystack_[1].value.as < blink::xpath::EqTestOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1501 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1500 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 53:
-#line 448 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 449 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1507 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1506 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 54:
-#line 451 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 452 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::EqTestOp>(yystack_[1].value.as < blink::xpath::EqTestOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1515 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1514 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 55:
-#line 457 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 458 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1521 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1520 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 56:
-#line 460 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 461 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Add, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1529 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1528 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 57:
-#line 465 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 466 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Sub, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1537 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1536 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 58:
-#line 471 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 472 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1543 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1542 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 59:
-#line 474 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 475 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(yystack_[1].value.as < blink::xpath::NumericOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1551 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1550 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 60:
-#line 480 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 481 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
-#line 1557 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1556 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
   case 61:
-#line 483 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 484 "third_party/blink/renderer/core/xml/xpath_grammar.y"
     {
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Negative>();
       yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
     }
-#line 1566 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1565 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
     break;
 
 
-#line 1570 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+#line 1569 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
 
             default:
               break;
@@ -1731,25 +1730,25 @@
   }
 
   void
-   YyParser ::error (const syntax_error& yyexc)
+  YyParser::error (const syntax_error& yyexc)
   {
     error (yyexc.what ());
   }
 
   // Generate an error message.
   std::string
-   YyParser ::yysyntax_error_ (state_type, const symbol_type&) const
+  YyParser::yysyntax_error_ (state_type, const symbol_type&) const
   {
     return YY_("syntax error");
   }
 
 
-  const signed char  YyParser ::yypact_ninf_ = -44;
+  const signed char YyParser::yypact_ninf_ = -44;
 
-  const signed char  YyParser ::yytable_ninf_ = -1;
+  const signed char YyParser::yytable_ninf_ = -1;
 
   const signed char
-   YyParser ::yypact_[] =
+  YyParser::yypact_[] =
   {
       77,    77,   -44,    -9,    -4,    18,   -44,   -44,   -44,   -44,
      -44,    19,    -2,   -44,    77,   -44,    36,   -44,   -44,    13,
@@ -1764,7 +1763,7 @@
   };
 
   const unsigned char
-   YyParser ::yydefact_[] =
+  YyParser::yydefact_[] =
   {
        0,     0,    16,     0,     0,     0,    31,    29,    32,    28,
       26,    21,     5,    17,     0,    27,     0,    41,     4,     3,
@@ -1779,7 +1778,7 @@
   };
 
   const signed char
-   YyParser ::yypgoto_[] =
+  YyParser::yypgoto_[] =
   {
      -44,     2,   -44,   -44,   -11,   -43,   -44,    35,   -18,    33,
      -36,   -16,   -44,   -44,   -44,   -44,   -32,   -44,     5,   -44,
@@ -1787,7 +1786,7 @@
   };
 
   const signed char
-   YyParser ::yydefgoto_[] =
+  YyParser::yydefgoto_[] =
   {
       -1,    69,    17,    18,    19,    20,    21,    22,    42,    43,
       44,    23,    24,    25,    26,    70,    71,    27,    28,    29,
@@ -1795,7 +1794,7 @@
   };
 
   const unsigned char
-   YyParser ::yytable_[] =
+  YyParser::yytable_[] =
   {
       37,    45,    16,    49,    52,    75,    76,    73,     2,     3,
        4,    66,    53,    57,    38,     9,    46,    11,    73,    39,
@@ -1813,7 +1812,7 @@
   };
 
   const signed char
-   YyParser ::yycheck_[] =
+  YyParser::yycheck_[] =
   {
        1,    12,     0,    19,    22,    48,    49,    43,    10,    11,
       12,    14,    23,    29,    23,    17,    14,    19,    54,    23,
@@ -1831,7 +1830,7 @@
   };
 
   const unsigned char
-   YyParser ::yystos_[] =
+  YyParser::yystos_[] =
   {
        0,     7,    10,    11,    12,    13,    14,    15,    16,    17,
       18,    19,    21,    22,    23,    27,    31,    32,    33,    34,
@@ -1846,7 +1845,7 @@
   };
 
   const unsigned char
-   YyParser ::yyr1_[] =
+  YyParser::yyr1_[] =
   {
        0,    30,    31,    32,    32,    33,    33,    33,    34,    34,
       34,    35,    35,    35,    35,    35,    36,    36,    37,    37,
@@ -1858,7 +1857,7 @@
   };
 
   const unsigned char
-   YyParser ::yyr2_[] =
+  YyParser::yyr2_[] =
   {
        0,     2,     1,     1,     1,     1,     2,     2,     1,     3,
        3,     2,     2,     3,     3,     1,     1,     1,     3,     3,
@@ -1874,7 +1873,7 @@
   // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
   // First, the terminals, then, starting at \a yyntokens_, nonterminals.
   const char*
-  const  YyParser ::yytname_[] =
+  const YyParser::yytname_[] =
   {
   "$end", "error", "$undefined", "kMulOp", "kEqOp", "kRelOp", "kPlus",
   "kMinus", "kOr", "kAnd", "kAxisName", "kNodeType", "kPI",
@@ -1891,20 +1890,20 @@
 
 
   const unsigned short
-   YyParser ::yyrline_[] =
+  YyParser::yyrline_[] =
   {
-       0,   127,   127,   135,   141,   149,   154,   159,   167,   173,
-     179,   188,   196,   211,   219,   234,   238,   240,   247,   257,
-     262,   270,   274,   281,   287,   295,   302,   309,   314,   321,
-     326,   331,   336,   341,   345,   352,   361,   367,   375,   379,
-     381,   390,   395,   397,   403,   412,   414,   421,   423,   430,
-     432,   439,   441,   448,   450,   457,   459,   464,   471,   473,
-     480,   482
+       0,   128,   128,   136,   142,   150,   155,   160,   168,   174,
+     180,   189,   197,   212,   220,   235,   239,   241,   248,   258,
+     263,   271,   275,   282,   288,   296,   303,   310,   315,   322,
+     327,   332,   337,   342,   346,   353,   362,   368,   376,   380,
+     382,   391,   396,   398,   404,   413,   415,   422,   424,   431,
+     433,   440,   442,   449,   451,   458,   460,   465,   472,   474,
+     481,   483
   };
 
   // Print the state stack on the debug stream.
   void
-   YyParser ::yystack_print_ ()
+  YyParser::yystack_print_ ()
   {
     *yycdebug_ << "Stack now";
     for (stack_type::const_iterator
@@ -1917,7 +1916,7 @@
 
   // Report on the debug stream that the rule \a yyrule is going to be reduced.
   void
-   YyParser ::yy_reduce_print_ (int yyrule)
+  YyParser::yy_reduce_print_ (int yyrule)
   {
     unsigned yylno = yyrline_[yyrule];
     int yynrhs = yyr2_[yyrule];
@@ -1931,8 +1930,8 @@
   }
 #endif // YYDEBUG
 
-   YyParser ::token_number_type
-   YyParser ::yytranslate_ (int t)
+  YyParser::token_number_type
+  YyParser::yytranslate_ (int t)
   {
     // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
     // TOKEN-NUM as returned by yylex.
@@ -1980,8 +1979,9 @@
       return undef_token_;
   }
 
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 } // xpathyy
 #line 1984 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
 
-#line 489 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+#line 490 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 
diff --git a/third_party/blink/renderer/core/xml/xpath_grammar_generated.h b/third_party/blink/renderer/core/xml/xpath_grammar_generated.h
index f1fbe2d..b8469fb1 100644
--- a/third_party/blink/renderer/core/xml/xpath_grammar_generated.h
+++ b/third_party/blink/renderer/core/xml/xpath_grammar_generated.h
@@ -44,8 +44,8 @@
 // Undocumented macros, especially those whose name start with YY_,
 // are private implementation details.  Do not rely on them.
 
-#ifndef YY_XPATHYY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
-# define YY_XPATHYY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+#ifndef YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+# define YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
 // //                    "%code requires" blocks.
 #line 46 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 
@@ -167,14 +167,15 @@
 # define YYDEBUG 0
 #endif
 
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 namespace xpathyy {
-#line 169 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
+#line 170 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
 
 
 
 
   /// A Bison parser.
-  class  YyParser 
+  class YyParser
   {
   public:
 #ifndef YYSTYPE
@@ -852,8 +853,8 @@
     };
 
     /// Build a parser object.
-     YyParser  (blink::xpath::Parser* parser__yyarg);
-    virtual ~ YyParser  ();
+    YyParser (blink::xpath::Parser* parser__yyarg);
+    virtual ~YyParser ();
 
     /// Parse.  An alias for parse ().
     /// \returns  0 iff parsing succeeded.
@@ -1159,8 +1160,8 @@
 
   private:
     /// This class is not copyable.
-     YyParser  (const  YyParser &);
-     YyParser & operator= (const  YyParser &);
+    YyParser (const YyParser&);
+    YyParser& operator= (const YyParser&);
 
     /// State numbers.
     typedef int state_type;
@@ -1472,12 +1473,13 @@
   };
 
 
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
 } // xpathyy
-#line 1474 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
+#line 1476 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
 
 
 
 
 
-#endif // !YY_XPATHYY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+#endif // !YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_H_
diff --git a/third_party/blink/renderer/core/xml/xsl_style_sheet.h b/third_party/blink/renderer/core/xml/xsl_style_sheet.h
index d59872e..5b709cd 100644
--- a/third_party/blink/renderer/core/xml/xsl_style_sheet.h
+++ b/third_party/blink/renderer/core/xml/xsl_style_sheet.h
@@ -34,36 +34,13 @@
 
 class XSLStyleSheet final : public StyleSheet {
  public:
-  static XSLStyleSheet* Create(ProcessingInstruction* parent_node,
-                               const String& original_url,
-                               const KURL& final_url) {
-    DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
-    return MakeGarbageCollected<XSLStyleSheet>(parent_node, original_url,
-                                               final_url, false);
-  }
-  static XSLStyleSheet* CreateEmbedded(ProcessingInstruction* parent_node,
-                                       const KURL& final_url) {
-    DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
-    return MakeGarbageCollected<XSLStyleSheet>(
-        parent_node, final_url.GetString(), final_url, true);
-  }
-
-  // Taking an arbitrary node is unsafe, because owner node pointer can become
-  // stale. XSLTProcessor ensures that the stylesheet doesn't outlive its
-  // parent, in part by not exposing it to JavaScript.
-  static XSLStyleSheet* CreateForXSLTProcessor(Document* document,
-                                               Node* stylesheet_root_node,
-                                               const String& original_url,
-                                               const KURL& final_url) {
-    DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
-    return MakeGarbageCollected<XSLStyleSheet>(document, stylesheet_root_node,
-                                               original_url, final_url, false);
-  }
-
   XSLStyleSheet(Node* parent_node,
                 const String& original_url,
                 const KURL& final_url,
                 bool embedded);
+  // Taking an arbitrary node is unsafe, because owner node pointer can become
+  // stale. XSLTProcessor ensures that the stylesheet doesn't outlive its
+  // parent, in part by not exposing it to JavaScript.
   XSLStyleSheet(Document* owner_document,
                 Node* style_sheet_root_node,
                 const String& original_url,
diff --git a/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc b/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
index 40f5bb28..90df940 100644
--- a/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
+++ b/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc
@@ -52,7 +52,9 @@
       stylesheet_doc_taken_(false),
       compilation_failed_(false),
       parent_style_sheet_(parent_style_sheet),
-      owner_document_(nullptr) {}
+      owner_document_(nullptr) {
+  DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
 
 XSLStyleSheet::XSLStyleSheet(Node* parent_node,
                              const String& original_url,
@@ -68,7 +70,9 @@
       stylesheet_doc_taken_(false),
       compilation_failed_(false),
       parent_style_sheet_(nullptr),
-      owner_document_(nullptr) {}
+      owner_document_(nullptr) {
+  DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
 
 XSLStyleSheet::XSLStyleSheet(Document* owner_document,
                              Node* style_sheet_root_node,
@@ -85,7 +89,9 @@
       stylesheet_doc_taken_(false),
       compilation_failed_(false),
       parent_style_sheet_(nullptr),
-      owner_document_(owner_document) {}
+      owner_document_(owner_document) {
+  DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
 
 XSLStyleSheet::~XSLStyleSheet() {
   if (!stylesheet_doc_taken_)
diff --git a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
index 16bd924..1f9c990 100644
--- a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
+++ b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
@@ -274,14 +274,14 @@
   if (!cached_stylesheet && stylesheet_root_node) {
     // When using importStylesheet, we will use the given document as the
     // imported stylesheet's owner.
-    cached_stylesheet = XSLStyleSheet::CreateForXSLTProcessor(
+    cached_stylesheet = MakeGarbageCollected<XSLStyleSheet>(
         stylesheet_root_node->parentNode()
             ? &stylesheet_root_node->parentNode()->GetDocument()
             : document,
         stylesheet_root_node,
         stylesheet_root_node->GetDocument().Url().GetString(),
-        stylesheet_root_node->GetDocument()
-            .Url());  // FIXME: Should we use baseURL here?
+        stylesheet_root_node->GetDocument().Url(),
+        false);  // FIXME: Should we use baseURL here?
 
     // According to Mozilla documentation, the node must be a Document node,
     // an xsl:stylesheet or xsl:transform element. But we just use text
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 03153a9d..8799f04 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -818,7 +818,7 @@
   if (AreMethodAndURLValidForSend()) {
     if (document->IsHTMLDocument())
       UpdateContentTypeAndCharset("text/html;charset=UTF-8", "UTF-8");
-    else if (document->IsXMLDocument())
+    else if (IsA<XMLDocument>(document))
       UpdateContentTypeAndCharset("application/xml;charset=UTF-8", "UTF-8");
 
     String body = CreateMarkup(document);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index cd094c0f..37a2263 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -145,20 +145,6 @@
   return ax_descendant;
 }
 
-bool HasAriaAttribute(Element* element) {
-  if (!element)
-    return false;
-
-  AttributeCollection attributes = element->AttributesWithoutUpdate();
-  for (const Attribute& attr : attributes) {
-    // Attributes cache their uppercase names.
-    if (attr.GetName().LocalNameUpper().StartsWith("ARIA-"))
-      return true;
-  }
-
-  return false;
-}
-
 AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
     IgnoredReasons* ignored_reasons) const {
   // If this element is within a parent that cannot have children, it should not
@@ -303,7 +289,7 @@
   // These checks are simplified in the interest of execution speed;
   // for example, any element having an alt attribute will make it
   // not ignored, rather than just images.
-  if (HasAriaAttribute(GetElement()) || !GetAttribute(kTitleAttr).IsEmpty() ||
+  if (HasAriaAttribute() || !GetAttribute(kTitleAttr).IsEmpty() ||
       has_non_empty_alt_attribute)
     return kIncludeObject;
 
@@ -2138,6 +2124,25 @@
   return aria_role_;
 }
 
+bool AXNodeObject::HasAriaAttribute() const {
+  Element* element = GetElement();
+  if (!element)
+    return false;
+
+  // Explicit ARIA role should be considered an aria attribute.
+  if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+    return true;
+
+  AttributeCollection attributes = element->AttributesWithoutUpdate();
+  for (const Attribute& attr : attributes) {
+    // Attributes cache their uppercase names.
+    if (attr.GetName().LocalNameUpper().StartsWith("ARIA-"))
+      return true;
+  }
+
+  return false;
+}
+
 // Returns the nearest block-level LayoutBlockFlow ancestor
 static LayoutBlockFlow* NonInlineBlockFlow(LayoutObject* object) {
   LayoutObject* current = object;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
index 132d4ff..d98977e 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -161,6 +161,7 @@
 
   // ARIA attributes.
   ax::mojom::Role AriaRoleAttribute() const final;
+  bool HasAriaAttribute() const override;
 
   // AX name calculation.
   String GetName(ax::mojom::NameFrom&,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index da4f4d1..81d0178 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -716,6 +716,7 @@
   virtual ax::mojom::Role DetermineAccessibilityRole();
   ax::mojom::Role DetermineAriaRoleAttribute() const;
   virtual ax::mojom::Role AriaRoleAttribute() const;
+  virtual bool HasAriaAttribute() const { return false; }
   virtual AXObject* ActiveDescendant() { return nullptr; }
   virtual String AutoComplete() const { return String(); }
   virtual void AriaOwnsElements(AXObjectVector& owns) const {}
diff --git a/third_party/blink/renderer/modules/animationworklet/animator_definition.cc b/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
index a19cd4d..24e01f70 100644
--- a/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
@@ -19,8 +19,6 @@
   DCHECK(animate_);
 }
 
-AnimatorDefinition::~AnimatorDefinition() = default;
-
 void AnimatorDefinition::Trace(Visitor* visitor) {
   visitor->Trace(constructor_);
   visitor->Trace(animate_);
diff --git a/third_party/blink/renderer/modules/animationworklet/animator_definition.h b/third_party/blink/renderer/modules/animationworklet/animator_definition.h
index 09bf9c6..ec81cc7 100644
--- a/third_party/blink/renderer/modules/animationworklet/animator_definition.h
+++ b/third_party/blink/renderer/modules/animationworklet/animator_definition.h
@@ -27,7 +27,6 @@
   explicit AnimatorDefinition(V8AnimatorConstructor* constructor,
                               V8AnimateCallback* animate,
                               V8StateCallback* state);
-  ~AnimatorDefinition();
   virtual void Trace(blink::Visitor* visitor);
   const char* NameInHeapSnapshot() const override {
     return "AnimatorDefinition";
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
index 7c597442..6c64e6a 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -120,8 +120,8 @@
 void StartEffectOnCompositor(CompositorAnimation* animation,
                              KeyframeEffect* effect) {
   DCHECK(effect);
-  DCHECK(effect->target());
-  Element& target = *effect->target();
+  DCHECK(effect->EffectTarget());
+  Element& target = *effect->EffectTarget();
   effect->Model()->SnapshotAllCompositorKeyframesIfNecessary(
       target, target.ComputedStyleRef(), target.ParentComputedStyle());
 
@@ -308,7 +308,7 @@
   has_started_ = true;
 
   for (auto& effect : effects_) {
-    Element* target = effect->target();
+    Element* target = effect->EffectTarget();
     if (!target)
       continue;
 
@@ -381,7 +381,7 @@
   SetCurrentTime(base::nullopt);
 
   for (auto& effect : effects_) {
-    Element* target = effect->target();
+    Element* target = effect->EffectTarget();
     if (!target)
       continue;
     // TODO(yigu): Currently we have to keep a set of worklet animations in
@@ -547,10 +547,10 @@
     return false;
   }
 
-  if (!GetEffect()->target())
+  if (!GetEffect()->EffectTarget())
     return false;
 
-  Element& target = *GetEffect()->target();
+  Element& target = *GetEffect()->EffectTarget();
 
   // TODO(crbug.com/836393): This should not be possible but it is currently
   // happening and needs to be investigated/fixed.
@@ -613,7 +613,7 @@
           document_->Timeline().CompositorTimeline())
     compositor_timeline->AnimationAttached(*this);
 
-  CompositorAnimations::AttachCompositedLayers(*GetEffect()->target(),
+  CompositorAnimations::AttachCompositedLayers(*GetEffect()->EffectTarget(),
                                                compositor_animation_.get());
 
   // TODO(smcgruer): We need to start all of the effects, not just the first.
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
index ec554b7..77bf3708 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -71,6 +71,8 @@
 
   ResourceRequest resource_request(best_icon_url);
   resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+  resource_request.SetRequestDestination(
+      network::mojom::RequestDestination::kImage);
   resource_request.SetPriority(ResourceLoadPriority::kMedium);
   resource_request.SetKeepalive(true);
   resource_request.SetMode(network::mojom::RequestMode::kNoCors);
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
index 1509e73f..a2c3f34 100644
--- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
+++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -260,9 +260,9 @@
       DCHECK(!request->blob && !request->body);
       auto request_clone_without_body = mojom::blink::FetchAPIRequest::New(
           request->mode, request->is_main_resource_load,
-          request->request_context_type, request->frame_type, request->url,
-          request->method, request->headers, nullptr /* blob */,
-          nullptr /* body */, request->referrer.Clone(),
+          request->request_context_type, request->destination,
+          request->frame_type, request->url, request->method, request->headers,
+          nullptr /* blob */, nullptr /* body */, request->referrer.Clone(),
           request->credentials_mode, request->cache_mode,
           request->redirect_mode, request->integrity, request->priority,
           request->fetch_window_id, request->keepalive, request->is_reload,
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
index 6f07bd9..129412d 100644
--- a/third_party/blink/renderer/modules/compression/deflate_transformer.cc
+++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -73,8 +73,14 @@
   DCHECK(buffer_source.IsArrayBuffer());
   const auto* array_buffer = buffer_source.GetAsArrayBuffer();
   const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
-  wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned();
-  Deflate(start, length, IsFinished(false), controller, exception_state);
+  size_t length = array_buffer->ByteLengthAsSizeT();
+  if (length > std::numeric_limits<wtf_size_t>::max()) {
+    exception_state.ThrowRangeError(
+        "Buffer size exceeds maximum heap object size.");
+    return ScriptPromise();
+  }
+  Deflate(start, static_cast<wtf_size_t>(length), IsFinished(false), controller,
+          exception_state);
 
   return ScriptPromise::CastUndefined(script_state_);
 }
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
index 5c70327..fe66e8d 100644
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -71,8 +71,14 @@
   DCHECK(buffer_source.IsArrayBuffer());
   const auto* array_buffer = buffer_source.GetAsArrayBuffer();
   const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
-  wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned();
-  Inflate(start, length, IsFinished(false), controller, exception_state);
+  size_t length = array_buffer->ByteLengthAsSizeT();
+  if (length > std::numeric_limits<wtf_size_t>::max()) {
+    exception_state.ThrowRangeError(
+        "Buffer size exceeds maximum heap object size.");
+    return ScriptPromise();
+  }
+  Inflate(start, static_cast<wtf_size_t>(length), IsFinished(false), controller,
+          exception_state);
 
   return ScriptPromise::CastUndefined(script_state_);
 }
diff --git a/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc b/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
index cd1ea626..4719b8a 100644
--- a/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
+++ b/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
@@ -29,6 +29,8 @@
                ThreadedIconLoader::IconCallback callback) {
   ResourceRequest resource_request(icon_url);
   resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+  resource_request.SetRequestDestination(
+      network::mojom::RequestDestination::kImage);
   resource_request.SetPriority(ResourceLoadPriority::kMedium);
   resource_request.SetTimeoutInterval(kIconFetchTimeout);
 
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc
index 8e4a75ab..ebc0f1fe 100644
--- a/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -442,6 +442,13 @@
   return private_->IsVisited();
 }
 
+bool WebAXObject::HasAriaAttribute() const {
+  if (IsDetached())
+    return false;
+
+  return private_->HasAriaAttribute();
+}
+
 WebString WebAXObject::AccessKey() const {
   if (IsDetached())
     return WebString();
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/third_party/blink/renderer/modules/filesystem/local_file_system.cc
index 05f3ba3..162cddff 100644
--- a/third_party/blink/renderer/modules/filesystem/local_file_system.cc
+++ b/third_party/blink/renderer/modules/filesystem/local_file_system.cc
@@ -52,8 +52,6 @@
 
 namespace blink {
 
-LocalFileSystem::~LocalFileSystem() = default;
-
 void LocalFileSystem::ResolveURL(ExecutionContext* context,
                                  const KURL& file_system_url,
                                  std::unique_ptr<ResolveURICallbacks> callbacks,
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.h b/third_party/blink/renderer/modules/filesystem/local_file_system.h
index 48d8734..0998188 100644
--- a/third_party/blink/renderer/modules/filesystem/local_file_system.h
+++ b/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -64,7 +64,6 @@
 
   explicit LocalFileSystem(LocalFrame&);
   explicit LocalFileSystem(WorkerGlobalScope&);
-  ~LocalFileSystem();
 
   void ResolveURL(ExecutionContext*,
                   const KURL&,
diff --git a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
index a7ef74a..453279a 100644
--- a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
+++ b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
@@ -17,7 +17,6 @@
 
 DOMWindowLaunchQueue::DOMWindowLaunchQueue()
     : launch_queue_(MakeGarbageCollected<LaunchQueue>()) {}
-DOMWindowLaunchQueue::~DOMWindowLaunchQueue() = default;
 
 Member<LaunchQueue> DOMWindowLaunchQueue::launchQueue(LocalDOMWindow& window) {
   return FromState(&window)->launch_queue_;
diff --git a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
index 4990a78e..2d3b0aa 100644
--- a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
+++ b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
@@ -29,7 +29,6 @@
   static const char kSupplementName[];
 
   explicit DOMWindowLaunchQueue();
-  ~DOMWindowLaunchQueue();
 
   // IDL Interface.
   static Member<LaunchQueue> launchQueue(LocalDOMWindow&);
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index 2988db0..2141c261 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -1616,7 +1616,7 @@
   if (!event->IsGestureEvent())
     return false;
 
-  float tap_x = ToGestureEvent(event)->NativeEvent().PositionInWidget().x;
+  float tap_x = ToGestureEvent(event)->NativeEvent().PositionInWidget().x();
 
   DOMRect* rect = getBoundingClientRect();
   double middle = rect->x() + (rect->width() / 2);
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 1960b69..4954d7d4 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -273,12 +273,12 @@
         HTMLMediaElement::kHaveEnoughData);
   }
 
-  void MouseDownAt(WebFloatPoint pos);
-  void MouseMoveTo(WebFloatPoint pos);
-  void MouseUpAt(WebFloatPoint pos);
+  void MouseDownAt(gfx::PointF pos);
+  void MouseMoveTo(gfx::PointF pos);
+  void MouseUpAt(gfx::PointF pos);
 
-  void GestureTapAt(WebFloatPoint pos);
-  void GestureDoubleTapAt(WebFloatPoint pos);
+  void GestureTapAt(gfx::PointF pos);
+  void GestureDoubleTapAt(gfx::PointF pos);
 
   bool HasAvailabilityCallbacks(RemotePlayback& remote_playback) {
     return !remote_playback.availability_callbacks_.IsEmpty();
@@ -311,7 +311,7 @@
   HistogramTester histogram_tester_;
 };
 
-void MediaControlsImplTest::MouseDownAt(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseDownAt(gfx::PointF pos) {
   WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown,
                                  pos /* client pos */, pos /* screen pos */,
                                  WebPointerProperties::Button::kLeft, 1,
@@ -322,7 +322,7 @@
       mouse_down_event);
 }
 
-void MediaControlsImplTest::MouseMoveTo(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseMoveTo(gfx::PointF pos) {
   WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
                                  pos /* client pos */, pos /* screen pos */,
                                  WebPointerProperties::Button::kLeft, 1,
@@ -333,7 +333,7 @@
       mouse_move_event, {}, {});
 }
 
-void MediaControlsImplTest::MouseUpAt(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseUpAt(gfx::PointF pos) {
   WebMouseEvent mouse_up_event(
       WebMouseEvent::kMouseUp, pos /* client pos */, pos /* screen pos */,
       WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
@@ -343,7 +343,7 @@
       mouse_up_event);
 }
 
-void MediaControlsImplTest::GestureTapAt(WebFloatPoint pos) {
+void MediaControlsImplTest::GestureTapAt(gfx::PointF pos) {
   WebGestureEvent gesture_tap_event(
       WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
       WebInputEvent::GetStaticTimeStampForTests());
@@ -351,8 +351,7 @@
   // Adjust |pos| by current frame scale.
   float frame_scale = GetDocument().GetFrame()->PageZoomFactor();
   gesture_tap_event.SetFrameScale(frame_scale);
-  pos.x = pos.x * frame_scale;
-  pos.y = pos.y * frame_scale;
+  pos.Scale(frame_scale);
   gesture_tap_event.SetPositionInWidget(pos);
 
   // Fire the event.
@@ -360,7 +359,7 @@
       gesture_tap_event);
 }
 
-void MediaControlsImplTest::GestureDoubleTapAt(WebFloatPoint pos) {
+void MediaControlsImplTest::GestureDoubleTapAt(gfx::PointF pos) {
   GestureTapAt(pos);
   GestureTapAt(pos);
 }
@@ -689,8 +688,8 @@
 
   EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
 
-  WebFloatPoint trackCenter(timelineRect->left() + timelineRect->width() / 2,
-                            timelineRect->top() + timelineRect->height() / 2);
+  gfx::PointF trackCenter(timelineRect->left() + timelineRect->width() / 2,
+                          timelineRect->top() + timelineRect->height() / 2);
   MouseDownAt(trackCenter);
   MouseUpAt(trackCenter);
   test::RunPendingTasks();
@@ -727,11 +726,11 @@
           ->UserAgentShadowRoot()
           ->getElementById(shadow_element_names::SliderThumb())
           ->getBoundingClientRect();
-  WebFloatPoint thumb(thumb_rect->x() + (thumb_rect->width() / 2),
-                      thumb_rect->y() + 1);
+  gfx::PointF thumb(thumb_rect->x() + (thumb_rect->width() / 2),
+                    thumb_rect->y() + 1);
 
   float y = timeline_rect->top() + timeline_rect->height() / 2;
-  WebFloatPoint track_two_thirds(
+  gfx::PointF track_two_thirds(
       timeline_rect->left() + timeline_rect->width() * 2 / 3, y);
   MouseDownAt(thumb);
   MouseMoveTo(track_two_thirds);
@@ -766,9 +765,9 @@
   EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
 
   float y = timelineRect->top() + timelineRect->height() / 2;
-  WebFloatPoint trackOneThird(
+  gfx::PointF trackOneThird(
       timelineRect->left() + timelineRect->width() * 1 / 3, y);
-  WebFloatPoint trackTwoThirds(
+  gfx::PointF trackTwoThirds(
       timelineRect->left() + timelineRect->width() * 2 / 3, y);
   MouseDownAt(trackOneThird);
   MouseMoveTo(trackTwoThirds);
@@ -803,10 +802,10 @@
   EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
 
   float y = timelineRect->top() + timelineRect->height() / 2;
-  WebFloatPoint trackTwoThirds(
+  gfx::PointF trackTwoThirds(
       timelineRect->left() + timelineRect->width() * 2 / 3, y);
-  WebFloatPoint trackEnd(timelineRect->left() + timelineRect->width(), y);
-  WebFloatPoint trackOneThird(
+  gfx::PointF trackEnd(timelineRect->left() + timelineRect->width(), y);
+  gfx::PointF trackOneThird(
       timelineRect->left() + timelineRect->width() * 1 / 3, y);
   MouseDownAt(trackTwoThirds);
   MouseMoveTo(trackEnd);
@@ -1207,10 +1206,10 @@
   EXPECT_TRUE(volume_slider->classList().contains("closed"));
 
   DOMRect* mute_btn_rect = mute_btn->getBoundingClientRect();
-  WebFloatPoint mute_btn_center(
+  gfx::PointF mute_btn_center(
       mute_btn_rect->left() + mute_btn_rect->width() / 2,
       mute_btn_rect->top() + mute_btn_rect->height() / 2);
-  WebFloatPoint edge(0, 0);
+  gfx::PointF edge(0, 0);
 
   // Hover on mute button and stay
   MouseMoveTo(mute_btn_center);
@@ -1393,10 +1392,10 @@
 
   DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
   ASSERT_LT(0, videoRect->width());
-  WebFloatPoint leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
-                             videoRect->top() + 5);
-  WebFloatPoint rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
-                              videoRect->top() + 5);
+  gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
+                           videoRect->top() + 5);
+  gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
+                            videoRect->top() + 5);
 
   // Double-tapping left of center should shift the time backwards by 10
   // seconds.
@@ -1423,10 +1422,10 @@
 
   DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
   ASSERT_LT(0, videoRect->width());
-  WebFloatPoint leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
-                             videoRect->top() + 10);
-  WebFloatPoint rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
-                              videoRect->top() + 10);
+  gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
+                           videoRect->top() + 10);
+  gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
+                            videoRect->top() + 10);
 
   // Add a zoom factor and ensure that it's properly handled.
   MediaControls().GetDocument().GetFrame()->SetPageZoomFactor(2);
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
index 235d17e..a69ae89 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -362,24 +362,24 @@
                                 ExceptionState& exception_state) {
   double media_time = GetMediaTime();
   DVLOG(2) << __func__ << " this=" << this << " media_time=" << media_time
-           << " size=" << data->DeprecatedByteLengthAsUnsigned();
+           << " size=" << data->ByteLengthAsSizeT();
   // Section 3.2 appendBuffer()
   // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
   AppendBufferInternal(media_time,
                        static_cast<const unsigned char*>(data->Data()),
-                       data->DeprecatedByteLengthAsUnsigned(), exception_state);
+                       data->ByteLengthAsSizeT(), exception_state);
 }
 
 void SourceBuffer::appendBuffer(NotShared<DOMArrayBufferView> data,
                                 ExceptionState& exception_state) {
   double media_time = GetMediaTime();
   DVLOG(3) << __func__ << " this=" << this << " media_time=" << media_time
-           << " size=" << data.View()->deprecatedByteLengthAsUnsigned();
+           << " size=" << data.View()->byteLengthAsSizeT();
   // Section 3.2 appendBuffer()
   // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
   AppendBufferInternal(
       media_time, static_cast<const unsigned char*>(data.View()->BaseAddress()),
-      data.View()->deprecatedByteLengthAsUnsigned(), exception_state);
+      data.View()->byteLengthAsSizeT(), exception_state);
 }
 
 void SourceBuffer::abort(ExceptionState& exception_state) {
@@ -1224,9 +1224,12 @@
   source_->OpenIfInEndedState();
 
   // 5. Run the coded frame eviction algorithm.
-  if (!EvictCodedFrames(media_time, new_data_size)) {
+  if (!EvictCodedFrames(media_time, new_data_size) ||
+      !base::CheckedNumeric<wtf_size_t>(new_data_size).IsValid()) {
     // 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_ERR
     //    exception and abort these steps.
+    //    If the incoming data exceeds wtf_size_t::max, then our implementation
+    //    cannot deal with it, so we also throw a QuotaExceededError.
     DVLOG(3) << __func__ << " this=" << this << " -> throw QuotaExceededError";
     MediaSource::LogAndThrowDOMException(exception_state,
                                          DOMExceptionCode::kQuotaExceededError,
@@ -1263,7 +1266,7 @@
 
 void SourceBuffer::AppendBufferInternal(double media_time,
                                         const unsigned char* data,
-                                        unsigned size,
+                                        size_t size,
                                         ExceptionState& exception_state) {
   TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size",
                            size);
@@ -1281,7 +1284,7 @@
   // 2. Add data to the end of the input buffer.
   DCHECK(data || size == 0);
   if (data)
-    pending_append_data_.Append(data, size);
+    pending_append_data_.Append(data, base::checked_cast<wtf_size_t>(size));
   pending_append_data_offset_ = 0;
 
   // 3. Set the updating attribute to true.
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.h b/third_party/blink/renderer/modules/mediasource/source_buffer.h
index e78b94a..4f2142c 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.h
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.h
@@ -126,7 +126,7 @@
   bool EvictCodedFrames(double media_time, size_t new_data_size);
   void AppendBufferInternal(double media_time,
                             const unsigned char*,
-                            unsigned,
+                            size_t,
                             ExceptionState&);
   void AppendBufferAsyncPart();
   void AppendError();
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
index c4a2c39..5d5a27c 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
@@ -119,7 +119,6 @@
 }
 Point::Point(const Point& other) = default;
 Point& Point::operator=(const Point& other) = default;
-Point::~Point() = default;
 
 bool Point::operator==(const Point& other) const {
   return height_ == other.height_ && width_ == other.width_;
@@ -216,7 +215,7 @@
     : ResolutionSet(0, kMaxDimension, 0, kMaxDimension, 0.0, HUGE_VAL) {}
 
 ResolutionSet::ResolutionSet(const ResolutionSet& other) = default;
-ResolutionSet::~ResolutionSet() = default;
+
 ResolutionSet& ResolutionSet::operator=(const ResolutionSet& other) = default;
 
 bool ResolutionSet::IsHeightEmpty() const {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
index 4ef0225..0fb2904 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h
@@ -239,7 +239,6 @@
     Point(double height, double width);
     Point(const Point& other);
     Point& operator=(const Point& other);
-    ~Point();
 
     // Accessors.
     double height() const { return height_; }
@@ -286,7 +285,6 @@
                 double max_aspect_ratio);
   ResolutionSet(const ResolutionSet& other);
   ResolutionSet& operator=(const ResolutionSet& other);
-  ~ResolutionSet();
 
   // Getters.
   int min_height() const { return min_height_; }
diff --git a/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc b/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
index be77a72d..bee37b64 100644
--- a/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
+++ b/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
@@ -118,6 +118,8 @@
 
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+  resource_request.SetRequestDestination(
+      network::mojom::RequestDestination::kImage);
   resource_request.SetPriority(ResourceLoadPriority::kMedium);
   resource_request.SetTimeoutInterval(kImageFetchTimeout);
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
index 022be86..ac8dd50 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -412,7 +412,7 @@
   }
   buffered_amount_ += data.View()->byteLengthAsSizeT();
   if (!SendRawData(static_cast<const char*>(data.View()->BaseAddress()),
-                   data.View()->deprecatedByteLengthAsUnsigned())) {
+                   data.View()->byteLengthAsSizeT())) {
     // TODO(https://crbug.com/937848): Don't throw an exception if data is
     // queued.
     ThrowCouldNotSendDataException(&exception_state);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc b/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
index cfb1899..4a974715 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
@@ -35,12 +35,13 @@
     sender_key[i] = kApplicationServerKey[i];
   sender_key[kApplicationServerKeyLength] = 0x0;
 
+  ASSERT_EQ(output->applicationServerKey()->ByteLengthAsSizeT(),
+            kApplicationServerKeyLength);
+
   String application_server_key(
       reinterpret_cast<const char*>(output->applicationServerKey()->Data()),
-      output->applicationServerKey()->DeprecatedByteLengthAsUnsigned());
-
-  ASSERT_EQ(output->applicationServerKey()->DeprecatedByteLengthAsUnsigned(),
-            kApplicationServerKeyLength);
+      static_cast<unsigned>(
+          output->applicationServerKey()->ByteLengthAsSizeT()));
 
   ASSERT_EQ(reinterpret_cast<const char*>(sender_key),
             application_server_key.Latin1());
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
index ad43b565..f2c3c46 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc
@@ -22,7 +22,7 @@
     const ArrayBufferOrArrayBufferViewOrString& application_server_key,
     ExceptionState& exception_state) {
   char* input;
-  int length;
+  size_t length;
   Vector<char> decoded_application_server_key;
   Vector<uint8_t> result;
 
@@ -30,15 +30,14 @@
   if (application_server_key.IsArrayBuffer()) {
     input =
         static_cast<char*>(application_server_key.GetAsArrayBuffer()->Data());
-    length = application_server_key.GetAsArrayBuffer()
-                 ->DeprecatedByteLengthAsUnsigned();
+    length = application_server_key.GetAsArrayBuffer()->ByteLengthAsSizeT();
   } else if (application_server_key.IsArrayBufferView()) {
     input = static_cast<char*>(
         application_server_key.GetAsArrayBufferView().View()->buffer()->Data());
     length = application_server_key.GetAsArrayBufferView()
                  .View()
                  ->buffer()
-                 ->DeprecatedByteLengthAsUnsigned();
+                 ->ByteLengthAsSizeT();
   } else if (application_server_key.IsString()) {
     if (!Base64UnpaddedURLDecode(application_server_key.GetAsString(),
                                  decoded_application_server_key)) {
@@ -65,7 +64,7 @@
        input + length);
 
   if (is_vapid || is_sender_id) {
-    result.Append(input, length);
+    result.Append(input, static_cast<wtf_size_t>(length));
   } else {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidAccessError,
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
index 55876b3..87ff711c 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -135,15 +135,23 @@
 
   const uint8_t* data = nullptr;
   uint32_t length = 0;
+  size_t byte_size = 0;
   if (buffer_source_.IsArrayBuffer()) {
     DOMArrayBuffer* array = buffer_source_.GetAsArrayBuffer();
+    byte_size = array->ByteLengthAsSizeT();
     data = static_cast<const uint8_t*>(array->Data());
-    length = array->DeprecatedByteLengthAsUnsigned();
   } else {
     DOMArrayBufferView* view = buffer_source_.GetAsArrayBufferView().View();
+    byte_size = view->byteLengthAsSizeT();
     data = static_cast<const uint8_t*>(view->BaseAddress());
-    length = view->deprecatedByteLengthAsUnsigned();
   }
+  if (byte_size > std::numeric_limits<uint32_t>::max()) {
+    pending_exception_ = DOMException::Create(
+        "Buffer size exceeds maximum heap object size.", "DataError");
+    PipeClosed();
+    return;
+  }
+  length = static_cast<uint32_t>(byte_size);
 
   DCHECK_LT(offset_, length);
   data += offset_;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index ef1f220..6a593439 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -250,7 +250,8 @@
   // "classic: Fetch a classic worker script given job's serialized script url,
   // job's client, "serviceworker", and the to-be-created environment settings
   // object for this service worker."
-  auto destination = mojom::RequestContextType::SERVICE_WORKER;
+  auto context_type = mojom::RequestContextType::SERVICE_WORKER;
+  auto destination = network::mojom::RequestDestination::kServiceWorker;
 
   // "To perform the fetch given request, run the following steps:"
   // Step 9.1. "Append `Service-Worker`/`script` to request's header list."
@@ -275,7 +276,8 @@
       *this,
       CreateOutsideSettingsFetcher(outside_settings_object,
                                    outside_resource_timing_notifier),
-      script_url, destination, network::mojom::RequestMode::kSameOrigin,
+      script_url, context_type, destination,
+      network::mojom::RequestMode::kSameOrigin,
       network::mojom::CredentialsMode::kSameOrigin,
       WTF::Bind(&ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript,
                 WrapWeakPersistent(this),
@@ -298,8 +300,9 @@
           : ModuleScriptCustomFetchType::kWorkerConstructor;
   FetchModuleScript(module_url_record, outside_settings_object,
                     outside_resource_timing_notifier,
-                    mojom::RequestContextType::SERVICE_WORKER, credentials_mode,
-                    fetch_type,
+                    mojom::RequestContextType::SERVICE_WORKER,
+                    network::mojom::RequestDestination::kServiceWorker,
+                    credentials_mode, fetch_type,
                     MakeGarbageCollected<ServiceWorkerModuleTreeClient>(
                         ScriptController()->GetScriptState()));
 }
@@ -1827,6 +1830,7 @@
         response_callback,
     DispatchFetchEventForMainResourceCallback callback) {
   DCHECK(IsContextThread());
+
   // We can use kNone as a |requestor_coep| for the main resource because it
   // must be the same origin.
   event_queue_->EnqueueNormal(
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
index 61ca81d1e..5364eb9 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -2179,16 +2179,21 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexImage2D", internalformat))
     return;
-  if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+  GLuint data_length;
+  if (!base::CheckedNumeric<GLuint>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
+                      "provided data exceeds the maximum supported length");
+    return;
+  }
+  if (src_offset > data_length) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                       "srcOffset is out of range");
     return;
   }
   if (src_length_override == 0) {
-    src_length_override =
-        data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
-  } else if (src_length_override >
-             data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+    src_length_override = data_length - src_offset;
+  } else if (src_length_override > data_length - src_offset) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                       "srcLengthOverride is out of range");
     return;
@@ -2261,16 +2266,21 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexSubImage2D", format))
     return;
-  if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+  GLuint data_length;
+  if (!base::CheckedNumeric<GLuint>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage2D",
+                      "provided data exceeds the maximum supported length");
+    return;
+  }
+  if (src_offset > data_length) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage2D",
                       "srcOffset is out of range");
     return;
   }
   if (src_length_override == 0) {
-    src_length_override =
-        data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
-  } else if (src_length_override >
-             data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+    src_length_override = data_length - src_offset;
+  } else if (src_length_override > data_length - src_offset) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                       "srcLengthOverride is out of range");
     return;
@@ -2325,16 +2335,21 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexImage3D", internalformat))
     return;
-  if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+  GLuint data_length;
+  if (!base::CheckedNumeric<GLuint>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
+                      "provided data exceeds the maximum supported length");
+    return;
+  }
+  if (src_offset > data_length) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
                       "srcOffset is out of range");
     return;
   }
   if (src_length_override == 0) {
-    src_length_override =
-        data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
-  } else if (src_length_override >
-             data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+    src_length_override = data_length - src_offset;
+  } else if (src_length_override > data_length - src_offset) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
                       "srcLengthOverride is out of range");
     return;
@@ -2391,16 +2406,21 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexSubImage3D", format))
     return;
-  if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+  GLuint data_length;
+  if (!base::CheckedNumeric<GLuint>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
+                      "provided data exceeds the maximum supported length");
+    return;
+  }
+  if (src_offset > data_length) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
                       "srcOffset is out of range");
     return;
   }
   if (src_length_override == 0) {
-    src_length_override =
-        data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
-  } else if (src_length_override >
-             data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+    src_length_override = data_length - src_offset;
+  } else if (src_length_override > data_length - src_offset) {
     SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
                       "srcLengthOverride is out of range");
     return;
@@ -2519,9 +2539,11 @@
                                                     1, src_offset, src_length))
     return;
 
-  ContextGL()->Uniform1fv(location->Location(),
-                          src_length ? src_length : (v.length() - src_offset),
-                          v.DataMaybeOnStack() + src_offset);
+  ContextGL()->Uniform1fv(
+      location->Location(),
+      src_length ? src_length
+                 : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+      v.DataMaybeOnStack() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniform1fv(
@@ -2550,7 +2572,10 @@
 
   ContextGL()->Uniform2fv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 1,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          1,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2581,7 +2606,10 @@
 
   ContextGL()->Uniform3fv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) / 3,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+          3,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2612,7 +2640,10 @@
 
   ContextGL()->Uniform4fv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 2,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          2,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2641,9 +2672,11 @@
                                                     1, src_offset, src_length))
     return;
 
-  ContextGL()->Uniform1iv(location->Location(),
-                          src_length ? src_length : (v.length() - src_offset),
-                          v.DataMaybeOnStack() + src_offset);
+  ContextGL()->Uniform1iv(
+      location->Location(),
+      src_length ? src_length
+                 : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+      v.DataMaybeOnStack() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniform1iv(
@@ -2672,7 +2705,10 @@
 
   ContextGL()->Uniform2iv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 1,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          1,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2703,7 +2739,10 @@
 
   ContextGL()->Uniform3iv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) / 3,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+          3,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2734,7 +2773,10 @@
 
   ContextGL()->Uniform4iv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 2,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          2,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2763,9 +2805,11 @@
                                                     1, src_offset, src_length))
     return;
 
-  ContextGL()->Uniform1uiv(location->Location(),
-                           src_length ? src_length : (v.length() - src_offset),
-                           v.DataMaybeOnStack() + src_offset);
+  ContextGL()->Uniform1uiv(
+      location->Location(),
+      src_length ? src_length
+                 : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+      v.DataMaybeOnStack() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniform1uiv(
@@ -2795,7 +2839,10 @@
 
   ContextGL()->Uniform2uiv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 1,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          1,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2826,7 +2873,10 @@
 
   ContextGL()->Uniform3uiv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) / 3,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+          3,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2857,7 +2907,10 @@
 
   ContextGL()->Uniform4uiv(
       location->Location(),
-      (src_length ? src_length : (v.length() - src_offset)) >> 2,
+      (src_length
+           ? src_length
+           : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+          2,
       v.DataMaybeOnStack() + src_offset);
 }
 
@@ -2890,7 +2943,8 @@
   ContextGL()->UniformMatrix2fv(
       location->Location(),
       (src_length ? src_length
-                  : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+                  : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+                     src_offset)) >>
           2,
       transpose, v.View()->DataMaybeShared() + src_offset);
 }
@@ -2924,7 +2978,8 @@
   ContextGL()->UniformMatrix3fv(
       location->Location(),
       (src_length ? src_length
-                  : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+                  : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+                     src_offset)) /
           9,
       transpose, v.View()->DataMaybeShared() + src_offset);
 }
@@ -2958,7 +3013,8 @@
   ContextGL()->UniformMatrix4fv(
       location->Location(),
       (src_length ? src_length
-                  : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+                  : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+                     src_offset)) >>
           4,
       transpose, v.View()->DataMaybeShared() + src_offset);
 }
@@ -2992,7 +3048,8 @@
   ContextGL()->UniformMatrix2x3fv(
       location->Location(),
       (src_length ? src_length
-                  : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) /
           6,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3027,7 +3084,8 @@
   ContextGL()->UniformMatrix3x2fv(
       location->Location(),
       (src_length ? src_length
-                  : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) /
           6,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3061,9 +3119,9 @@
     return;
   ContextGL()->UniformMatrix2x4fv(
       location->Location(),
-      (src_length
-           ? src_length
-           : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+      (src_length ? src_length
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) >>
           3,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3097,9 +3155,9 @@
     return;
   ContextGL()->UniformMatrix4x2fv(
       location->Location(),
-      (src_length
-           ? src_length
-           : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+      (src_length ? src_length
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) >>
           3,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3134,7 +3192,8 @@
   ContextGL()->UniformMatrix3x4fv(
       location->Location(),
       (src_length ? src_length
-                  : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) /
           12,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3169,7 +3228,8 @@
   ContextGL()->UniformMatrix4x3fv(
       location->Location(),
       (src_length ? src_length
-                  : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+                  : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+                     src_offset)) /
           12,
       transpose, value.View()->DataMaybeShared() + src_offset);
 }
@@ -3565,7 +3625,7 @@
 
 bool WebGL2RenderingContextBase::ValidateClearBuffer(const char* function_name,
                                                      GLenum buffer,
-                                                     GLsizei size,
+                                                     size_t size,
                                                      GLuint src_offset) {
   base::CheckedNumeric<GLsizei> checked_size(size);
   checked_size -= src_offset;
@@ -3612,8 +3672,7 @@
                                                GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferiv", buffer,
-                           value.View()->deprecatedLengthAsUnsigned(),
-                           src_offset))
+                           value.View()->lengthAsSizeT(), src_offset))
     return;
 
   ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_,
@@ -3646,8 +3705,7 @@
     GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferuiv", buffer,
-                           value.View()->deprecatedLengthAsUnsigned(),
-                           src_offset))
+                           value.View()->lengthAsSizeT(), src_offset))
     return;
 
   ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_,
@@ -3680,8 +3738,7 @@
     GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferfv", buffer,
-                           value.View()->deprecatedLengthAsUnsigned(),
-                           src_offset))
+                           value.View()->lengthAsSizeT(), src_offset))
     return;
 
   // As of this writing the default back buffer will always have an
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
index c971693..e0a262b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
@@ -997,7 +997,7 @@
 
   bool ValidateClearBuffer(const char* function_name,
                            GLenum buffer,
-                           GLsizei length,
+                           size_t length,
                            GLuint src_offset);
 
   enum TexStorageType {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_extension.cc b/third_party/blink/renderer/modules/webgl/webgl_extension.cc
index bb576c93..08da6099 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_extension.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_extension.cc
@@ -31,8 +31,6 @@
     WebGLExtension* extension)
     : context_(extension->context_) {}
 
-WebGLExtensionScopedContext::~WebGLExtensionScopedContext() = default;
-
 WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
     : context_(context) {}
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_extension.h b/third_party/blink/renderer/modules/webgl/webgl_extension.h
index adc2b41..ad390121 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_extension.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_extension.h
@@ -40,7 +40,6 @@
 
  public:
   explicit WebGLExtensionScopedContext(WebGLExtension*);
-  ~WebGLExtensionScopedContext();
 
   bool IsLost() const { return !context_; }
   WebGLRenderingContextBase* Context() const { return context_.Get(); }
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index e9db2ef..20c37c2 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -1994,7 +1994,7 @@
   if (isContextLost())
     return;
   DCHECK(data);
-  BufferDataImpl(target, data.View()->deprecatedByteLengthAsUnsigned(),
+  BufferDataImpl(target, data.View()->byteLengthAsSizeT(),
                  data.View()->BaseAddressMaybeShared(), usage);
 }
 
@@ -2033,7 +2033,7 @@
   if (isContextLost())
     return;
   DCHECK(data);
-  BufferSubDataImpl(target, offset, data.DeprecatedByteLengthAsUnsigned(),
+  BufferSubDataImpl(target, offset, data.ByteLengthAsSizeT(),
                     data.BaseAddressMaybeOnStack());
 }
 
@@ -2185,10 +2185,16 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexImage2D", internalformat))
     return;
-  ContextGL()->CompressedTexImage2D(
-      target, level, internalformat, width, height, border,
-      data.View()->deprecatedByteLengthAsUnsigned(),
-      data.View()->BaseAddressMaybeShared());
+  GLsizei data_length;
+  if (!base::CheckedNumeric<GLsizei>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
+                      "src_length exceeds the maximum supported length");
+    return;
+  }
+  ContextGL()->CompressedTexImage2D(target, level, internalformat, width,
+                                    height, border, data_length,
+                                    data.View()->BaseAddressMaybeShared());
 }
 
 void WebGLRenderingContextBase::compressedTexSubImage2D(
@@ -2206,10 +2212,16 @@
     return;
   if (!ValidateCompressedTexFormat("compressedTexSubImage2D", format))
     return;
-  ContextGL()->CompressedTexSubImage2D(
-      target, level, xoffset, yoffset, width, height, format,
-      data.View()->deprecatedByteLengthAsUnsigned(),
-      data.View()->BaseAddressMaybeShared());
+  GLsizei data_length;
+  if (!base::CheckedNumeric<GLsizei>(data.View()->byteLengthAsSizeT())
+           .AssignIfValid(&data_length)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
+                      "src_length exceeds the maximum supported length");
+    return;
+  }
+  ContextGL()->CompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+                                       height, format, data_length,
+                                       data.View()->BaseAddressMaybeShared());
 }
 
 bool WebGLRenderingContextBase::ValidateSettableTexFormat(
@@ -4422,7 +4434,8 @@
   base::CheckedNumeric<GLuint> offset_in_bytes = offset;
   offset_in_bytes *= pixels->TypeSize();
   if (!offset_in_bytes.IsValid() ||
-      offset_in_bytes.ValueOrDie() > pixels->deprecatedByteLengthAsUnsigned()) {
+      static_cast<size_t>(offset_in_bytes.ValueOrDie()) >
+          pixels->byteLengthAsSizeT()) {
     SynthesizeGLError(GL_INVALID_VALUE, "readPixels",
                       "destination offset out of range");
     return;
@@ -4435,7 +4448,7 @@
     return;
   }
   base::CheckedNumeric<GLuint> buffer_size =
-      pixels->deprecatedByteLengthAsUnsigned() - offset_in_bytes;
+      pixels->byteLengthAsSizeT() - offset_in_bytes;
   if (!buffer_size.IsValid()) {
     SynthesizeGLError(GL_INVALID_VALUE, "readPixels",
                       "destination offset out of range");
@@ -5588,10 +5601,18 @@
       source_image_rect == SentinelEmptyRect() ||
       source_image_rect ==
           IntRect(0, 0, video->videoWidth(), video->videoHeight());
-  const bool use_copyTextureCHROMIUM = function_id == kTexImage2D &&
-                                       source_image_rect_is_default &&
-                                       depth == 1 && GL_TEXTURE_2D == target &&
-                                       CanUseTexImageViaGPU(format, type);
+
+  const auto& caps = GetDrawingBuffer()->ContextProvider()->GetCapabilities();
+  const bool may_need_image_external_essl3 =
+      caps.egl_image_external &&
+      Extensions3DUtil::CopyTextureCHROMIUMNeedsESSL3(internalformat);
+  const bool have_image_external_essl3 = caps.egl_image_external_essl3;
+  const bool use_copyTextureCHROMIUM =
+      function_id == kTexImage2D && source_image_rect_is_default &&
+      depth == 1 && GL_TEXTURE_2D == target &&
+      (have_image_external_essl3 || !may_need_image_external_essl3) &&
+      CanUseTexImageViaGPU(format, type);
+
   // Format of source video may be 16-bit format, e.g. Y16 format.
   // glCopyTextureCHROMIUM requires the source texture to be in 8-bit format.
   // Converting 16-bits formated source texture to 8-bits formated texture will
@@ -6022,11 +6043,12 @@
 
 void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location,
                                            const FlexibleFloat32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform1fv", location, v, 1, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform1fv", location, v,
+                                                    1, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform1fv(location->Location(), v.length(),
+  ContextGL()->Uniform1fv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()),
                           v.DataMaybeOnStack());
 }
 
@@ -6056,11 +6078,12 @@
 
 void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location,
                                            const FlexibleInt32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform1iv", location, v, 1, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform1iv", location, v,
+                                                    1, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform1iv(location->Location(), v.length(),
+  ContextGL()->Uniform1iv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()),
                           v.DataMaybeOnStack());
 }
 
@@ -6091,11 +6114,12 @@
 
 void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location,
                                            const FlexibleFloat32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform2fv", location, v, 2, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform2fv", location, v,
+                                                    2, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform2fv(location->Location(), v.length() >> 1,
+  ContextGL()->Uniform2fv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 1,
                           v.DataMaybeOnStack());
 }
 
@@ -6126,11 +6150,12 @@
 
 void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location,
                                            const FlexibleInt32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform2iv", location, v, 2, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform2iv", location, v,
+                                                    2, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform2iv(location->Location(), v.length() >> 1,
+  ContextGL()->Uniform2iv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 1,
                           v.DataMaybeOnStack());
 }
 
@@ -6162,11 +6187,12 @@
 
 void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location,
                                            const FlexibleFloat32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform3fv", location, v, 3, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform3fv", location, v,
+                                                    3, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform3fv(location->Location(), v.length() / 3,
+  ContextGL()->Uniform3fv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) / 3,
                           v.DataMaybeOnStack());
 }
 
@@ -6198,11 +6224,12 @@
 
 void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location,
                                            const FlexibleInt32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform3iv", location, v, 3, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform3iv", location, v,
+                                                    3, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform3iv(location->Location(), v.length() / 3,
+  ContextGL()->Uniform3iv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) / 3,
                           v.DataMaybeOnStack());
 }
 
@@ -6235,11 +6262,12 @@
 
 void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location,
                                            const FlexibleFloat32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform4fv", location, v, 4, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform4fv", location, v,
+                                                    4, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform4fv(location->Location(), v.length() >> 2,
+  ContextGL()->Uniform4fv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 2,
                           v.DataMaybeOnStack());
 }
 
@@ -6272,11 +6300,12 @@
 
 void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location,
                                            const FlexibleInt32ArrayView& v) {
-  if (isContextLost() ||
-      !ValidateUniformParameters("uniform4iv", location, v, 4, 0, v.length()))
+  if (isContextLost() || !ValidateUniformParameters("uniform4iv", location, v,
+                                                    4, 0, v.lengthAsSizeT()))
     return;
 
-  ContextGL()->Uniform4iv(location->Location(), v.length() >> 2,
+  ContextGL()->Uniform4iv(location->Location(),
+                          base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 2,
                           v.DataMaybeOnStack());
 }
 
@@ -6296,11 +6325,12 @@
     MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
                              "uniformMatrix2fv", location, transpose, v.View(),
-                             4, 0, v.View()->deprecatedLengthAsUnsigned()))
+                             4, 0, v.View()->lengthAsSizeT()))
     return;
-  ContextGL()->UniformMatrix2fv(location->Location(),
-                                v.View()->deprecatedLengthAsUnsigned() >> 2,
-                                transpose, v.View()->DataMaybeShared());
+  ContextGL()->UniformMatrix2fv(
+      location->Location(),
+      base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) >> 2, transpose,
+      v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix2fv(
@@ -6321,11 +6351,12 @@
     MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
                              "uniformMatrix3fv", location, transpose, v.View(),
-                             9, 0, v.View()->deprecatedLengthAsUnsigned()))
+                             9, 0, v.View()->lengthAsSizeT()))
     return;
-  ContextGL()->UniformMatrix3fv(location->Location(),
-                                v.View()->deprecatedLengthAsUnsigned() / 9,
-                                transpose, v.View()->DataMaybeShared());
+  ContextGL()->UniformMatrix3fv(
+      location->Location(),
+      base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) / 9, transpose,
+      v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix3fv(
@@ -6346,11 +6377,12 @@
     MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
                              "uniformMatrix4fv", location, transpose, v.View(),
-                             16, 0, v.View()->deprecatedLengthAsUnsigned()))
+                             16, 0, v.View()->lengthAsSizeT()))
     return;
-  ContextGL()->UniformMatrix4fv(location->Location(),
-                                v.View()->deprecatedLengthAsUnsigned() >> 4,
-                                transpose, v.View()->DataMaybeShared());
+  ContextGL()->UniformMatrix4fv(
+      location->Location(),
+      base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) >> 4, transpose,
+      v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix4fv(
@@ -7492,7 +7524,7 @@
   total += total_bytes_required;
   total += skip_bytes;
   if (!total.IsValid() ||
-      pixels->deprecatedByteLengthAsUnsigned() < total.ValueOrDie()) {
+      pixels->byteLengthAsSizeT() < static_cast<size_t>(total.ValueOrDie())) {
     SynthesizeGLError(GL_INVALID_OPERATION, function_name,
                       "ArrayBufferView not big enough for request");
     return false;
@@ -7652,15 +7684,20 @@
     DOMFloat32Array* v,
     GLsizei required_min_size,
     GLuint src_offset,
-    GLuint src_length) {
+    size_t src_length) {
   if (!v) {
     SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
     return false;
   }
+  if (!base::CheckedNumeric<GLuint>(src_length).IsValid()) {
+    SynthesizeGLError(GL_INVALID_VALUE, function_name,
+                      "src_length exceeds the maximum supported length");
+    return false;
+  }
   return ValidateUniformMatrixParameters(
       function_name, location, transpose, v->DataMaybeShared(),
-      v->deprecatedLengthAsUnsigned(), required_min_size, src_offset,
-      src_length);
+      v->lengthAsSizeT(), required_min_size, src_offset,
+      static_cast<GLuint>(src_length));
 }
 
 bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
@@ -7668,7 +7705,7 @@
     const WebGLUniformLocation* location,
     GLboolean transpose,
     void* v,
-    GLsizei size,
+    size_t size,
     GLsizei required_min_size,
     GLuint src_offset,
     GLuint src_length) {
@@ -7684,6 +7721,11 @@
     SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
     return false;
   }
+  if (!base::CheckedNumeric<GLsizei>(size).IsValid()) {
+    SynthesizeGLError(GL_INVALID_VALUE, function_name,
+                      "array exceeds the maximum supported size");
+    return false;
+  }
   if (transpose && !IsWebGL2OrHigher()) {
     SynthesizeGLError(GL_INVALID_VALUE, function_name, "transpose not FALSE");
     return false;
@@ -7692,7 +7734,7 @@
     SynthesizeGLError(GL_INVALID_VALUE, function_name, "invalid srcOffset");
     return false;
   }
-  GLsizei actual_size = size - src_offset;
+  GLsizei actual_size = static_cast<GLsizei>(size) - src_offset;
   if (src_length > 0) {
     if (src_length > static_cast<GLuint>(actual_size)) {
       SynthesizeGLError(GL_INVALID_VALUE, function_name,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index fb5bd85f..91a0730 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -1418,12 +1418,12 @@
                                        DOMFloat32Array*,
                                        GLsizei mod,
                                        GLuint src_offset,
-                                       GLuint src_length);
+                                       size_t src_length);
   bool ValidateUniformMatrixParameters(const char* function_name,
                                        const WebGLUniformLocation*,
                                        GLboolean transpose,
                                        void*,
-                                       GLsizei,
+                                       size_t size,
                                        GLsizei mod,
                                        GLuint src_offset,
                                        GLuint src_length);
@@ -1435,14 +1435,26 @@
       const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
       GLsizei required_min_size,
       GLuint src_offset,
-      GLuint src_length) {
+      size_t src_length) {
+    GLuint length;
+    if (!base::CheckedNumeric<GLuint>(src_length).AssignIfValid(&length)) {
+      SynthesizeGLError(GL_INVALID_VALUE, function_name,
+                        "src_length is too big");
+      return false;
+    }
+    GLuint array_length;
+    if (!base::CheckedNumeric<GLuint>(v.lengthAsSizeT())
+             .AssignIfValid(&array_length)) {
+      SynthesizeGLError(GL_INVALID_VALUE, function_name, "array is too big");
+      return false;
+    }
     if (!v.DataMaybeOnStack()) {
       SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
       return false;
     }
     return ValidateUniformMatrixParameters(
-        function_name, location, false, v.DataMaybeOnStack(), v.length(),
-        required_min_size, src_offset, src_length);
+        function_name, location, false, v.DataMaybeOnStack(), array_length,
+        required_min_size, src_offset, length);
   }
 
   // Helper function to validate the target for bufferData and
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
index 7e6649e..7e5fdd5 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
@@ -12,7 +12,7 @@
     uint32_t dynamic_offsets_data_length,
     ExceptionState& exception_state) {
   const uint64_t src_length =
-      static_cast<uint64_t>(dynamic_offsets_data.length());
+      static_cast<uint64_t>(dynamic_offsets_data.lengthAsSizeT());
 
   if (dynamic_offsets_data_start > src_length) {
     exception_state.ThrowRangeError("dynamicOffsetsDataStart too large");
diff --git a/third_party/blink/renderer/modules/webmidi/midi_output.cc b/third_party/blink/renderer/modules/webmidi/midi_output.cc
index c7e8162..cd64245 100644
--- a/third_party/blink/renderer/modules/webmidi/midi_output.cc
+++ b/third_party/blink/renderer/modules/webmidi/midi_output.cc
@@ -98,6 +98,13 @@
       : data_(array->Data()), length_(array->lengthAsSizeT()), offset_(0) {}
 
   bool Process(ExceptionState& exception_state, bool sysex_enabled) {
+    // data_ is put into a WTF::Vector eventually, which only has wtf_size_t
+    // space.
+    if (!base::CheckedNumeric<wtf_size_t>(length_).IsValid()) {
+      exception_state.ThrowRangeError(
+          "Data exceeds the maximum supported length");
+      return false;
+    }
     while (!IsEndOfData() && AcceptRealTimeMessages()) {
       if (!IsStatusByte()) {
         exception_state.ThrowTypeError("Running status is not allowed " +
@@ -307,9 +314,10 @@
 
   while (!pending_data_.empty()) {
     auto& front = pending_data_.front();
-    midiAccess()->SendMIDIData(port_index_, front.first->Data(),
-                               front.first->deprecatedLengthAsUnsigned(),
-                               front.second);
+    midiAccess()->SendMIDIData(
+        port_index_, front.first->Data(),
+        base::checked_cast<wtf_size_t>(front.first->lengthAsSizeT()),
+        front.second);
     pending_data_.TakeFirst();
   }
 }
@@ -338,8 +346,9 @@
   if (IsOpening()) {
     pending_data_.emplace_back(array, timestamp);
   } else {
-    midiAccess()->SendMIDIData(port_index_, array->Data(),
-                               array->deprecatedLengthAsUnsigned(), timestamp);
+    midiAccess()->SendMIDIData(
+        port_index_, array->Data(),
+        base::checked_cast<wtf_size_t>(array->lengthAsSizeT()), timestamp);
   }
 }
 
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 5ec2b41..d9ca32f 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -150,6 +150,7 @@
     "//gpu/command_buffer/client:client",
     "//gpu/command_buffer/client:gles2_interface",
     "//gpu/command_buffer/common:common",
+    "//gpu/command_buffer/common:gles2_utils",
     "//net",
     "//services/device/public/mojom:generic_sensor_blink",
     "//services/device/public/mojom:mojom_blink",
@@ -192,7 +193,7 @@
   header_dir = "third_party/blink/renderer/platform/bindings"
 
   flags = [
-    "RAW_HEAP_SNAPSHOTS=$v8_enable_raw_heap_snapshots",
+    "RAW_HEAP_SNAPSHOTS=$enable_additional_blink_object_names",
     "RCS_COUNT_EVERYTHING=$runtime_call_stats_count_everything",
   ]
 }
@@ -512,7 +513,6 @@
     "exported/web_http_load_info.cc",
     "exported/web_icon_sizes_parser.cc",
     "exported/web_image_generator.cc",
-    "exported/web_input_event.cc",
     "exported/web_media_constraints.cc",
     "exported/web_media_player_client.cc",
     "exported/web_media_player_encrypted_media_client.cc",
diff --git a/third_party/blink/renderer/platform/exported/web_gesture_event.cc b/third_party/blink/renderer/platform/exported/web_gesture_event.cc
index 406e279..75cd9db 100644
--- a/third_party/blink/renderer/platform/exported/web_gesture_event.cc
+++ b/third_party/blink/renderer/platform/exported/web_gesture_event.cc
@@ -59,35 +59,34 @@
   return data.fling_start.velocity_y;
 }
 
-WebFloatSize WebGestureEvent::TapAreaInRootFrame() const {
+gfx::SizeF WebGestureEvent::TapAreaInRootFrame() const {
   if (type_ == WebInputEvent::kGestureTwoFingerTap) {
-    return WebFloatSize(data.two_finger_tap.first_finger_width / frame_scale_,
-                        data.two_finger_tap.first_finger_height / frame_scale_);
+    return gfx::SizeF(data.two_finger_tap.first_finger_width / frame_scale_,
+                      data.two_finger_tap.first_finger_height / frame_scale_);
   } else if (type_ == WebInputEvent::kGestureLongPress ||
              type_ == WebInputEvent::kGestureLongTap) {
-    return WebFloatSize(data.long_press.width / frame_scale_,
-                        data.long_press.height / frame_scale_);
+    return gfx::SizeF(data.long_press.width / frame_scale_,
+                      data.long_press.height / frame_scale_);
   } else if (type_ == WebInputEvent::kGestureTap ||
              type_ == WebInputEvent::kGestureTapUnconfirmed ||
              type_ == WebInputEvent::kGestureDoubleTap) {
-    return WebFloatSize(data.tap.width / frame_scale_,
-                        data.tap.height / frame_scale_);
+    return gfx::SizeF(data.tap.width / frame_scale_,
+                      data.tap.height / frame_scale_);
   } else if (type_ == WebInputEvent::kGestureTapDown) {
-    return WebFloatSize(data.tap_down.width / frame_scale_,
-                        data.tap_down.height / frame_scale_);
+    return gfx::SizeF(data.tap_down.width / frame_scale_,
+                      data.tap_down.height / frame_scale_);
   } else if (type_ == WebInputEvent::kGestureShowPress) {
-    return WebFloatSize(data.show_press.width / frame_scale_,
-                        data.show_press.height / frame_scale_);
+    return gfx::SizeF(data.show_press.width / frame_scale_,
+                      data.show_press.height / frame_scale_);
   }
   // This function is called for all gestures and determined if the tap
   // area is empty or not; so return an empty rect here.
-  return WebFloatSize();
+  return gfx::SizeF();
 }
 
-WebFloatPoint WebGestureEvent::PositionInRootFrame() const {
-  return WebFloatPoint(
-      (position_in_widget_.x / frame_scale_) + frame_translate_.x,
-      (position_in_widget_.y / frame_scale_) + frame_translate_.y);
+gfx::PointF WebGestureEvent::PositionInRootFrame() const {
+  return gfx::ScalePoint(position_in_widget_, 1 / frame_scale_) +
+         frame_translate_;
 }
 
 int WebGestureEvent::TapCount() const {
@@ -95,16 +94,15 @@
   return data.tap.tap_count;
 }
 
-void WebGestureEvent::ApplyTouchAdjustment(WebFloatPoint root_frame_coords) {
+void WebGestureEvent::ApplyTouchAdjustment(
+    const gfx::PointF& root_frame_coords) {
   // Update the window-relative position of the event so that the node that
   // was ultimately hit is under this point (i.e. elementFromPoint for the
   // client co-ordinates in a 'click' event should yield the target). The
   // global position is intentionally left unmodified because it's intended to
   // reflect raw co-ordinates unrelated to any content.
-  frame_translate_.x =
-      root_frame_coords.x - (position_in_widget_.x / frame_scale_);
-  frame_translate_.y =
-      root_frame_coords.y - (position_in_widget_.y / frame_scale_);
+  frame_translate_ = root_frame_coords -
+                     gfx::ScalePoint(position_in_widget_, 1 / frame_scale_);
 }
 
 void WebGestureEvent::FlattenTransform() {
@@ -147,8 +145,7 @@
   }
 
   SetPositionInWidget(PositionInRootFrame());
-  frame_translate_.x = 0;
-  frame_translate_.y = 0;
+  frame_translate_ = gfx::Vector2dF();
   frame_scale_ = 1;
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_input_event.cc b/third_party/blink/renderer/platform/exported/web_input_event.cc
deleted file mode 100644
index 85661bc..0000000
--- a/third_party/blink/renderer/platform/exported/web_input_event.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/platform/web_input_event.h"
-
-#include <ctype.h>
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
-#include "third_party/blink/renderer/platform/keyboard_codes.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
-
-namespace blink {
-
-struct SameSizeAsWebInputEvent {
-  int input_data[8];
-};
-
-struct SameSizeAsWebKeyboardEvent : public SameSizeAsWebInputEvent {
-  int keyboard_data[9];
-};
-
-struct SameSizeAsWebMouseEvent : public SameSizeAsWebInputEvent {
-  int mouse_data[17];
-};
-
-struct SameSizeAsWebMouseWheelEvent : public SameSizeAsWebMouseEvent {
-  int mousewheel_data[12];
-};
-
-struct SameSizeAsWebGestureEvent : public SameSizeAsWebInputEvent {
-  int gesture_data[14];
-};
-
-struct SameSizeAsWebTouchEvent : public SameSizeAsWebInputEvent {
-  WebTouchPoint touch_points[WebTouchEvent::kTouchesLengthCap];
-  int touch_data[4];
-};
-
-static_assert(sizeof(WebInputEvent) == sizeof(SameSizeAsWebInputEvent),
-              "WebInputEvent should not have gaps");
-static_assert(sizeof(WebKeyboardEvent) == sizeof(SameSizeAsWebKeyboardEvent),
-              "WebKeyboardEvent should not have gaps");
-static_assert(sizeof(WebMouseEvent) == sizeof(SameSizeAsWebMouseEvent),
-              "WebMouseEvent should not have gaps");
-static_assert(sizeof(WebMouseWheelEvent) ==
-                  sizeof(SameSizeAsWebMouseWheelEvent),
-              "WebMouseWheelEvent should not have gaps");
-static_assert(sizeof(WebGestureEvent) == sizeof(SameSizeAsWebGestureEvent),
-              "WebGestureEvent should not have gaps");
-static_assert(sizeof(WebTouchEvent) == sizeof(SameSizeAsWebTouchEvent),
-              "WebTouchEvent should not have gaps");
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_mouse_event.cc b/third_party/blink/renderer/platform/exported/web_mouse_event.cc
index ff5338a..15b5d9e5 100644
--- a/third_party/blink/renderer/platform/exported/web_mouse_event.cc
+++ b/third_party/blink/renderer/platform/exported/web_mouse_event.cc
@@ -29,10 +29,9 @@
   SetMenuSourceType(gesture_event.GetType());
 }
 
-WebFloatPoint WebMouseEvent::PositionInRootFrame() const {
-  return WebFloatPoint(
-      (position_in_widget_.x / frame_scale_) + frame_translate_.x,
-      (position_in_widget_.y / frame_scale_) + frame_translate_.y);
+gfx::PointF WebMouseEvent::PositionInRootFrame() const {
+  return gfx::ScalePoint(position_in_widget_, 1 / frame_scale_) +
+         frame_translate_;
 }
 
 WebMouseEvent WebMouseEvent::FlattenTransform() const {
@@ -43,8 +42,7 @@
 
 void WebMouseEvent::FlattenTransformSelf() {
   position_in_widget_ = PositionInRootFrame();
-  frame_translate_.x = 0;
-  frame_translate_.y = 0;
+  frame_translate_ = gfx::Vector2dF();
   frame_scale_ = 1;
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_pointer_event.cc b/third_party/blink/renderer/platform/exported/web_pointer_event.cc
index 8c710c1..d4a8058 100644
--- a/third_party/blink/renderer/platform/exported/web_pointer_event.cc
+++ b/third_party/blink/renderer/platform/exported/web_pointer_event.cc
@@ -91,10 +91,8 @@
   if (HasHeight())
     transformed_event.height /= frame_scale_;
   transformed_event.position_in_widget_ =
-      WebFloatPoint((transformed_event.PositionInWidget().x / frame_scale_) +
-                        frame_translate_.x,
-                    (transformed_event.PositionInWidget().y / frame_scale_) +
-                        frame_translate_.y);
+      gfx::ScalePoint(transformed_event.PositionInWidget(), 1 / frame_scale_) +
+      frame_translate_;
   return transformed_event;
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_touch_event.cc b/third_party/blink/renderer/platform/exported/web_touch_event.cc
index e358ccb9..4965eba 100644
--- a/third_party/blink/renderer/platform/exported/web_touch_event.cc
+++ b/third_party/blink/renderer/platform/exported/web_touch_event.cc
@@ -11,8 +11,7 @@
   for (unsigned i = 0; i < touches_length; ++i) {
     transformed_event.touches[i] = TouchPointInRootFrame(i);
   }
-  transformed_event.frame_translate_.x = 0;
-  transformed_event.frame_translate_.y = 0;
+  transformed_event.frame_translate_ = gfx::Vector2dF();
   transformed_event.frame_scale_ = 1;
 
   return transformed_event;
@@ -27,10 +26,8 @@
   transformed_point.radius_x /= frame_scale_;
   transformed_point.radius_y /= frame_scale_;
   transformed_point.SetPositionInWidget(
-      (transformed_point.PositionInWidget().x / frame_scale_) +
-          frame_translate_.x,
-      (transformed_point.PositionInWidget().y / frame_scale_) +
-          frame_translate_.y);
+      gfx::ScalePoint(transformed_point.PositionInWidget(), 1 / frame_scale_) +
+      frame_translate_);
   return transformed_point;
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc
index 50ebdbb..943a17f 100644
--- a/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -170,20 +170,6 @@
   resource_request_->SetHttpHeaderField(name, value);
 }
 
-void WebURLRequest::SetHttpReferrer(
-    const WebString& web_referrer,
-    network::mojom::ReferrerPolicy referrer_policy) {
-  // WebString doesn't have the distinction between empty and null. We use
-  // the null WTFString for referrer.
-  DCHECK_EQ(Referrer::NoReferrer(), String());
-  String referrer =
-      web_referrer.IsEmpty() ? Referrer::NoReferrer() : String(web_referrer);
-  // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
-  // header and instead use a separate member. See https://crbug.com/850813.
-  resource_request_->SetHttpReferrer(Referrer(referrer, referrer_policy));
-  resource_request_->SetReferrerString(referrer);
-}
-
 void WebURLRequest::AddHttpHeaderField(const WebString& name,
                                        const WebString& value) {
   resource_request_->AddHttpHeaderField(name, value);
@@ -227,6 +213,24 @@
   return resource_request_->GetRequestContext();
 }
 
+network::mojom::RequestDestination WebURLRequest::GetRequestDestination()
+    const {
+  return resource_request_->GetRequestDestination();
+}
+
+void WebURLRequest::SetReferrerString(const WebString& referrer) {
+  resource_request_->SetReferrerString(referrer);
+}
+
+void WebURLRequest::SetReferrerPolicy(
+    network::mojom::ReferrerPolicy referrer_policy) {
+  resource_request_->SetReferrerPolicy(referrer_policy);
+}
+
+WebString WebURLRequest::ReferrerString() const {
+  return resource_request_->ReferrerString();
+}
+
 network::mojom::ReferrerPolicy WebURLRequest::GetReferrerPolicy() const {
   return resource_request_->GetReferrerPolicy();
 }
@@ -248,6 +252,11 @@
   resource_request_->SetRequestContext(request_context);
 }
 
+void WebURLRequest::SetRequestDestination(
+    network::mojom::RequestDestination destination) {
+  resource_request_->SetRequestDestination(destination);
+}
+
 int WebURLRequest::RequestorID() const {
   return resource_request_->RequestorID();
 }
diff --git a/third_party/blink/renderer/platform/geometry/float_point.h b/third_party/blink/renderer/platform/geometry/float_point.h
index cd1ddb8b..73d13fd 100644
--- a/third_party/blink/renderer/platform/geometry/float_point.h
+++ b/third_party/blink/renderer/platform/geometry/float_point.h
@@ -217,6 +217,10 @@
   return IntPoint(clampTo<int>(floorf(p.X())), clampTo<int>(floorf(p.Y())));
 }
 
+inline IntPoint FlooredIntPoint(const gfx::PointF& p) {
+  return IntPoint(clampTo<int>(floorf(p.x())), clampTo<int>(floorf(p.y())));
+}
+
 inline IntPoint CeiledIntPoint(const FloatPoint& p) {
   return IntPoint(clampTo<int>(ceilf(p.X())), clampTo<int>(ceilf(p.Y())));
 }
diff --git a/third_party/blink/renderer/platform/geometry/layout_size.h b/third_party/blink/renderer/platform/geometry/layout_size.h
index 472784b0..32a0c93 100644
--- a/third_party/blink/renderer/platform/geometry/layout_size.h
+++ b/third_party/blink/renderer/platform/geometry/layout_size.h
@@ -65,6 +65,8 @@
       : width_(size.Width()), height_(size.Height()) {}
   constexpr explicit LayoutSize(const gfx::Size& size)
       : width_(size.width()), height_(size.height()) {}
+  constexpr explicit LayoutSize(const gfx::SizeF& size)
+      : width_(size.width()), height_(size.height()) {}
 
   constexpr explicit operator FloatSize() const {
     return FloatSize(width_.ToFloat(), height_.ToFloat());
diff --git a/third_party/blink/renderer/platform/graphics/DEPS b/third_party/blink/renderer/platform/graphics/DEPS
index 69ebb83..a41c151c8 100644
--- a/third_party/blink/renderer/platform/graphics/DEPS
+++ b/third_party/blink/renderer/platform/graphics/DEPS
@@ -19,6 +19,7 @@
     "+gpu/command_buffer/client/gpu_memory_buffer_manager.h",
     "+gpu/command_buffer/client/raster_interface.h",
     "+gpu/command_buffer/client/shared_image_interface.h",
+    "+gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h",
     "+gpu/command_buffer/common/gpu_memory_buffer_support.h",
     "+gpu/command_buffer/common/capabilities.h",
     "+gpu/command_buffer/common/mailbox.h",
diff --git a/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc b/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
index 50308ff..388559e7 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
@@ -9,6 +9,7 @@
 #include "base/memory/ptr_util.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
 
 namespace blink {
@@ -75,6 +76,12 @@
   return enabled_extensions_.Contains(name);
 }
 
+// static
+bool Extensions3DUtil::CopyTextureCHROMIUMNeedsESSL3(GLenum dest_format) {
+  return gpu::gles2::CopyTextureCHROMIUMNeedsESSL3(dest_format);
+}
+
+// static
 bool Extensions3DUtil::CanUseCopyTextureCHROMIUM(GLenum dest_target) {
   switch (dest_target) {
     case GL_TEXTURE_2D:
diff --git a/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h b/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
index 062807c4..6a21415 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
+++ b/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
@@ -38,6 +38,7 @@
   bool EnsureExtensionEnabled(const String& name);
   bool IsExtensionEnabled(const String& name);
 
+  static bool CopyTextureCHROMIUMNeedsESSL3(GLenum dest_format);
   static bool CanUseCopyTextureCHROMIUM(GLenum dest_target);
 
  private:
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator.h b/third_party/blink/renderer/platform/heap/heap_allocator.h
index d41fe4e4..9d150d78d 100644
--- a/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -125,8 +125,11 @@
   static void FreeHashTableBacking(void* address);
   static bool ExpandHashTableBacking(void*, size_t);
 
-  static void TraceMarkedBackingStore(void* address) {
-    MarkingVisitor::TraceMarkedBackingStore(address);
+  static void TraceBackingStoreIfMarked(void* address) {
+    // Trace backing store elements only if backing store was marked.
+    if (HeapObjectHeader::FromPayload(address)->IsMarked()) {
+      MarkingVisitor::TraceMarkedBackingStore(address);
+    }
   }
 
   static void BackingWriteBarrier(void* address) {
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index 968254e..614f0b37 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -311,11 +311,9 @@
   DCHECK(ScriptForbiddenScope::IsScriptForbidden());
 
   size_t page_count = 1;
-  // TODO(bikineev): We should probably process pages in the reverse order. This
-  // will leave more work for concurrent sweeper and reduce memory footprint
-  // faster.
-  while (BasePage* page = unswept_pages_.PopLocked()) {
-    SweepUnsweptPage(page);
+  // First, process empty pages to faster reduce memory footprint.
+  while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
+    page->FinalizeSweep(SweepResult::kPageEmpty);
     if (page_count % kDeadlineCheckInterval == 0) {
       if (deadline <= base::TimeTicks::Now()) {
         // Deadline has come.
@@ -324,6 +322,7 @@
     }
     page_count++;
   }
+  // Second, execute finalizers to leave more work for concurrent sweeper.
   while (BasePage* page = swept_unfinalized_pages_.PopLocked()) {
     swept_pages_.PushLocked(page);
     page->FinalizeSweep(SweepResult::kPageNotEmpty);
@@ -335,8 +334,9 @@
     }
     page_count++;
   }
-  while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
-    page->FinalizeSweep(SweepResult::kPageEmpty);
+  // Help concurrent sweeper.
+  while (BasePage* page = unswept_pages_.PopLocked()) {
+    SweepUnsweptPage(page);
     if (page_count % kDeadlineCheckInterval == 0) {
       if (deadline <= base::TimeTicks::Now()) {
         // Deadline has come.
@@ -384,14 +384,14 @@
   // Some phases, e.g. verification, require iterability of a page.
   MakeIterable();
 
-  // First, sweep and finalize pages.
+  // First, finalize pages that have been processed by concurrent sweepers.
+  InvokeFinalizersOnSweptPages();
+
+  // Then, sweep and finalize pages.
   while (BasePage* page = unswept_pages_.PopLocked()) {
     SweepUnsweptPage(page);
   }
 
-  // Then, finalize pages that have been processed by concurrent sweepers.
-  InvokeFinalizersOnSweptPages();
-
   // Verify object start bitmap after all freelists have been merged.
   VerifyObjectStartBitmap();
 }
@@ -1125,7 +1125,9 @@
 }
 
 void FreeList::MoveFrom(FreeList* other) {
+#if DCHECK_IS_ON()
   const size_t expected_size = FreeListSize() + other->FreeListSize();
+#endif
 
   // Newly created entries get added to the head.
   for (size_t index = 0; index < kBlinkPageSizeLog2; ++index) {
@@ -1146,7 +1148,9 @@
       std::max(biggest_free_list_index_, other->biggest_free_list_index_);
   other->biggest_free_list_index_ = 0;
 
+#if DCHECK_IS_ON()
   DCHECK_EQ(expected_size, FreeListSize());
+#endif
   DCHECK(other->IsEmpty());
 }
 
diff --git a/third_party/blink/renderer/platform/heap/marking_verifier.cc b/third_party/blink/renderer/platform/heap/marking_verifier.cc
index 1fd41c4..c08b7615 100644
--- a/third_party/blink/renderer/platform/heap/marking_verifier.cc
+++ b/third_party/blink/renderer/platform/heap/marking_verifier.cc
@@ -83,12 +83,13 @@
   CHECK(child_header);
   if (!child_header->IsMarked()) {
     CHECK(!PageFromObject(child_header->Payload())->HasBeenSwept());
-    LOG(FATAL) << "MarkingVerifier: Encountered unmarked object. " << std::endl
-               << std::endl
-               << "Hint (use v8_enable_raw_heap_snapshots for better naming): "
-               << std::endl
-               << parent_->Name() << std::endl
-               << "\\-> " << child_header->Name() << std::endl;
+    LOG(FATAL)
+        << "MarkingVerifier: Encountered unmarked object. " << std::endl
+        << std::endl
+        << "Hint (use enable_additional_blink_object_names for better naming): "
+        << std::endl
+        << parent_->Name() << std::endl
+        << "\\-> " << child_header->Name() << std::endl;
   }
 }
 
diff --git a/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc b/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
index e1e2417..54c702cb 100644
--- a/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
+++ b/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
@@ -14,8 +14,6 @@
     : memory_allocator_dump_(memory_allocator_dump),
       guid_(memory_allocator_dump->guid().ToUint64()) {}
 
-WebMemoryAllocatorDump::~WebMemoryAllocatorDump() = default;
-
 void WebMemoryAllocatorDump::AddScalar(const char* name,
                                        const char* units,
                                        uint64_t value) {
diff --git a/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h b/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
index a9af22e..75180ad 100644
--- a/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
+++ b/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
@@ -30,7 +30,6 @@
  public:
   explicit WebMemoryAllocatorDump(
       base::trace_event::MemoryAllocatorDump* memory_allocator_dump);
-  ~WebMemoryAllocatorDump();
 
   // Adds a scalar attribute to the dump.
   // Arguments:
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
index de0d27f..bfdf261 100644
--- a/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
+++ b/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
@@ -88,6 +88,10 @@
     resource_request_.SetRequestContext(context);
   }
 
+  void SetRequestDestination(network::mojom::RequestDestination destination) {
+    resource_request_.SetRequestDestination(destination);
+  }
+
   void SetFetchImportanceMode(mojom::FetchImportanceMode importance_mode) {
     resource_request_.SetFetchImportanceMode(importance_mode);
   }
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index 4d15c82..9f5346c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -55,6 +55,7 @@
                                       ResourceFetcher* fetcher,
                                       RawResourceClient* client) {
   params.SetRequestContext(mojom::RequestContextType::IMPORT);
+  params.SetRequestDestination(network::mojom::RequestDestination::kEmpty);
   return ToRawResource(fetcher->RequestResource(
       params, RawResourceFactory(ResourceType::kImportResource), client));
 }
@@ -85,6 +86,7 @@
                                          ResourceFetcher* fetcher,
                                          RawResourceClient* client) {
   params.SetRequestContext(mojom::RequestContextType::TRACK);
+  params.SetRequestDestination(network::mojom::RequestDestination::kTrack);
   return ToRawResource(fetcher->RequestResource(
       params, RawResourceFactory(ResourceType::kTextTrack), client));
 }
@@ -406,8 +408,6 @@
 RawResourceClientStateChecker::RawResourceClientStateChecker()
     : state_(kNotAddedAsClient) {}
 
-RawResourceClientStateChecker::~RawResourceClientStateChecker() = default;
-
 NOINLINE void RawResourceClientStateChecker::WillAddClient() {
   SECURITY_CHECK(state_ == kNotAddedAsClient);
   state_ = kStarted;
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
index 11aa753..3c0fc518 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
@@ -207,7 +207,6 @@
 
  public:
   RawResourceClientStateChecker();
-  ~RawResourceClientStateChecker();
 
   // Call before addClient()/removeClient() is called.
   void WillAddClient();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 9bc35c6..cac85602 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -37,7 +37,6 @@
 #include "base/time/time.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/loader/request_destination.h"
 #include "third_party/blink/public/common/mime_util/mime_util.h"
 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
@@ -307,65 +306,20 @@
 void SetReferrer(
     ResourceRequest& request,
     const FetchClientSettingsObject& fetch_client_settings_object) {
-  if (!request.DidSetHttpReferrer()) {
-    String referrer_to_use = request.ReferrerString();
-    network::mojom::ReferrerPolicy referrer_policy_to_use =
-        request.GetReferrerPolicy();
+  String referrer_to_use = request.ReferrerString();
+  network::mojom::ReferrerPolicy referrer_policy_to_use =
+      request.GetReferrerPolicy();
 
-    if (referrer_to_use == Referrer::ClientReferrerString())
-      referrer_to_use = fetch_client_settings_object.GetOutgoingReferrer();
+  if (referrer_to_use == Referrer::ClientReferrerString())
+    referrer_to_use = fetch_client_settings_object.GetOutgoingReferrer();
 
-    if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
-      referrer_policy_to_use = fetch_client_settings_object.GetReferrerPolicy();
+  if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
+    referrer_policy_to_use = fetch_client_settings_object.GetReferrerPolicy();
 
-    request.SetReferrerString(referrer_to_use);
-    request.SetReferrerPolicy(referrer_policy_to_use);
-    // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header
-    // and store it elsewhere. See https://crbug.com/850813.
-    request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
-        referrer_policy_to_use, request.Url(), referrer_to_use));
-  } else {
-    // In the case of stale requests that are being revalidated, these requests
-    // will already have their HttpReferrer set, and we will end up here. We
-    // won't regenerate the referrer, but instead check that it's still correct.
-    CHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(),
-                                              request.Url(),
-                                              request.ReferrerString())
-                 .referrer,
-             request.HttpReferrer());
-  }
-}
-
-void SetSecFetchHeaders(
-    ResourceRequest& request,
-    const FetchClientSettingsObject& fetch_client_settings_object) {
-  scoped_refptr<SecurityOrigin> url_origin =
-      SecurityOrigin::Create(request.Url());
-  if (blink::RuntimeEnabledFeatures::FetchMetadataEnabled() &&
-      url_origin->IsPotentiallyTrustworthy()) {
-    const char* destination_value =
-        GetRequestDestinationFromContext(request.GetRequestContext());
-
-    // If the request's destination is the empty string (e.g. `fetch()`), then
-    // we'll use the identifier "empty" instead.
-    if (strlen(destination_value) == 0)
-      destination_value = "empty";
-
-    // We'll handle adding these headers to navigations outside of Blink.
-    if ((strncmp(destination_value, "document", 8) != 0 ||
-         strncmp(destination_value, "iframe", 6) != 0 ||
-         strncmp(destination_value, "frame", 5) != 0) &&
-        request.GetRequestContext() != mojom::RequestContextType::INTERNAL) {
-      if (blink::RuntimeEnabledFeatures::FetchMetadataDestinationEnabled()) {
-        request.SetHttpHeaderField("Sec-Fetch-Dest", destination_value);
-      }
-
-      // Note that the `Sec-Fetch-User` header is always false (and therefore
-      // omitted) for subresource requests. Likewise, note that we rely on
-      // Blink's embedder to set `Sec-Fetch-Site`, as we don't want to trust the
-      // renderer to assert its own origin. Ditto for `Sec-Fetch-Mode`.
-    }
-  }
+  Referrer generated_referrer = SecurityPolicy::GenerateReferrer(
+      referrer_policy_to_use, request.Url(), referrer_to_use);
+  request.SetReferrerString(generated_referrer.referrer);
+  request.SetReferrerPolicy(generated_referrer.referrer_policy);
 }
 
 }  // namespace
@@ -426,6 +380,40 @@
   return mojom::RequestContextType::SUBRESOURCE;
 }
 
+network::mojom::RequestDestination ResourceFetcher::DetermineRequestDestination(
+    ResourceType type) {
+  switch (type) {
+    case ResourceType::kXSLStyleSheet:
+      DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+      FALLTHROUGH;
+    case ResourceType::kCSSStyleSheet:
+      return network::mojom::RequestDestination::kStyle;
+    case ResourceType::kScript:
+      return network::mojom::RequestDestination::kScript;
+    case ResourceType::kFont:
+      return network::mojom::RequestDestination::kFont;
+    case ResourceType::kImage:
+      return network::mojom::RequestDestination::kImage;
+    case ResourceType::kTextTrack:
+      return network::mojom::RequestDestination::kTrack;
+    case ResourceType::kSVGDocument:
+      return network::mojom::RequestDestination::kImage;
+    case ResourceType::kAudio:
+      return network::mojom::RequestDestination::kAudio;
+    case ResourceType::kVideo:
+      return network::mojom::RequestDestination::kVideo;
+    case ResourceType::kManifest:
+      return network::mojom::RequestDestination::kManifest;
+    case ResourceType::kRaw:
+    case ResourceType::kImportResource:
+    case ResourceType::kLinkPrefetch:
+    case ResourceType::kMock:
+      return network::mojom::RequestDestination::kEmpty;
+  }
+  NOTREACHED();
+  return network::mojom::RequestDestination::kEmpty;
+}
+
 // static
 void ResourceFetcher::AddPriorityObserverForTesting(
     const KURL& resource_url,
@@ -868,6 +856,8 @@
       mojom::RequestContextType::UNSPECIFIED) {
     resource_request.SetRequestContext(
         DetermineRequestContext(resource_type, kImageNotImageSet));
+    resource_request.SetRequestDestination(
+        DetermineRequestDestination(resource_type));
   }
   if (resource_type == ResourceType::kLinkPrefetch)
     resource_request.SetPurposeHeader("prefetch");
@@ -885,9 +875,6 @@
   resource_request.SetExternalRequestStateFromRequestorAddressSpace(
       properties_->GetFetchClientSettingsObject().GetAddressSpace());
 
-  SetSecFetchHeaders(resource_request,
-                     properties_->GetFetchClientSettingsObject());
-
   Context().AddAdditionalRequestHeaders(resource_request);
 
   TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(
@@ -2037,12 +2024,14 @@
     Resource* resource,
     const KURL& url,
     mojom::RequestContextType request_context,
+    network::mojom::RequestDestination request_destination,
     const AtomicString& initiator_name) {
   base::AutoReset<bool> r(&is_in_request_resource_, true);
   if (CachedResource(url))
     return;
   ResourceRequest resource_request(url);
   resource_request.SetRequestContext(request_context);
+  resource_request.SetRequestDestination(request_destination);
   if (!resource_request.PriorityHasBeenSet()) {
     resource_request.SetPriority(ComputeLoadPriority(
         resource->GetType(), resource_request, ResourcePriority::kNotVisible,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 9c3ad282..87f2d01 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -223,6 +223,9 @@
       ResourceType,
       IsImageSet);
 
+  static network::mojom::RequestDestination DetermineRequestDestination(
+      ResourceType);
+
   void UpdateAllImageResourcePriorities();
 
   // Returns whether the given resource is contained as a preloaded resource.
@@ -237,6 +240,7 @@
   void EmulateLoadStartedForInspector(Resource*,
                                       const KURL&,
                                       mojom::RequestContextType,
+                                      network::mojom::RequestDestination,
                                       const AtomicString& initiator_name);
 
   // This is called from leak detectors (Real-world leak detector & web test
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
index fa5cd0a..4a07d2eb 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -69,13 +69,13 @@
       requestor_id_(0),
       previews_state_(WebURLRequest::kPreviewsUnspecified),
       request_context_(mojom::RequestContextType::UNSPECIFIED),
+      destination_(network::mojom::RequestDestination::kEmpty),
       mode_(network::mojom::RequestMode::kNoCors),
       fetch_importance_mode_(mojom::FetchImportanceMode::kImportanceAuto),
       credentials_mode_(network::mojom::CredentialsMode::kInclude),
       redirect_mode_(network::mojom::RedirectMode::kFollow),
       referrer_string_(Referrer::ClientReferrerString()),
       referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
-      did_set_http_referrer_(false),
       is_external_request_(false),
       cors_preflight_policy_(
           network::mojom::CorsPreflightPolicy::kConsiderPreflight),
@@ -101,9 +101,8 @@
   request->SetSiteForCookies(new_site_for_cookies);
   String referrer =
       new_referrer.IsEmpty() ? Referrer::NoReferrer() : String(new_referrer);
-  // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
-  // header and instead use a separate member. See https://crbug.com/850813.
-  request->SetHttpReferrer(Referrer(referrer, new_referrer_policy));
+  request->SetReferrerString(referrer);
+  request->SetReferrerPolicy(new_referrer_policy);
   request->SetSkipServiceWorker(skip_service_worker);
   request->SetRedirectStatus(RedirectStatus::kFollowedRedirect);
 
@@ -221,21 +220,6 @@
   http_header_fields_.Set(name, value);
 }
 
-void ResourceRequest::SetHttpReferrer(const Referrer& referrer) {
-  if (referrer.referrer.IsEmpty())
-    http_header_fields_.Remove(http_names::kReferer);
-  else
-    SetHttpHeaderField(http_names::kReferer, referrer.referrer);
-  referrer_policy_ = referrer.referrer_policy;
-  did_set_http_referrer_ = true;
-}
-
-void ResourceRequest::ClearHTTPReferrer() {
-  http_header_fields_.Remove(http_names::kReferer);
-  referrer_policy_ = network::mojom::ReferrerPolicy::kDefault;
-  did_set_http_referrer_ = false;
-}
-
 void ResourceRequest::SetHTTPOrigin(const SecurityOrigin* origin) {
   SetHttpHeaderField(http_names::kOrigin, origin->ToAtomicString());
 }
@@ -251,9 +235,7 @@
 
 void ResourceRequest::SetHTTPOriginToMatchReferrerIfNeeded() {
   if (NeedsHTTPOrigin()) {
-    SetHTTPOrigin(
-        SecurityOrigin::CreateFromString(HttpHeaderField(http_names::kReferer))
-            .get());
+    SetHTTPOrigin(SecurityOrigin::CreateFromString(ReferrerString()).get());
   }
 }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index 4148460..a3b4c6c0 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -52,7 +52,6 @@
 namespace blink {
 
 class EncodedFormData;
-struct Referrer;
 
 // A ResourceRequest is a "request" object for ResourceLoader. Conceptually
 // it is https://fetch.spec.whatwg.org/#concept-request, but it contains
@@ -151,16 +150,6 @@
     SetHttpHeaderField(http_names::kContentType, http_content_type);
   }
 
-  // TODO(domfarolino): Remove this once we stop storing the generated referrer
-  // as a header, and instead use a separate member. See
-  // https://crbug.com/850813.
-  const AtomicString& HttpReferrer() const {
-    return HttpHeaderField(http_names::kReferer);
-  }
-  void SetHttpReferrer(const Referrer&);
-  bool DidSetHttpReferrer() const { return did_set_http_referrer_; }
-  void ClearHTTPReferrer();
-
   void SetReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy) {
     referrer_policy_ = referrer_policy;
   }
@@ -281,6 +270,13 @@
     request_context_ = context;
   }
 
+  network::mojom::RequestDestination GetRequestDestination() const {
+    return destination_;
+  }
+  void SetRequestDestination(network::mojom::RequestDestination destination) {
+    destination_ = destination;
+  }
+
   network::mojom::RequestMode GetMode() const { return mode_; }
   void SetMode(network::mojom::RequestMode mode) { mode_ = mode; }
 
@@ -494,6 +490,7 @@
   WebURLRequest::PreviewsState previews_state_;
   scoped_refptr<SharableExtraData> sharable_extra_data_;
   mojom::RequestContextType request_context_;
+  network::mojom::RequestDestination destination_;
   network::mojom::RequestMode mode_;
   mojom::FetchImportanceMode fetch_importance_mode_;
   network::mojom::CredentialsMode credentials_mode_;
@@ -501,7 +498,6 @@
   String fetch_integrity_;
   String referrer_string_;
   network::mojom::ReferrerPolicy referrer_policy_;
-  bool did_set_http_referrer_;
   bool is_external_request_;
   network::mojom::CorsPreflightPolicy cors_preflight_policy_;
   RedirectStatus redirect_status_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
index ffb5fbc..cde5b01 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
@@ -33,7 +33,7 @@
   std::unique_ptr<ResourceRequest> redirect_request =
       original.CreateRedirectRequest(
           KURL("https://example.test/redirect"), original.HttpMethod(),
-          original.SiteForCookies(), original.HttpReferrer(),
+          original.SiteForCookies(), original.ReferrerString(),
           original.GetReferrerPolicy(), original.GetSkipServiceWorker());
   EXPECT_TRUE(redirect_request->IsAdResource());
 }
@@ -48,7 +48,7 @@
   std::unique_ptr<ResourceRequest> redirect_request =
       original.CreateRedirectRequest(
           KURL("https://example.test/redirect"), original.HttpMethod(),
-          original.SiteForCookies(), original.HttpReferrer(),
+          original.SiteForCookies(), original.ReferrerString(),
           original.GetReferrerPolicy(), original.GetSkipServiceWorker());
   EXPECT_TRUE(redirect_request->UpgradeIfInsecure());
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
index f5aebce..5829e0c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
@@ -25,6 +25,7 @@
   resource_loader_options.initiator_info.name = "script";
   FetchParameters params(resource_request, resource_loader_options);
   params.SetRequestContext(mojom::RequestContextType::SCRIPT);
+  params.SetRequestDestination(network::mojom::RequestDestination::kScript);
 
   // Step 1. ... and CORS setting. [spec text]
   if (cross_origin != kCrossOriginAttributeNotSet)
diff --git a/third_party/blink/renderer/platform/network/http_names.json5 b/third_party/blink/renderer/platform/network/http_names.json5
index 248c5e8..71e696a 100644
--- a/third_party/blink/renderer/platform/network/http_names.json5
+++ b/third_party/blink/renderer/platform/network/http_names.json5
@@ -51,7 +51,6 @@
     "Ping-To",
     "Pragma",
     "Range",
-    // TODO(domfarolino): Remove "Referer" as part of https://crbug.com/850813.
     "Referer",
     "Referrer-Policy",
     "Refresh",
diff --git a/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc b/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
index d26f6d7a..aab5cf3 100644
--- a/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
@@ -7,8 +7,6 @@
 PollableThreadSafeFlag::PollableThreadSafeFlag(base::Lock* write_lock_)
     : flag_(false), write_lock_(write_lock_) {}
 
-PollableThreadSafeFlag::~PollableThreadSafeFlag() = default;
-
 void PollableThreadSafeFlag::SetWhileLocked(bool value) {
   write_lock_->AssertAcquired();
   base::subtle::Release_Store(&flag_, value);
diff --git a/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h b/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
index a78dc2b..1fdd4a2e 100644
--- a/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
+++ b/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
@@ -21,7 +21,6 @@
 
  public:
   explicit PollableThreadSafeFlag(base::Lock* write_lock);
-  ~PollableThreadSafeFlag();
 
   // Set the flag. May only be called if |write_lock| is held.
   void SetWhileLocked(bool value);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
index 361b57e..a9cba7913 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
@@ -11,7 +11,6 @@
     : pending_input_event_count_(0),
       is_gesture_active_(false),
       is_gesture_expected_(false) {}
-UserModel::~UserModel() = default;
 
 void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type,
                                              const base::TimeTicks now) {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
index e29de4b..5acf50d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
@@ -21,7 +21,6 @@
 
  public:
   UserModel();
-  ~UserModel();
 
   // Tells us that the system started processing an input event. Must be paired
   // with a call to DidFinishProcessingInputEvent.
diff --git a/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h b/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
index 17c9a3b..ab1b52d 100644
--- a/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
+++ b/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_PENDING_USER_INPUT_TYPE_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_PENDING_USER_INPUT_TYPE_H_
 
+#include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h b/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
index 143b058..4e9bd56 100644
--- a/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
+++ b/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
@@ -76,7 +76,7 @@
     Free(ptr);  // Not the system free, the one from this class.
   }
 
-  static void TraceMarkedBackingStore(void*) {}
+  static void TraceBackingStoreIfMarked(void*) {}
   static void BackingWriteBarrier(void*) {}
   template <typename>
   static void BackingWriteBarrierForHashTable(void*) {}
diff --git a/third_party/blink/renderer/platform/wtf/hash_table.h b/third_party/blink/renderer/platform/wtf/hash_table.h
index 9e56df2..d198f512 100644
--- a/third_party/blink/renderer/platform/wtf/hash_table.h
+++ b/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -945,6 +945,22 @@
   void ClearEnqueued() { queue_flag_ = false; }
   bool Enqueued() { return queue_flag_; }
 
+  // Constructor for hash tables with raw storage.
+  struct RawStorageTag {};
+  HashTable(RawStorageTag, ValueType* table, unsigned size)
+      : table_(table),
+        table_size_(size),
+        key_count_(0),
+        deleted_count_(0),
+        queue_flag_(0)
+#if DCHECK_IS_ON()
+        ,
+        access_forbidden_(0),
+        modifications_(0)
+#endif
+  {
+  }
+
   ValueType* table_;
   unsigned table_size_;
   unsigned key_count_;
@@ -1753,10 +1769,6 @@
   }
   new_entry = RehashTo(original_table, new_table_size, new_entry);
 
-  EnterAccessForbiddenScope();
-  DeleteAllBucketsAndDeallocate(temporary_table, old_table_size);
-  LeaveAccessForbiddenScope();
-
   return new_entry;
 }
 
@@ -1770,41 +1782,50 @@
 Value*
 HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
     RehashTo(ValueType* new_table, unsigned new_table_size, Value* entry) {
-  unsigned old_table_size = table_size_;
-  ValueType* old_table = table_;
-
 #if DUMP_HASHTABLE_STATS
-  if (old_table_size != 0) {
+  if (table_size_ != 0) {
     HashTableStats::instance().numRehashes.fetch_add(1,
                                                      std::memory_order_relaxed);
   }
 #endif
 
 #if DUMP_HASHTABLE_STATS_PER_TABLE
-  if (old_table_size != 0)
+  if (table_size_ != 0)
     stats_->numRehashes.fetch_add(1, std::memory_order_relaxed);
 #endif
 
-  AsAtomicPtr(&table_)->store(new_table, std::memory_order_relaxed);
-  Allocator::template BackingWriteBarrierForHashTable<HashTable>(new_table);
-  table_size_ = new_table_size;
+  HashTable new_hash_table(RawStorageTag{}, new_table, new_table_size);
 
   Value* new_entry = nullptr;
-  for (unsigned i = 0; i != old_table_size; ++i) {
-    if (IsEmptyOrDeletedBucket(old_table[i])) {
-      DCHECK_NE(&old_table[i], entry);
+  for (unsigned i = 0; i != table_size_; ++i) {
+    if (IsEmptyOrDeletedBucket(table_[i])) {
+      DCHECK_NE(&table_[i], entry);
       continue;
     }
-    Value* reinserted_entry = Reinsert(std::move(old_table[i]));
-    if (&old_table[i] == entry) {
+    Value* reinserted_entry = new_hash_table.Reinsert(std::move(table_[i]));
+    if (&table_[i] == entry) {
       DCHECK(!new_entry);
       new_entry = reinserted_entry;
     }
   }
-  // Rescan the contents of the backing store as no write barriers were emitted
-  // during re-insertion. Traits::NeedsToForbidGCOnMove ensures that no
-  // garbage collection is triggered during moving.
-  Allocator::TraceMarkedBackingStore(new_table);
+
+  Allocator::TraceBackingStoreIfMarked(new_hash_table.table_);
+
+  ValueType* old_table = table_;
+  unsigned old_table_size = table_size_;
+
+  // This swaps the newly allocated buffer with the current one. The store to
+  // the current table has to be atomic to prevent races with concurrent marker.
+  AsAtomicPtr(&table_)->store(new_hash_table.table_, std::memory_order_relaxed);
+  Allocator::template BackingWriteBarrierForHashTable<HashTable>(table_);
+  table_size_ = new_table_size;
+
+  new_hash_table.table_ = old_table;
+  new_hash_table.table_size_ = old_table_size;
+
+  // Explicitly clear since garbage collected HashTables don't do this on
+  // destruction.
+  new_hash_table.clear();
 
   deleted_count_ = 0;
 
@@ -1827,7 +1848,6 @@
 HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
     Rehash(unsigned new_table_size, Value* entry) {
   unsigned old_table_size = table_size_;
-  ValueType* old_table = table_;
 
 #if DUMP_HASHTABLE_STATS
   if (old_table_size != 0) {
@@ -1854,10 +1874,6 @@
   ValueType* new_table = AllocateTable(new_table_size);
   Value* new_entry = RehashTo(new_table, new_table_size, entry);
 
-  EnterAccessForbiddenScope();
-  DeleteAllBucketsAndDeallocate(old_table, old_table_size);
-  LeaveAccessForbiddenScope();
-
   return new_entry;
 }
 
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index cc2c79b..ca7c16e2 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -229,6 +229,7 @@
 
             # Chromium geometry types.
             'gfx::Point',
+            'gfx::PointF',
             'gfx::Point3F',
             'gfx::Quaternion',
             'gfx::Rect',
diff --git a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item
index adf2878..f2200b8 100644
--- a/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item
+++ b/third_party/blink/web_tests/FlagExpectations/layout-ng-fragment-item
@@ -124,7 +124,7 @@
 crbug.com/982194 external/wpt/css/filter-effects/filtered-inline-applies-to-float.html [ Failure ]
 crbug.com/982194 external/wpt/css/filter-effects/filtered-inline-is-container.html [ Failure ]
 crbug.com/846656 external/wpt/css/selectors/focus-visible-002-manual.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin.html [ Failure Pass ]
+crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin.html [ Failure ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/descriptor-fallback-invalid.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/descriptor-fallback.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/descriptor-negative-invalid.html [ Pass ]
@@ -275,15 +275,15 @@
 crbug.com/982194 fast/dom/nodesFromRect/nodesFromRect-links-and-text.html [ Failure ]
 crbug.com/982194 fast/dom/shadow/hover-active-drag-distributed-nodes.html [ Failure ]
 crbug.com/982194 fast/dom/shadow/touch-event.html [ Failure ]
-crbug.com/874695 fast/events/autoscroll-iframe-no-scrolling.html [ Pass ]
-crbug.com/982194 fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
+crbug.com/874695 fast/events/autoscroll-iframe-no-scrolling.html [ Pass Timeout ]
+crbug.com/982194 fast/events/autoscroll-should-not-stop-on-keypress.html [ Crash Failure ]
 crbug.com/982194 fast/events/content-changed-during-drop.html [ Failure ]
 crbug.com/663847 fast/events/context-no-deselect.html [ Pass ]
 crbug.com/982194 fast/events/drag-in-frames.html [ Failure ]
 crbug.com/346473 fast/events/drag-on-mouse-move-cancelled.html [ Failure ]
 crbug.com/982194 fast/events/drag_and_drop_into_removed_on_focus.html [ Failure ]
 crbug.com/982194 fast/events/event-on-culled-inline-with-pseudo.html [ Failure ]
-crbug.com/874695 fast/events/frame-detached-in-mousedown.html [ Pass ]
+crbug.com/874695 fast/events/frame-detached-in-mousedown.html [ Pass Timeout ]
 crbug.com/982194 fast/events/middleClickAutoscroll-click-hyperlink.html [ Failure ]
 crbug.com/982194 fast/events/open-window-from-another-frame.html [ Timeout ]
 crbug.com/982194 fast/events/pointerevents/mouse-node-remove.html [ Failure ]
@@ -311,7 +311,6 @@
 crbug.com/982194 fast/forms/label/label-selection-by-dragging.html [ Failure ]
 crbug.com/982194 fast/forms/label/label-selection-by-textSelection-and-click.html [ Failure ]
 crbug.com/874695 fast/forms/number/number-spinbutton-gets-disabled-or-readonly.html [ Pass ]
-crbug.com/982194 fast/history/visited-link-hover-outline-color.html [ Crash Pass ]
 crbug.com/982194 fast/html/draggable-controls.html [ Failure ]
 crbug.com/982194 fast/inline/inline-box-background-long-image.html [ Failure ]
 crbug.com/982194 fast/inline/inline-box-background-repeat-x.html [ Failure ]
@@ -333,7 +332,7 @@
 crbug.com/982194 fast/scrolling/scrollable-area-frame-overried-inherited-visibility-hidden.html [ Failure ]
 crbug.com/982194 fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ]
 crbug.com/982194 fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ]
-crbug.com/982194 fast/scrolling/scrollable-area-frame.html [ Crash Failure ]
+crbug.com/982194 fast/scrolling/scrollable-area-frame.html [ Failure ]
 crbug.com/889952 fast/selectors/selection-window-inactive.html [ Pass ]
 crbug.com/591099 fast/selectors/shadow-host-div-with-span.html [ Failure ]
 crbug.com/591099 fast/selectors/shadow-host-div-with-text.html [ Failure ]
@@ -373,10 +372,10 @@
 crbug.com/451577 crbug.com/916975 http/tests/devtools/console/console-repeat-count.js [ Crash Failure Pass Timeout ]
 crbug.com/451577 http/tests/devtools/console/console-search.js [ Pass ]
 crbug.com/967526 http/tests/devtools/console/console-uncaught-promise.js [ Pass ]
-crbug.com/982194 http/tests/devtools/coverage/decorations-after-script-formatter.js [ Pass Timeout ]
-crbug.com/678482 http/tests/devtools/debugger/fetch-breakpoints.js [ Pass ]
+crbug.com/982194 http/tests/devtools/coverage/decorations-after-script-formatter.js [ Failure Pass Timeout ]
+crbug.com/678482 http/tests/devtools/debugger/fetch-breakpoints.js [ Pass Timeout ]
 crbug.com/846997 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Pass Timeout ]
-crbug.com/850358 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Pass ]
+crbug.com/850358 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Pass Timeout ]
 crbug.com/846982 crbug.com/874695 http/tests/devtools/editor/text-editor-formatter.js [ Crash Pass Timeout ]
 crbug.com/420008 crbug.com/749738 http/tests/devtools/editor/text-editor-word-jumps.js [ Crash Pass Timeout ]
 crbug.com/596486 http/tests/devtools/elements/insert-node.js [ Pass ]
@@ -388,7 +387,7 @@
 crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Pass ]
 crbug.com/528419 http/tests/devtools/elements/styles-2/pseudo-elements.js [ Pass ]
 crbug.com/959002 crbug.com/959042 http/tests/devtools/elements/styles-3/style-autocomplete.js [ Crash Pass Timeout ]
-crbug.com/938884 http/tests/devtools/elements/styles-3/styles-add-blank-property.js [ Pass Timeout ]
+crbug.com/938884 http/tests/devtools/elements/styles-3/styles-add-blank-property.js [ Timeout ]
 crbug.com/945665 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Failure ]
 crbug.com/945665 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Failure Timeout ]
 crbug.com/945665 http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Failure ]
@@ -396,7 +395,7 @@
 crbug.com/959002 crbug.com/959042 http/tests/devtools/elements/styles-3/styles-variables.js [ Crash Pass Timeout ]
 crbug.com/667560 http/tests/devtools/elements/styles-4/inline-style-sourcemap.js [ Failure Pass ]
 crbug.com/959002 crbug.com/959042 http/tests/devtools/elements/styles-4/styles-keyframes.js [ Crash Pass Timeout ]
-crbug.com/946714 http/tests/devtools/elements/styles-4/styles-live-locations-leak.js [ Pass Timeout ]
+crbug.com/946714 http/tests/devtools/elements/styles-4/styles-live-locations-leak.js [ Timeout ]
 crbug.com/982116 http/tests/devtools/elements/styles-4/styles-new-API.js [ Pass Timeout ]
 crbug.com/849978 http/tests/devtools/elements/styles-4/stylesheet-source-url-comment.js [ Pass Timeout ]
 crbug.com/959002 crbug.com/959042 http/tests/devtools/elements/styles-4/undo-add-new-rule.js [ Crash Pass Timeout ]
@@ -416,7 +415,7 @@
 crbug.com/818076 http/tests/devtools/oopif/oopif-elements-navigate-in.js [ Pass ]
 crbug.com/874695 http/tests/devtools/persistence/persistence-mimetype-on-rename.js [ Pass ]
 crbug.com/450493 crbug.com/971262 http/tests/devtools/profiler/live-line-level-heap-profile.js [ Crash Pass Timeout ]
-crbug.com/831673 http/tests/devtools/reveal-objects.js [ Pass Timeout ]
+crbug.com/831673 http/tests/devtools/reveal-objects.js [ Timeout ]
 crbug.com/849670 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass Timeout ]
 crbug.com/874695 crbug.com/954319 http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-in-multiple-workers.js [ Crash Pass Timeout ]
 crbug.com/874695 http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-shifted-breakpoint.js [ Pass ]
@@ -434,7 +433,7 @@
 crbug.com/851363 http/tests/devtools/sxg/sxg-prefetch.js [ Pass ]
 crbug.com/420008 crbug.com/916975 http/tests/devtools/tracing/timeline-misc/timeline-event-causes.js [ Crash Failure Pass Timeout ]
 crbug.com/982194 http/tests/input/discard-events-to-unstable-iframe.html [ Failure ]
-crbug.com/982194 http/tests/inspector-protocol/target/target-expose-devtools-protocol.js [ Failure Timeout ]
+crbug.com/982194 http/tests/inspector-protocol/target/target-expose-devtools-protocol.js [ Failure ]
 crbug.com/982194 http/tests/media/video-frame-size-change.html [ Failure ]
 crbug.com/24182 http/tests/misc/acid3.html [ Pass ]
 crbug.com/874695 http/tests/misc/drag-not-loaded-image.html [ Pass ]
@@ -457,7 +456,7 @@
 crbug.com/942951 media/controls/controls-layout-in-different-size.html [ Pass ]
 crbug.com/982194 media/picture-in-picture/v2/detached-iframe.html [ Failure Pass Timeout ]
 crbug.com/982194 media/picture-in-picture/v2/request-picture-in-picture-twice.html [ Failure ]
-crbug.com/982194 media/picture-in-picture/v2/request-picture-in-picture.html [ Failure Pass Timeout ]
+crbug.com/982194 media/picture-in-picture/v2/request-picture-in-picture.html [ Failure Timeout ]
 crbug.com/874695 media/remoteplayback/prompt-twice-throws.html [ Pass ]
 crbug.com/982194 overflow/overflow-inline-002.html [ Failure ]
 crbug.com/982194 overflow/overflow-inline-003.html [ Failure ]
@@ -504,14 +503,13 @@
 crbug.com/982194 paint/invalidation/offset-change-wrong-invalidation-with-float.html [ Failure ]
 crbug.com/982194 paint/invalidation/outline/focus-continuations.html [ Failure ]
 crbug.com/982194 paint/invalidation/outline/focus-enable-continuations.html [ Failure ]
-crbug.com/982194 paint/invalidation/outline/focus-ring-continuation-move-crash.html [ Crash Pass ]
 crbug.com/982194 paint/invalidation/outline/focus-ring-on-child-move.html [ Failure ]
-crbug.com/982194 paint/invalidation/outline/focus-ring-on-continuation-move.html [ Crash Failure ]
-crbug.com/982194 paint/invalidation/outline/focus-ring-on-inline-continuation-move.html [ Crash Failure ]
+crbug.com/982194 paint/invalidation/outline/focus-ring-on-continuation-move.html [ Failure ]
+crbug.com/982194 paint/invalidation/outline/focus-ring-on-inline-continuation-move.html [ Failure ]
 crbug.com/835484 paint/invalidation/outline/inline-focus.html [ Failure ]
 crbug.com/982194 paint/invalidation/outline/inline-outline-repaint-2.html [ Failure ]
 crbug.com/982194 paint/invalidation/outline/outline-change-invalidation.html [ Failure ]
-crbug.com/982194 paint/invalidation/outline/outline-containing-image-in-non-standard-mode.html [ Crash Failure ]
+crbug.com/982194 paint/invalidation/outline/outline-containing-image-in-non-standard-mode.html [ Failure ]
 crbug.com/982194 paint/invalidation/outline/outline-continuations.html [ Failure ]
 crbug.com/982194 paint/invalidation/overflow/float-overflow-right.html [ Failure ]
 crbug.com/982194 paint/invalidation/overflow/float-overflow.html [ Failure ]
@@ -520,7 +518,6 @@
 crbug.com/982194 paint/invalidation/overflow/inline-vertical-rl-overflow.html [ Failure ]
 crbug.com/982194 paint/invalidation/overflow/line-overflow.html [ Failure ]
 crbug.com/982194 paint/invalidation/overflow/negative-text-indent-with-overflow-hidden.html [ Failure ]
-crbug.com/982194 paint/invalidation/overflow/overflow-outline-repaint.html [ Crash Pass ]
 crbug.com/982194 paint/invalidation/paint-invalidation-with-reparent-across-frame-boundaries.html [ Failure ]
 crbug.com/982194 paint/invalidation/position/abspos-shift-image-incorrect-repaint.html [ Failure ]
 crbug.com/982194 paint/invalidation/position/inline-relative-positioned.html [ Failure ]
@@ -616,7 +613,7 @@
 crbug.com/942951 virtual/audio-service/media/controls/controls-layout-in-different-size.html [ Pass ]
 crbug.com/982194 virtual/audio-service/media/picture-in-picture/v2/detached-iframe.html [ Failure Pass ]
 crbug.com/982194 virtual/audio-service/media/picture-in-picture/v2/request-picture-in-picture-twice.html [ Failure ]
-crbug.com/982194 virtual/audio-service/media/picture-in-picture/v2/request-picture-in-picture.html [ Failure ]
+crbug.com/982194 virtual/audio-service/media/picture-in-picture/v2/request-picture-in-picture.html [ Failure Pass ]
 crbug.com/874695 virtual/audio-service/media/remoteplayback/prompt-twice-throws.html [ Pass ]
 crbug.com/982194 virtual/audio-service/media/stable/video-object-fit-stable.html [ Pass ]
 crbug.com/982194 virtual/cache-storage-sequence/external/wpt/service-workers/service-worker/udate-bytecheck.https.html [ Timeout ]
@@ -799,6 +796,7 @@
 crbug.com/982194 external/wpt/css/css-pseudo/marker-content-009.tentative.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-pseudo/marker-content-010.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-pseudo/marker-content-011.tentative.html [ Pass ]
+crbug.com/982194 external/wpt/css/css-pseudo/marker-content-014.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-pseudo/marker-font-variant-numeric-normal.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-pseudo/marker-list-style-position.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-scrollbars/textarea-scrollbar-width-none.html [ Pass ]
@@ -914,8 +912,6 @@
 crbug.com/982194 external/wpt/css/css-writing-modes/text-combine-upright-value-all-002.html [ Pass ]
 crbug.com/982194 external/wpt/css/css-writing-modes/text-combine-upright-value-all-003.html [ Pass ]
 crbug.com/982194 external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Pass ]
-crbug.com/982194 external/wpt/css/filter-effects/backdrop-filter-containing-block.html [ Pass ]
-crbug.com/982194 external/wpt/css/filter-effects/backdrop-filter-zero-size.html [ Pass ]
 crbug.com/982194 external/wpt/css/filter-effects/css-filters-animation-combined-001.html [ Pass ]
 crbug.com/982194 external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Pass ]
 crbug.com/982194 external/wpt/css/mediaqueries/viewport-script-dynamic.html [ Pass ]
@@ -933,22 +929,6 @@
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-content-rtl-002.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-content-vertWM-001.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-content-vertWM-002.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-001.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-002.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-003.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-004.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-005.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-006.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-007.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-008.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-rtl-001.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-rtl-002.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-rtl-003.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-rtl-004.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-vertWM-001.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-vertWM-002.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-vertWM-003.html [ Pass ]
-crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-align-self-vertWM-004.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-fallback-align-content-001.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-justify-content-001.html [ Pass ]
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/flex-abspos-staticpos-justify-content-002.html [ Pass ]
@@ -1066,15 +1046,8 @@
 crbug.com/982194 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-006a.html [ Pass ]
 crbug.com/982194 external/wpt/encoding/eof-utf-8-three.html [ Pass ]
 crbug.com/982194 external/wpt/encoding/eof-utf-8-two.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-05.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-14.html [ Pass ]
-crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-17.html [ Pass ]
 crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-19.html [ Failure ]
-crbug.com/982194 external/wpt/forced-colors-mode/forced-colors-mode-23.html [ Pass ]
-crbug.com/982194 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ]
+crbug.com/982194 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ]
 crbug.com/982194 external/wpt/html/rendering/non-replaced-elements/tables/table-border-1.html [ Pass ]
 crbug.com/982194 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Failure ]
 crbug.com/982194 external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Failure ]
@@ -1183,7 +1156,7 @@
 crbug.com/982194 external/wpt/mathml/relations/html5-tree/integration-point-2.html [ Pass ]
 crbug.com/982194 external/wpt/mathml/relations/html5-tree/integration-point-3.html [ Pass ]
 crbug.com/982194 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Pass ]
-crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.window.html [ Crash Pass ]
+crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage-BroadcastChannel.tentative.https.window.html [ Crash ]
 crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage-MessagePort.tentative.https.window.html [ Crash ]
 crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemBaseHandle-postMessage.tentative.https.window.html [ Crash ]
 crbug.com/982194 external/wpt/native-file-system/sandboxed_FileSystemDirectoryHandle-getEntries.tentative.https.any.html [ Crash Pass ]
@@ -1210,9 +1183,6 @@
 crbug.com/982194 external/wpt/svg/text/reftests/text-inline-size-003.svg [ Pass ]
 crbug.com/982194 external/wpt/svg/text/reftests/text-multiline-003.svg [ Pass ]
 crbug.com/982194 external/wpt/svg/text/reftests/text-xml-space-001.svg [ Pass ]
-crbug.com/982194 external/wpt/trusted-types/eval-csp-no-tt.tentative.html [ Pass ]
-crbug.com/982194 external/wpt/trusted-types/eval-no-csp-no-tt-default-policy.tentative.html [ Pass ]
-crbug.com/982194 external/wpt/trusted-types/eval-no-csp-no-tt.tentative.html [ Pass ]
 crbug.com/982194 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html [ Pass ]
 crbug.com/982194 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html [ Pass ]
 crbug.com/982194 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_tracks.html [ Pass ]
@@ -1435,7 +1405,7 @@
 crbug.com/982194 http/tests/devtools/application-panel/storage-view-reports-quota.js [ Pass Timeout ]
 crbug.com/982194 http/tests/devtools/elements/edit/edit-dom-actions-2.js [ Pass Timeout ]
 crbug.com/982194 http/tests/devtools/elements/highlight/highlight-dom-updates.js [ Pass Timeout ]
-crbug.com/982194 http/tests/devtools/elements/styles-4/styles-update-from-js.js [ Timeout ]
+crbug.com/982194 http/tests/devtools/elements/styles-4/styles-update-from-js.js [ Failure Timeout ]
 crbug.com/982194 http/tests/devtools/indexeddb/database-refresh-view.js [ Pass ]
 crbug.com/982194 http/tests/devtools/oopif/oopif-storage.js [ Pass ]
 crbug.com/982194 http/tests/devtools/profiler/heap-snapshot-location.js [ Pass ]
@@ -1448,7 +1418,7 @@
 crbug.com/982194 http/tests/devtools/service-workers/service-worker-agents.js [ Pass ]
 crbug.com/982194 http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js [ Pass ]
 crbug.com/982194 http/tests/devtools/service-workers/service-workers-redundant.js [ Pass ]
-crbug.com/982194 http/tests/devtools/service-workers/user-agent-override.js [ Pass ]
+crbug.com/982194 http/tests/devtools/service-workers/user-agent-override.js [ Pass Timeout ]
 crbug.com/982194 http/tests/devtools/sources/debugger/navigator-view.js [ Crash Pass ]
 crbug.com/982194 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Pass ]
 crbug.com/982194 http/tests/intersection-observer/cross-origin-display-none.html [ Crash Pass ]
@@ -1460,7 +1430,7 @@
 crbug.com/982194 jquery/data.html [ Pass ]
 crbug.com/982194 jquery/dimensions.html [ Pass ]
 crbug.com/982194 jquery/event.html [ Pass ]
-crbug.com/982194 jquery/manipulation.html [ Pass ]
+crbug.com/982194 jquery/manipulation.html [ Pass Timeout ]
 crbug.com/982194 jquery/offset.html [ Pass ]
 crbug.com/982194 jquery/traversing.html [ Pass ]
 crbug.com/982194 media/video-canvas-draw.html [ Crash Failure ]
@@ -1475,17 +1445,22 @@
 crbug.com/982194 svg/custom/visibility-enable-on-svg-element.html [ Failure ]
 crbug.com/982194 virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure ]
 crbug.com/982194 virtual/audio-service/media/video-canvas-draw.html [ Failure ]
-crbug.com/982194 virtual/composite-after-paint/compositing/gestures/gesture-tapHighlight-simple-scaledY.html [ Pass ]
 crbug.com/982194 virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/file/file-appearance-basic.html [ Failure ]
 crbug.com/982194 virtual/controls-refresh/color-scheme/file/file-appearance-basic.html [ Failure ]
 crbug.com/982194 virtual/exotic-color-space/images/55.html [ Failure ]
 crbug.com/982194 virtual/exotic-color-space/images/yuv-decode-eligible/color-profile-layer-filter.html [ Failure ]
 crbug.com/985520 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest-a11y.html [ Pass ]
 crbug.com/985520 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-enter-from-interest.html [ Pass ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html [ Failure ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html [ Failure ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html [ Failure ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html [ Failure ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html [ Failure ]
+crbug.com/982194 virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html [ Failure ]
 crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html [ Failure ]
 crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html [ Failure ]
 crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html [ Failure ]
-crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html [ Crash Failure ]
+crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html [ Failure ]
 crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html [ Failure ]
 crbug.com/982194 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html [ Failure ]
 crbug.com/982194 virtual/gpu-rasterization/images/55.html [ Failure ]
@@ -1550,8 +1525,7 @@
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-add-002.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-add-003.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-add-004.html [ Pass ]
-crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-add-007.html [ Crash Pass ]
-crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-remove-004.html [ Crash Pass ]
+crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-dynamic-add-007.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-rule-001.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-004.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-005.html [ Pass ]
@@ -1650,7 +1624,7 @@
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/abspos-auto-position-on-line.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/abspos-auto-position-small-on-line-at-boundary.html [ Pass ]
 crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/nested-multicol.html [ Pass ]
-crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/outlines-at-column-boundaries.html [ Crash Pass ]
+crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/outlines-at-column-boundaries.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/fast/multicol/overflow-across-columns.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/fast/multicol/overflow-content.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_block_frag/fast/multicol/overflow-unsplittable.html [ Pass ]
@@ -1743,7 +1717,7 @@
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/css-contain/quote-scoping-003.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/css-contain/quote-scoping-004.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-ignored-cases-ruby-stacking-and-clipping-001.html [ Pass ]
-crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-stacking-context-001b.html [ Pass ]
+crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-stacking-context-001b.html [ Crash Pass ]
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-fieldset-002.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-flex-001.html [ Pass ]
 crbug.com/982194 virtual/layout_ng_fieldset/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-inline-flex-001.html [ Pass ]
@@ -1816,8 +1790,6 @@
 crbug.com/982194 virtual/scalefactor200/css3/filters/effect-blur-hw.html [ Pass ]
 crbug.com/982194 virtual/scalefactor200/css3/filters/filterRegions.html [ Pass ]
 crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Pass ]
-crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-containing-block.html [ Pass ]
-crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-zero-size.html [ Pass ]
 crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/css-filters-animation-combined-001.html [ Pass ]
 crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Pass ]
 crbug.com/982194 virtual/scalefactor200/external/wpt/css/filter-effects/filtered-inline-is-container.html [ Failure ]
@@ -1870,12 +1842,9 @@
 crbug.com/982194 virtual/stable/http/tests/navigation/ping-cross-origin.html [ Timeout ]
 crbug.com/982194 virtual/stable/http/tests/navigation/ping-same-origin.html [ Timeout ]
 crbug.com/982194 virtual/stable/media/stable/video-object-fit-stable.html [ Pass ]
-crbug.com/982194 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test.html [ Pass ]
-crbug.com/982194 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html [ Pass ]
-crbug.com/982194 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/css-module/utf8.tentative.html [ Pass ]
 crbug.com/874695 virtual/sxg-with-network-service/http/tests/devtools/sxg/sxg-disable-cache.js [ Pass ]
-crbug.com/851363 virtual/sxg-with-network-service/http/tests/devtools/sxg/sxg-prefetch-fail.js [ Failure Pass ]
-crbug.com/851363 virtual/sxg-with-network-service/http/tests/devtools/sxg/sxg-prefetch.js [ Failure Pass ]
+crbug.com/851363 virtual/sxg-with-network-service/http/tests/devtools/sxg/sxg-prefetch-fail.js [ Pass ]
+crbug.com/851363 virtual/sxg-with-network-service/http/tests/devtools/sxg/sxg-prefetch.js [ Pass ]
 crbug.com/982194 virtual/text-antialias/font-format-support-color-cff2-vertical.html [ Pass ]
 crbug.com/982194 virtual/text-antialias/remove-zero-length-run.html [ Failure ]
 crbug.com/982194 virtual/threaded-no-composited-antialiasing/animations/timing/animation-duration-infinite.html [ Failure Pass ]
@@ -1884,6 +1853,7 @@
 crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ]
 crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ]
 crbug.com/982194 virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame.html [ Failure ]
+crbug.com/982194 virtual/threaded/external/wpt/css/css-animations/CSSAnimation-canceling.tentative.html [ Failure Pass ]
 crbug.com/982194 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html [ Pass ]
 crbug.com/982194 virtual/threaded/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html [ Pass ]
 crbug.com/982194 virtual/threaded/fast/scroll-snap/snaps-after-scrollbar-scrolling.html [ Timeout ]
@@ -1916,32 +1886,6 @@
 crbug.com/982194 virtual/web-components-v0-disabled/fast/dom/nodesFromRect/nodesFromRect-inner-documents.html [ Failure ]
 crbug.com/982194 virtual/web-components-v0-disabled/fast/dom/nodesFromRect/nodesFromRect-links-and-text.html [ Failure ]
 crbug.com/982194 virtual/web-components-v0-disabled/fast/dom/shadow/gesture-tapHighlight-shadow-tree.html [ Pass ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/content-changed-during-drop.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/drag-in-frames.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/drag_and_drop_into_removed_on_focus.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/event-on-culled-inline-with-pseudo.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/middleClickAutoscroll-click-hyperlink.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/mouse-relative-position.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/open-window-from-another-frame.html [ Timeout ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-node-remove.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-pointer-capture-transition-events.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-pointer-capture.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-pointer-transition-events.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-pointer-updown-events.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/touch-capture.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/pointerevents/touch-pointer-events.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/selectstart-by-single-click-with-shift.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/shift-drag-selection-on-link-triggers-drag-n-drop.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/simulated-click-coords.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/touch/gesture/gesture-tap-mouse-events-between-frames.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/events/touch/gesture/gesture-tap-mouse-events.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/focus-selection-input.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/focus-selection-textarea.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/huge-mac-input-clamped-width.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/label/label-click.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/label/label-selection-by-dragging.html [ Failure ]
-crbug.com/982194 virtual/web-components-v0-disabled/fast/forms/label/label-selection-by-textSelection-and-click.html [ Failure ]
 crbug.com/982194 virtual/web-components-v0-disabled/fast/html/draggable-controls.html [ Failure ]
 crbug.com/982194 virtual/web-components-v0-disabled/html/sections/body-legacy-colors.html [ Timeout ]
 crbug.com/982194 wpt_internal/css/css-intrinsic-size/intrinsic-size-015.html [ Crash ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations
index 3a6763b..cd60d044 100644
--- a/third_party/blink/web_tests/MSANExpectations
+++ b/third_party/blink/web_tests/MSANExpectations
@@ -187,6 +187,9 @@
 crbug.com/856601 [ Linux ] external/wpt/sms/idlharness.https.any.html [ Pass Timeout ]
 crbug.com/856601 [ Linux ] external/wpt/wake-lock/idlharness.https.any.worker.html [ Pass Timeout ]
 crbug.com/856601 [ Linux ] virtual/omt-worker-fetch/external/wpt/fetch/api/idl.any.sharedworker.html [ Pass Timeout ]
+crbug.com/856601 [ Linux ] external/wpt/trusted-types/idlharness.tentative.window.html [ Pass Timeout ]
+crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.html [ Pass Timeout ]
+crbug.com/856601 [ Linux ] external/wpt/media-playback-quality/idlharness.window.html [ Pass Timeout ]
 
 # Disabled by sheriff due to repeated flakes
 crbug.com/873045 [ Linux ] external/wpt/WebCryptoAPI/idlharness.https.any.worker.html [ Pass Failure Timeout ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index fc15390..888ed48 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -70,6 +70,7 @@
 [ Mac ] fast/forms/select/menulist-onchange-fired-with-key-up-down.html [ Skip ]
 [ Mac ] fast/forms/select/popup-with-display-none-optgroup.html [ Skip ]
 [ Mac ] fast/forms/select-popup [ Skip ]
+[ Mac ] virtual/cascade/fast/forms/select-popup [ Skip ]
 
 # These tests are specific to Windows and Linux.
 [ Mac ] fast/forms/calendar-picker/date-open-picker-with-f4-key.html [ Skip ]
@@ -2133,3 +2134,4 @@
 [ Win ] virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/content-index-origin-trial-interfaces.html [ Skip ]
 [ Linux ] virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/content-index-origin-trial-interfaces.html [ Skip ]
 [ Mac ] virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/content-index-origin-trial-interfaces.html [ Skip ]
+crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_fractional_coordinates-manual.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index be2a62e..5d744cc 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2668,21 +2668,17 @@
 
 crbug.com/1029514 external/wpt/html/semantics/embedded-content/the-video-element/resize-during-playback.html [ Pass Failure ]
 
+# These need WPT fuzzy matching:
+crbug.com/1035194 [ Linux ] external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Failure ]
+crbug.com/1035194 [ Linux ] external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ]
+crbug.com/1035194 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Failure ]
+crbug.com/1035194 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ]
+
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Linux ] external/wpt/css/css-pseudo/marker-content-013.html [ Timeout ]
-crbug.com/626703 [ Mac ] external/wpt/css/css-pseudo/marker-content-013.html [ Timeout ]
-crbug.com/626703 [ Win ] external/wpt/css/css-pseudo/marker-content-013.html [ Timeout ]
+crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-pan-x-css_touch.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/css/motion/offset-anchor-transform-box-fill-box-003.html [ Failure ]
 crbug.com/626703 [ Mac ] external/wpt/css/motion/offset-anchor-transform-box-fill-box-003.html [ Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/motion/offset-anchor-transform-box-fill-box-003.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/css/filter-effects/backdrop-filter-containing-block.html [ Failure ]
-crbug.com/626703 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Failure ]
-crbug.com/626703 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-zero-size.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2.html [ Failure ]
-crbug.com/626703 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/css-filters-animation-opacity.html [ Failure ]
-crbug.com/626703 [ Linux ] virtual/scalefactor200/external/wpt/css/filter-effects/backdrop-filter-containing-block.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/css/filter-effects/backdrop-filter-zero-size.html [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/offscreen-canvas/text/2d.text.measure.width.empty.worker.html [ Timeout ]
 crbug.com/626703 [ Mac ] external/wpt/offscreen-canvas/text/2d.text.measure.width.empty.worker.html [ Timeout ]
 crbug.com/626703 [ Win ] external/wpt/offscreen-canvas/text/2d.text.measure.width.empty.worker.html [ Timeout ]
@@ -3781,6 +3777,7 @@
 
 # Failure due to on-going off-thread paint worklet project.
 crbug.com/957457 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Crash ]
+crbug.com/1034807 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-gradient.https.html [ Failure ]
 
 crbug.com/982116 http/tests/devtools/elements/styles-4/styles-new-API.js [ Pass Timeout ]
 
@@ -4167,8 +4164,6 @@
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/shadowroot-keyframes.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/transition-on-shadow-host-createshadowroot.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/transition-on-shadow-host-with-distributed-node.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/fieldset/fieldset-adoptnode-crash.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/fieldset/fieldset-shadowdom-crash.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/gc-treescope.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/StyleSheet/css-insert-import-rule-to-shadow-stylesheets.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/content-pseudo-element-dynamic-class.html [ Skip ]
@@ -4211,7 +4206,6 @@
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/shadowdom-reprojection-2.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/shadowroot-of-insertionpoint.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/table-border.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/datalist/datalist-inside-shadow-dom.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/shadow-dom/v0/v0-added-after-v1-and-slotted.html [ Skip ]
 
 
@@ -4225,20 +4219,6 @@
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/dom/events/document-level-wheel-event-listener-passive-by-default-manual.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/dom/ranges/Range-compareBoundaryPoints.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/dom/elements/global-attributes/title-manual.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3q.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/tables/table-border-3s.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2i.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2j.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2k.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2l.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/document-metadata/styling/LinkStyle.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html [ Skip ]
@@ -4336,92 +4316,33 @@
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/HTMLImageElement/image-sizes-meta-viewport.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/Window/window-postmessage-clone-deep-array.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/shadow/focus-controller-recursion-crash.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/autoscroll-in-textfield.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/drag-on-mouse-move-cancelled.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/option-tab.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/inputevents/inputevent-yank.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/pointerevents/mouse-pointer-event-properties.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/compositor-touch-hit-rects-continuation.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/compositor-touch-hit-rects-iframes.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/compositor-touch-hit-rects.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/gesture/pad-gesture-cancel.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/gesture/pad-gesture-fling.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/wheel/wheel-fling-cancel.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/autofocus-in-sandbox-with-allow-scripts.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/color/color-suggestion-picker-appearance-zoom200.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/search/search-appearance-basic.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/select-popup/popup-menu-appearance-tall.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/html/marquee/marquee-scroll.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/html/marquee/marquee-scrollamount.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/dom/ranges/Range-set.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/tables/table-border-1.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/color.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/width.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1i.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1j.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1k.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1l.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/widgets/button-layout/anonymous-button-content-box.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/rendering/widgets/button-layout/inline-level.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-after-controls-added.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-non-snap-to-lines.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/forms/the-textarea-element/multiline-placeholder-cr.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-menu.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/context-no-deselect.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/mouse-cursor-change-after-image-load.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/long-text-in-input.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/datalist/input-appearance-range-with-transform.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/parser/residual-style-hang.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/rtl-scroll-to-leftmost-and-resize.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/the-video-element/resize-during-playback.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/touch/multi-touch-user-gesture.html [ Skip ]
-crbug.com/937746 [ Win7 ] virtual/web-components-v0-disabled/fast/forms/suggested-value.html [ Skip ]
 crbug.com/937746 [ Win7 ] virtual/web-components-v0-disabled/external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/text/text-lineheight-centering.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/external/wpt/html/rendering/non-replaced-elements/form-controls/select-sizing-001.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/external/wpt/html/rendering/widgets/button-layout/propagate-text-decoration.html [ Skip ]
 crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/dom/inert/inert-node-is-uneditable.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/touch/gesture/gesture-scroll-by-page.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/touch/gesture/gesture-scrollbar-touchpad-fling.html [ Skip ]
 # These are in NeverFixTests:
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/select-popup [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/select/menulist-onchange-fired-with-key-up-down.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/select/popup-with-display-none-optgroup.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/calendar-picker/date-open-picker-with-f4-key.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/calendar-picker/datetimelocal-open-picker-with-f4-key.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/calendar-picker/month-open-picker-with-f4-key.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/forms/calendar-picker/week-open-picker-with-f4-key.html [ Skip ]
 crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/external/wpt/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html [ Skip ]
 crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/external/wpt/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html [ Skip ]
 crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/external/wpt/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/context-menu-key-shift-f10-modifiers.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/context-menu-key-shift-f10-prevent-default.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/contextmenu-follows-focus.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/menu-key-context-menu-document.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/menu-key-context-menu-position.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/menu-key-context-menu-reveal-focus.html [ Skip ]
-crbug.com/937746 [ Mac ] virtual/web-components-v0-disabled/fast/events/menu-key-context-menu.html [ Skip ]
 
 # Sheriffs, please add any newly discovered flaky tests within
 # the virtual/web-components-v0-disabled suite here:
 ###crbug.com/937746 virtual/web-components-v0-disabled/my/test/here [ Skip ]
 
-crbug.com/937746 virtual/web-components-v0-disabled/fast/events/before-unload-return-value-from-listener.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/semantics/links/following-hyperlinks/activation-behavior.window.html [ Skip ]
-crbug.com/937746 virtual/web-components-v0-disabled/fast/forms/number/number-input-event-composed.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/dom/idlharness.any.serviceworker.html [ Skip ]
 crbug.com/937746 virtual/web-components-v0-disabled/external/wpt/html/dom/idlharness.worker.html [ Skip ]
+crbug.com/937746 virtual/web-components-v0-disabled/fast/dom/gc-acid3.html [ Pass Timeout ]
 
 # ====== End web-components-v0-disabled virtual suite tests ======
 
@@ -6103,6 +6024,11 @@
 crbug.com/1029489 http/tests/devtools/elements/elements-linkify-attributes.js [ Pass Failure ]
 crbug.com/1029826 http/tests/devtools/copy-network-request.js [ Pass Failure ]
 crbug.com/1029521 virtual/threaded/external/wpt/web-animations/timing-model/animations/updating-the-finished-state.html [ Pass Failure Timeout ]
+crbug.com/1030258 http/tests/devtools/components/cookie-parser.js [ Pass Failure ]
+crbug.com/1030258 http/tests/devtools/network/network-cookies-pane.js [ Pass Failure ]
+crbug.com/1027168 http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.js [ Pass Failure ]
+crbug.com/1027168 http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.js [ Pass Failure ]
+crbug.com/1027168 http/tests/devtools/elements/styles-2/inject-stylesheet.js [ Pass Failure ]
 
 # Enable scroll-snap tests on impl thread
 # These are currently failing on Mac which needs more investigation, snap-scrolls-visual-viewport seems flaky
@@ -6116,6 +6042,31 @@
 # Sheriff 2019-12-10
 crbug.com/1032451 virtual/threaded-no-composited-antialiasing/animations/stability/animation-iteration-event-destroy-renderer.html [ Pass Timeout ]
 
+# DevTools
+# Disabled until https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/1969479 lands and rolls into Chromium
+crbug.com/1008910 http/tests/devtools/a11y-axe-core/sources/global-listeners-sidebar-a11y-test.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-call-getter-on-proto.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-dir.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-format-es6.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-format.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-functions.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-log-object-with-getter.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-log-short-hand-method.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/console/console-object-preview.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listener-sidebar-custom-framework.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listener-sidebar.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listener-sidebar-jquery1.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listener-sidebar-jquery2.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listener-sidebar-remove.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listeners-about-blank.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/elements/event-listeners-framework-with-service-worker.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger-pause/set-return-value.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger-ui/debugger-expand-scope.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger/debugger-scope-minified-variables.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/sources/debugger/properties-special.js [ Pass Failure ]
+crbug.com/1008910 http/tests/devtools/startup/console/console-format-startup.js [ Pass Failure ]
 
 # Temporarily disabled for landing changes to front_end/common in DevTools
 crbug.com/1006759 inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Pass Failure ]
@@ -6127,14 +6078,6 @@
 crbug.com/1006759 inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers.js [ Pass Failure ]
 crbug.com/1006759 inspector-protocol/heap-profiler/heap-snapshot-with-no-detached-iframe.js [ Pass Failure ]
 
-# Temporarily disabled for landing datagrid Changes in devtools
-crbug.com/963183 http/tests/devtools/components/datagrid.js [ Pass Failure ]
-crbug.com/963183 http/tests/devtools/components/viewport-datagrid.js [ Pass Failure ]
-crbug.com/963183 http/tests/devtools/unit/datagrid-editable-longtext.js [ Pass Failure ]
-crbug.com/963183 http/tests/devtools/unit/datagrid-items-attached-to-dom.js [ Pass Failure ]
-crbug.com/963183 http/tests/devtools/unit/viewport-datagrid-items-attached-to-dom.js [ Pass Failure ]
-crbug.com/963183 http/tests/devtools/unit/viewport-datagrid-items-expandable-attached-to-dom.js [ Pass Failure ]
-
 # Temporarily disabled for landing changes to treeoutline in DevTools
 crbug.com/1033213 http/tests/devtools/security/interstitial-sidebar.js [ Pass Failure ]
 crbug.com/1033213 http/tests/devtools/security/mixed-content-sidebar.js [ Pass Failure ]
@@ -6149,7 +6092,6 @@
 crbug.com/1034374 [ Linux Debug ] virtual/threaded/http/tests/devtools/tracing/timeline-worker-events.js [ Pass Failure ]
 crbug.com/1034513 [ Win7 ] virtual/stable/fast/dom/Window/window-resize-contents.html [ Pass Failure ]
 crbug.com/1026712 [ Mac ] fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-hour.html [ Pass Timeout ]
-crbug.com/1026712 [ Mac ] virtual/web-components-v0-disabled/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-hour.html [ Pass Timeout ]
 
 # The Wasm code cache requires disabling the baseline compiler, so only the
 # virtual test should be run.
@@ -6158,11 +6100,11 @@
 # Assertion errors need to be fixed
 crbug.com/1034492 http/tests/devtools/unit/filtered-item-selection-dialog-filtering.js [ Pass Failure ]
 crbug.com/1034492 http/tests/devtools/unit/filtered-list-widget-providers.js [ Pass Failure ]
+crbug.com/1034492 http/tests/devtools/unit/soft-drop-down.js [ Pass Failure ]
 
 # Sheriff 2019-12-17
-crbug.com/1034841 external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html [ Pass Failure Timeout ]
-crbug.com/1034789 [ Mac10.13 ] virtual/web-components-v0-disabled/fast/events/no-fake-mousemove.html [ Pass Timeout ]
 crbug.com/1034789 [ Mac10.13 ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Pass Timeout ]
 crbug.com/1034789 [ Mac10.13 ] virtual/threaded/fast/scroll-snap/snap-to-target-on-layout-change.html [ Pass Timeout ]
 crbug.com/1034789 [ Mac10.13 ] external/wpt/pointerevents/pointerevent_coalesced_events_attributes.html [ Pass Failure ]
-crbug.com/1034839 css3/filters/effect-reference-image.html [ Pass Failure ]
\ No newline at end of file
+crbug.com/1034839 css3/filters/effect-reference-image.html [ Pass Failure ]
+crbug.com/1035293 virtual/web-components-v0-disabled/fast/dom/StyleSheet/stylesheet-move-between-documents-crash.html [ Pass Crash ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 66f21be9..bba81b7 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -40,7 +40,10 @@
     "bases": ["external/wpt/css/css-paint-api",
               "http/tests/csspaint"],
     "args": ["--enable-threaded-compositing",
-             "--enable-blink-features=OffMainThreadCSSPaint"]
+             "--enable-blink-features=OffMainThreadCSSPaint",
+	     "--enable-gpu-rasterization",
+	     "--enable-oop-rasterization",
+	     "--enable-accelerated-2d-canvas"]
   },
   {
     "prefix": "prefer_compositing_to_lcd_text",
@@ -536,10 +539,53 @@
               "external/wpt/css/css-typed-om",
               "external/wpt/css/css-variables",
               "fast/css/variables",
-              "fast/forms/select/select-autofilled.html"],
+              "fast/forms/select/select-autofilled.html",
+              "fast/forms/001.html",
+              "fast/forms/button-style-color.html",
+              "fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html",
+              "fast/forms/color/color-suggestion-picker-appearance.html",
+              "fast/forms/date/date-appearance-basic.html",
+              "fast/forms/datetimelocal/datetimelocal-appearance-basic.html",
+              "fast/forms/fieldset/fieldset-align.html",
+              "fast/forms/month/month-appearance-basic.html",
+              "fast/forms/select/basic-selects.html",
+              "fast/forms/select-popup/popup-menu-appearance-zoom090.html",
+              "fast/forms/select-popup/popup-menu-appearance-zoom110.html",
+              "fast/forms/submit/submit-appearance-basic.html",
+              "fast/forms/text/text-appearance-basic.html",
+              "fast/forms/textarea/textarea-appearance-basic.html",
+              "external/wpt/css/css-writing-modes/block-flow-direction-vlr-022.xht",
+              "external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht",
+              "external/wpt/css/css-logical/cascading-001.html",
+              "external/wpt/css/css-logical/inheritance.html",
+              "external/wpt/css/css-logical/logical-box-border-color.html",
+              "external/wpt/css/css-logical/logical-box-border-shorthands.html",
+              "external/wpt/css/css-logical/logical-box-border-style.html",
+              "external/wpt/css/css-logical/logical-box-border-width.html",
+              "external/wpt/css/css-logical/logical-box-inset.html",
+              "external/wpt/css/css-logical/logical-box-margin.html",
+              "external/wpt/css/css-logical/logical-box-padding.html",
+              "external/wpt/css/css-logical/logical-box-size.html",
+              "external/wpt/css/css-logical/logicalprops-block-size-vlr.html",
+              "external/wpt/css/css-logical/logicalprops-block-size.html",
+              "external/wpt/css/css-logical/logicalprops-inline-size-vlr.html",
+              "external/wpt/css/css-logical/logicalprops-inline-size.html",
+              "fast/borders/border-image-outset-in-shorthand.html",
+              "fast/borders/border-image-repeat-round.html",
+              "fast/borders/border-image-repeat.html",
+              "fast/borders/border-image-slices.html",
+              "fast/borders/border-image-source.html",
+              "fast/backgrounds/mask-composite.html",
+              "fast/css/acid2.html"],
     "args": ["--enable-blink-features=CSSCascade"]
   },
   {
+    "prefix": "forced-high-contrast-cascade",
+    "bases": ["external/wpt/forced-colors-mode"],
+    "args": ["--force-high-contrast",
+             "--enable-blink-features=CSSCascade,ForcedColors"]
+  },
+  {
     "prefix": "at-property",
     "bases": ["fast/css/css-properties-values-api",
               "external/wpt/css/css-properties-values-api"],
@@ -648,15 +694,11 @@
     "bases": ["external/wpt/dom",
               "external/wpt/shadow-dom",
               "external/wpt/html/dom",
-              "external/wpt/html/rendering",
               "external/wpt/html/semantics",
-              "external/wpt/html/syntax",
               "dom",
               "shadow-dom",
               "html",
               "fast/dom",
-              "fast/events",
-              "fast/forms",
               "fast/html",
               "fast/parser"],
     "args": ["--disable-blink-features=ShadowDOMV0,CustomElementsV0,HTMLImports"]
diff --git a/third_party/blink/web_tests/animations/composition/font-variation-settings-composition.html b/third_party/blink/web_tests/animations/composition/font-variation-settings-composition.html
deleted file mode 100644
index cec5f45..0000000
--- a/third_party/blink/web_tests/animations/composition/font-variation-settings-composition.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE html>
-<meta charset="UTF-8">
-<body>
-<script src="../interpolation/resources/interpolation-test.js"></script>
-<script>
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'test' 50"',
-  addFrom: '"'test' 100"',
-  addTo: '"'test' 200"',
-}, [
-  {at: -0.3, is: "'test' 120"},
-  {at: 0, is: "'test' 150"},
-  {at: 0.5, is: "'test' 200"},
-  {at: 1, is: "'test' 250"},
-  {at: 1.5, is: "'test' 300"},
-]);
-
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'test' 50"',
-  addFrom: '"'test' 100"',
-  replaceTo: '"'test' 200"',
-}, [
-  {at: -0.3, is: "'test' 135"},
-  {at: 0, is: "'test' 150"},
-  {at: 0.5, is: "'test' 175"},
-  {at: 1, is: "'test' 200"},
-  {at: 1.5, is: "'test' 225"},
-]);
-
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'test' 100"',
-  addFrom: ''normal'',
-  replaceTo: '"'test' 200"',
-}, [
-  {at: -0.3, is: 'normal'},
-  {at: 0, is: 'normal'},
-  {at: 0.5, is: "'test' 200"},
-  {at: 1, is: "'test' 200"},
-  {at: 1.5, is: "'test' 200"},
-]);
-
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'test' 100"',
-  addFrom: ''normal'',
-  addTo: '"'test' 200"',
-}, [
-  {at: -0.3, is: 'normal'},
-  {at: 0, is: 'normal'},
-  {at: 0.5, is: "'test' 300"},
-  {at: 1, is: "'test' 300"},
-  {at: 1.5, is: "'test' 300"},
-]);
-
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'aaaa' 100, 'bbbb' 200"',
-  addFrom: '"'aaaa' 20, 'bbbb' 50"',
-  addTo: '"'aaaa' 30, 'bbbb' 100"',
-}, [
-  {at: -0.3, is: "'aaaa' 117, 'bbbb' 235"},
-  {at: 0, is: "'aaaa' 120, 'bbbb' 250"},
-  {at: 0.5, is: "'aaaa' 125, 'bbbb' 275"},
-  {at: 1, is: "'aaaa' 230, 'bbbb' 300"},
-  {at: 1.5, is: "'aaaa' 235, 'bbbb' 325"},
-]);
-
-assertComposition({
-  property: 'font-variation-settings',
-  underlying: '"'test' 100"',
-  addFrom: '"'aaaa' 20, 'bbbb' 50"',
-  addTo: '"'aaaa' 30, 'bbbb' 100"',
-}, [
-  {at: -0.3, is: "'aaaa' 17, 'bbbb' 35"},
-  {at: 0, is: "'aaaa' 20, 'bbbb' 50"},
-  {at: 0.5, is: "'aaaa' 25, 'bbbb' 75"},
-  {at: 1, is: "'aaaa' 30, 'bbbb' 100"},
-  {at: 1.5, is: "'aaaa' 35, 'bbbb' 125"},
-]);
-</script>
-</body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index ab66606..c2f1262 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -7473,6 +7473,18 @@
      {}
     ]
    ],
+   "compat/webkit-linear-gradient-diff-unprefixed.html": [
+    [
+     "compat/webkit-linear-gradient-diff-unprefixed.html",
+     [
+      [
+       "/compat/webkit-linear-gradient-diff-unprefixed-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "compat/webkit-linear-gradient-line-bottom.html": [
     [
      "compat/webkit-linear-gradient-line-bottom.html",
@@ -63791,6 +63803,18 @@
      {}
     ]
    ],
+   "css/css-pseudo/marker-content-014.html": [
+    [
+     "css/css-pseudo/marker-content-014.html",
+     [
+      [
+       "/css/css-pseudo/marker-content-014-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-pseudo/marker-display-dynamic-001.html": [
     [
      "css/css-pseudo/marker-display-dynamic-001.html",
@@ -88583,6 +88607,18 @@
      {}
     ]
    ],
+   "css/css-ui/outline-offset-table-001.html": [
+    [
+     "css/css-ui/outline-offset-table-001.html",
+     [
+      [
+       "/css/css-ui/outline-offset-table-001-notref.html",
+       "!="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-ui/outline-offset.html": [
     [
      "css/css-ui/outline-offset.html",
@@ -128348,6 +128384,9 @@
    "compat/webkit-gradient-comma-expected.txt": [
     []
    ],
+   "compat/webkit-linear-gradient-diff-unprefixed-ref.html": [
+    []
+   ],
    "compat/webkit-text-fill-color-property-001-ref.html": [
     []
    ],
@@ -143915,6 +143954,9 @@
    "css/css-pseudo/marker-content-013-ref.html": [
     []
    ],
+   "css/css-pseudo/marker-content-014-ref.html": [
+    []
+   ],
    "css/css-pseudo/marker-font-properties-ref.html": [
     []
    ],
@@ -148535,6 +148577,9 @@
    "css/css-ui/inheritance-expected.txt": [
     []
    ],
+   "css/css-ui/outline-offset-table-001-notref.html": [
+    []
+   ],
    "css/css-ui/parsing/outline-color-valid-optional-expected.txt": [
     []
    ],
@@ -155219,6 +155264,9 @@
    "element-timing/resources/square20.png": [
     []
    ],
+   "encoding-detection/__dir__.headers": [
+    []
+   ],
    "encoding-detection/ar-ISO-8859-6-late.tentative-expected.txt": [
     []
    ],
@@ -155240,6 +155288,9 @@
    "encoding-detection/ja-EUC-JP.tentative-expected.txt": [
     []
    ],
+   "encoding-detection/support/__dir__.headers": [
+    []
+   ],
    "encoding-detection/support/ar-ISO-8859-6-late.sub.html": [
     []
    ],
@@ -159737,6 +159788,9 @@
    "html/dom/reflection-embedded-expected.txt": [
     []
    ],
+   "html/dom/reflection-forms-expected.txt": [
+    []
+   ],
    "html/dom/reflection-metadata-expected.txt": [
     []
    ],
@@ -165572,6 +165626,12 @@
    "imagebitmap-renderingcontext/OWNERS": [
     []
    ],
+   "imagebitmap-renderingcontext/context-creation-offscreen-expected.txt": [
+    []
+   ],
+   "imagebitmap-renderingcontext/context-preserves-canvas-expected.txt": [
+    []
+   ],
    "images/META.yml": [
     []
    ],
@@ -212243,6 +212303,12 @@
      {}
     ]
    ],
+   "css/css-fonts/animations/font-variation-settings-composition.html": [
+    [
+     "css/css-fonts/animations/font-variation-settings-composition.html",
+     {}
+    ]
+   ],
    "css/css-fonts/animations/font-variation-settings-interpolation.html": [
     [
      "css/css-fonts/animations/font-variation-settings-interpolation.html",
@@ -224959,6 +225025,12 @@
      {}
     ]
    ],
+   "css/css-values/ch-recalc-on-font-load.html": [
+    [
+     "css/css-values/ch-recalc-on-font-load.html",
+     {}
+    ]
+   ],
    "css/css-values/clamp-length-computed.html": [
     [
      "css/css-values/clamp-length-computed.html",
@@ -226087,6 +226159,12 @@
      {}
     ]
    ],
+   "css/cssom-view/getClientRects-inline-atomic-child.html": [
+    [
+     "css/cssom-view/getClientRects-inline-atomic-child.html",
+     {}
+    ]
+   ],
    "css/cssom-view/historical.html": [
     [
      "css/cssom-view/historical.html",
@@ -347612,6 +347690,14 @@
    "b288a9a43fe8eba26a4ef37bd5439cbe75047885",
    "testharness"
   ],
+  "compat/webkit-linear-gradient-diff-unprefixed-ref.html": [
+   "96c2089d6566b370f7e65d1455e202933ea80436",
+   "support"
+  ],
+  "compat/webkit-linear-gradient-diff-unprefixed.html": [
+   "ee49dc4e158bdec6013860afc443d4b6e9c4411c",
+   "reftest"
+  ],
   "compat/webkit-linear-gradient-line-bottom.html": [
    "21e1c8948bfedb697e64627d7c2372163cd5bb28",
    "reftest"
@@ -379968,6 +380054,10 @@
    "d84ff7e5dfe3f4c86ed4b9bf30914ed3d11b156c",
    "testharness"
   ],
+  "css/css-fonts/animations/font-variation-settings-composition.html": [
+   "58f037415e23801fb2c540e5ae3b032cdd4ff0c8",
+   "testharness"
+  ],
   "css/css-fonts/animations/font-variation-settings-interpolation-expected.txt": [
    "854efe3e4d1412ea3da15bace063e8bfcf46b8c9",
    "support"
@@ -397377,11 +397467,11 @@
    "support"
   ],
   "css/css-paint-api/background-image-alpha-ref.html": [
-   "519b3599e95d0bc3463bfc077f6022edeaa4ca8c",
+   "532b1bd7e31450ad60c76d5c8007d67485609bc7",
    "support"
   ],
   "css/css-paint-api/background-image-alpha.https.html": [
-   "7f1e31bf39bbc98bd6f37a99f7e660cda3590de0",
+   "c8fdc852579994edf4ea44155a7c2c1c8a6e1f14",
    "reftest"
   ],
   "css/css-paint-api/background-image-multiple-ref.html": [
@@ -397421,19 +397511,19 @@
    "reftest"
   ],
   "css/css-paint-api/geometry-background-image-001-ref.html": [
-   "83edae100ee4ecd02315147ddf96ef61f34e875d",
+   "3e7db50548e0ddd1739ab91db24e29072d267061",
    "support"
   ],
   "css/css-paint-api/geometry-background-image-001.https.html": [
-   "eb7f6716ada1bdea3761b4d164e9b2ca7ea35f98",
+   "50d75a54703c32fdea3b74890b1f8f3a0e7a55f4",
    "reftest"
   ],
   "css/css-paint-api/geometry-background-image-002-ref.html": [
-   "ab964dbf8d72fcdaac1f7463a5d4811b759558b6",
+   "b03fcd02ec348e42fe74c61d8b887ff07e260ff8",
    "support"
   ],
   "css/css-paint-api/geometry-background-image-002.https.html": [
-   "e636aa73b3b2e519c2a6c12457a6434b38036ea0",
+   "06be523c320ba8393cd287d13676dc1a5ecdb211",
    "reftest"
   ],
   "css/css-paint-api/geometry-background-image-tiled-001-ref.html": [
@@ -397441,55 +397531,55 @@
    "support"
   ],
   "css/css-paint-api/geometry-background-image-tiled-001.https.html": [
-   "51373a528e4ca46b0adcf665e28cc3dc1aa793bc",
+   "dbb4c385ee1a4f9dc2601475625c6caa1c97fd81",
    "reftest"
   ],
   "css/css-paint-api/geometry-background-image-tiled-002-ref.html": [
-   "f3c65e6776dbe4ad258c9cd1e17a13b2f98ffb8e",
+   "3b3b2bc30e6e182cf8d0ffd22a8d64a623de76cc",
    "support"
   ],
   "css/css-paint-api/geometry-background-image-tiled-002.https.html": [
-   "d55761b47cd362827bf828e03d6a8f94dd309431",
+   "6f865175ce30656534e1cb7894cfec91baa7660e",
    "reftest"
   ],
   "css/css-paint-api/geometry-background-image-tiled-003-ref.html": [
-   "8e1eb027658afccf9139cce1ee736e6b0e37b095",
+   "a21a990f98d3b1afe1122e535cfe13c95a34ba8a",
    "support"
   ],
   "css/css-paint-api/geometry-background-image-tiled-003.https.html": [
-   "6d5bdd2fa539979f4069e42cd9582c2d13fba445",
+   "a3792caafbf746f9b9cd32ea0cedb950571e1b65",
    "reftest"
   ],
   "css/css-paint-api/geometry-border-image-001-ref.html": [
-   "bb0aa409374be3b7d83cb2f9cf88e61f73c6e450",
+   "23a48d55737f24bc96d7191e69b4630a15cb34d4",
    "support"
   ],
   "css/css-paint-api/geometry-border-image-001.https.html": [
-   "ff7f56e299ddd2a0206d7a25d0d930afb616c0f0",
+   "76813eab30f1e1cb6e156029defaac858df10366",
    "reftest"
   ],
   "css/css-paint-api/geometry-border-image-002-ref.html": [
-   "0eb84ec0400d77e85259f82c18d6bd1d47dd88cc",
+   "050c6a9c356d4cd92cc8dbb3981fcd0bb26bf35b",
    "support"
   ],
   "css/css-paint-api/geometry-border-image-002.https.html": [
-   "d6e47f049071416302a250c019b110d7dcaa8071",
+   "4c686b9c11c2aa258ef031bdb460a8fbef1a3f40",
    "reftest"
   ],
   "css/css-paint-api/geometry-border-image-003-ref.html": [
-   "b17c9ffce2ad49576ff17f7d264c05205e73b3a9",
+   "ef14f7728b60db4f3bc0165d0562e39615d5f53f",
    "support"
   ],
   "css/css-paint-api/geometry-border-image-003.https.html": [
-   "36af043cc5fe9e2ebe0dc94855b3b1def55f28aa",
+   "ce343df2916b87f4945aab410e939b0404c4fa6a",
    "reftest"
   ],
   "css/css-paint-api/geometry-border-image-004-ref.html": [
-   "c32fdd8f0abbb6389ff651f3d3befc0d1d831010",
+   "764b6e57c5cd33bb19ff843b35b3754a53a0b487",
    "support"
   ],
   "css/css-paint-api/geometry-border-image-004.https.html": [
-   "0f483cd5d19acf4923e60a9f59f55b2bd1e2d0d0",
+   "8dd80c717191346275aa44b8a28125d6aff04105",
    "reftest"
   ],
   "css/css-paint-api/geometry-border-image-005-ref.html": [
@@ -397557,7 +397647,7 @@
    "reftest"
   ],
   "css/css-paint-api/non-registered-property-value.https.html": [
-   "5b237e01eae6ca03672ecb7c533773754d79abab",
+   "774cb4eb2de487e3254dc4fa7b39bd3e3d19f136",
    "reftest"
   ],
   "css/css-paint-api/one-custom-property-animation-ref.html": [
@@ -397577,19 +397667,19 @@
    "reftest"
   ],
   "css/css-paint-api/paint-arguments-ref.html": [
-   "3352acf6518d9ffd1ffee5a8ecab4b7f292a038d",
+   "3675fc10e72eb175863597eba6e0a7cfdb6beea6",
    "support"
   ],
   "css/css-paint-api/paint-arguments.https.html": [
-   "615027c8fe393c2109bb99bc6bb1c2f36d104f9e",
+   "c08069c2e399eb8fd04f45c6df2c882321ae93d7",
    "reftest"
   ],
   "css/css-paint-api/paint-function-arguments-ref.html": [
-   "99adfd2712199dae9990c1ddf6593f45ccb5383c",
+   "6391d17f01ae4f7f2366d21b66a42fb380401916",
    "support"
   ],
   "css/css-paint-api/paint-function-arguments.https.html": [
-   "3a1e579f5ecbe324d48a6e0cb4d94a77cb4361d3",
+   "fc303bf12839617bc24b0972d23520950ef4cea8",
    "reftest"
   ],
   "css/css-paint-api/paint2d-composite-ref.html": [
@@ -397597,23 +397687,23 @@
    "support"
   ],
   "css/css-paint-api/paint2d-composite.https.html": [
-   "edf8a766fabedaac61f2de9607ebde01e0d86c5b",
+   "d654ba49aad6048f88e6ddb6750554dc22b860fb",
    "reftest"
   ],
   "css/css-paint-api/paint2d-filter-ref.html": [
-   "4ca6383b141308fb2d2582f62d946eb2df99f2c4",
+   "2e4b979ad818e2ab05bca014fd6acfc4f433d66f",
    "support"
   ],
   "css/css-paint-api/paint2d-filter.https.html": [
-   "9d598c7a9689fccd3fcf140f912f58233f734b14",
+   "a53fff986c7207656b93f8d671f01f3280c2b24f",
    "reftest"
   ],
   "css/css-paint-api/paint2d-gradient-ref.html": [
-   "a8064f595efeade2fef058ec5a969a85337e1276",
+   "f3644a92fd2bea78288db7add1c47cef023e0ead",
    "support"
   ],
   "css/css-paint-api/paint2d-gradient.https.html": [
-   "1887f52b06b1033d183ef6506f92cf9fe0d69773",
+   "594f42b4c098cff337b98bb2a33b35c7d269f134",
    "reftest"
   ],
   "css/css-paint-api/paint2d-image-ref.html": [
@@ -397625,11 +397715,11 @@
    "reftest"
   ],
   "css/css-paint-api/paint2d-paths-ref.html": [
-   "7557411b4a18d240f92b32250343474079e013c3",
+   "313a71e1908473bc0826de3cc8c361c95314830a",
    "support"
   ],
   "css/css-paint-api/paint2d-paths.https.html": [
-   "0e04168fcb1aae5bc555873b795dc448d476551b",
+   "ae29930dc61dea1cfe4f48faab4ead46cdd7833d",
    "reftest"
   ],
   "css/css-paint-api/paint2d-rects-ref.html": [
@@ -397641,115 +397731,115 @@
    "reftest"
   ],
   "css/css-paint-api/paint2d-shadows-ref.html": [
-   "268db495ee5907daaf16f09e9a99dc46d51ad5c8",
+   "94aea6ff8087a06bd58b4269e2fa046bc60c6813",
    "support"
   ],
   "css/css-paint-api/paint2d-shadows.https.html": [
-   "b641dab8860f87264cd7b23f170ba693d894af62",
+   "124819fa3a68e893439df41f3e410d5526160dd1",
    "reftest"
   ],
   "css/css-paint-api/paint2d-transform-ref.html": [
-   "e863f363f79ad9cf52670d0a7a7db447158cbc69",
+   "08893127a68872dbb8be4645275cbd5bfcc16ee0",
    "support"
   ],
   "css/css-paint-api/paint2d-transform.https.html": [
-   "d052b8c5543344ba3629c4723e5d05912cfc86dd",
+   "b264d1da5f5038283b1f83635b7a03df20652426",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-001.https.html": [
-   "486f379dd7b27e70fd734d62e7de45fd8ca9ab5e",
+   "d18259e4d719847fdc362d5d471557b7888291f2",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-002.https.html": [
-   "5c7b3aca048d05f8535e6d182b9c5350595464ea",
+   "c5975586e9b10c98e85f937b0550a85fd2110d9a",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-003.https.html": [
-   "81904ee6f7b132fe6a58cd12d84e43b95cee625b",
+   "4d5daa70731c1895e580e85155f44716448a58b1",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-004.https.html": [
-   "9bf264b0d5fc21225c9f7ae8c887b61237b3f882",
+   "bd1e5651af7c4cb01c446ddee7595f2001dc65c5",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-005.https.html": [
-   "24769f472c5b88b3b311a8d5e46e13ca3aaf6609",
+   "16744ec355c28c616eabbdcfdc100cbc0708cf5f",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-006.https.html": [
-   "a6fcc16c5da9e135eebe3b4f53194f7fbe867fd2",
+   "2fbbec77054698b7c342294fa989cf854e95e497",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-007.https.html": [
-   "462cfb601069597977dabe25c806ee1af095a554",
+   "1fc435fc7b0ab7e47d0e2d183682efbf73e34c95",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-008.https.html": [
-   "d5c18b0905d76948428a3e874eccf7bda6ac944e",
+   "9543d2d88423caf1d9dfdfe29c96a0d4ecb8f0f1",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-009.https.html": [
-   "7cfdf91eb02a2d2f293f52cc3a8256243757557f",
+   "41e8411a4a7e2b060142c0d8a792dc2ea9f7e9a8",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-010.https.html": [
-   "142ca0c5d5d6b291f126d83554aa9ccec6aaa194",
+   "44bbab5b7f1a6d781b209f1fe6f654bec5badb71",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-011.https.html": [
-   "23eb9d3c9f98f4e2a67728be32897bf59b87a1aa",
+   "09f8b0274760dab95f19d381b3aa365596e864ad",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-012.https.html": [
-   "fa2c6b5f56053373e3be5d48e8ca0840b090ee8f",
+   "4a05b6fcf12accb0a2c4604529993b3d0030089b",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-013.https.html": [
-   "adc1c03cfe66f4ce6fe75c4a59ca4708f7115059",
+   "ef8bf905c23dc4cd429d536b5b2f8e450cdf9b91",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-014.https.html": [
-   "d041ae316f7a3ea2c853828d6845716c36c13c85",
+   "715dab8dc792cc8ffa4854b1adc8f411bb11676a",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-015.https.html": [
-   "8ebe3e7c4d15fb653d890127eece81e1049df38f",
+   "4c8cfebca439981e4ab6d1af78010756455df2d0",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-016.https.html": [
-   "ccd0595faa514a877eb2ff0f7d9a8980b9a5b971",
+   "aa5eda8aaecb5e2085abd70156f15d7227e797eb",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-017.https.html": [
-   "476e29ff12f0d75940ee5dfb5ac4079e43a7ae04",
+   "2ba8d996c63d7856ff982b0f12ccb097e8f4893f",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-018-ref.html": [
-   "05da4ed7880b640d5ad83af2b8f9ce53d283b89a",
+   "55b841fc649cfdc57093a7d6e8d7f7a5543fa436",
    "support"
   ],
   "css/css-paint-api/parse-input-arguments-018.https.html": [
-   "e6a31cbdd41899f2d4a548a7af39e97c44140380",
+   "1554cc64451d3133980804bff1e24f87fdfaa51e",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-019.https.html": [
-   "309ec800eacfde6302add112ecd94275f394dc1a",
+   "d0a628561d8f87c382feee2307d496ae9cb7f1c7",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-020.https.html": [
-   "7e00b64123d5621c226b104ccec133b83f10fa6e",
+   "7797eb45fec1123c4f7138ed101fe24cc58599e2",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-021.https.html": [
-   "8fa043a8cdead2ebbbb83f69fe708acac05127b1",
+   "22d6d5adbd009751117f589df8add31dbf384c4f",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-022.https.html": [
-   "2ff27d7a4af5d4905a76ca53228b3cc619c05ecf",
+   "9434807039762e83ec291e2ff49c2862a9a76662",
    "reftest"
   ],
   "css/css-paint-api/parse-input-arguments-ref.html": [
-   "086bc7b27ee79caab2c2e433da4ff00ba1bace9b",
+   "862212092a488948c202d88ba18334a738b583a8",
    "support"
   ],
   "css/css-paint-api/registered-property-interpolation-001.https.html": [
@@ -397793,15 +397883,15 @@
    "reftest"
   ],
   "css/css-paint-api/registered-property-invalidation-001.https.html": [
-   "133b9238e6ceef161f99b99711839cf791c908b8",
+   "408ba49743c561f3310eb4beba6767eba87b2f07",
    "reftest"
   ],
   "css/css-paint-api/registered-property-invalidation-002.https.html": [
-   "aadbfec42c8c89a9fa9b9a77d86f36fd36b0cbe3",
+   "b65bcd5a6eebb71101d222065a6e704b7bbfae53",
    "reftest"
   ],
   "css/css-paint-api/registered-property-stylemap.https.html": [
-   "4a6b4db521af8ddff57dd4ecaf9f9c35c5a4cc6b",
+   "3dec98d9102b4adcb09ec6bb496a4c74cb701280",
    "reftest"
   ],
   "css/css-paint-api/registered-property-value-001.https.html": [
@@ -397881,7 +397971,7 @@
    "support"
   ],
   "css/css-paint-api/resources/utils.js": [
-   "7efe85f260303050c73d58715f8dd768adb4e9d1",
+   "e9686441361326b996c73bfd084bd2f5a0bb1648",
    "support"
   ],
   "css/css-paint-api/setTransform-001.https.html": [
@@ -397905,27 +397995,27 @@
    "support"
   ],
   "css/css-paint-api/style-background-image-ref.html": [
-   "2fe4d0c9c024c22002f77e9e320624483f0086b7",
+   "ac936dd1694dc85f24049816ed0717632c966e09",
    "support"
   ],
   "css/css-paint-api/style-background-image.https.html": [
-   "8e5f2f81547f0305ff230198f1b0300c838adfde",
+   "6a58da327332ee1edb3e8c18f099bf7408aae1c3",
    "reftest"
   ],
   "css/css-paint-api/style-before-pseudo-ref.html": [
-   "cd8ea6bd66ff0d8ab77d6d537212d97bab855492",
+   "823fc257d41d2fd9f803d6bc3642c0e5ccf2d871",
    "support"
   ],
   "css/css-paint-api/style-before-pseudo.https.html": [
-   "017b23a6caf66219a2b5912ce6eb9316cd0adfe5",
+   "7fde66ecb605184cc3040e84299fc83635cdf820",
    "reftest"
   ],
   "css/css-paint-api/style-first-letter-pseudo-ref.html": [
-   "f9b116dcb6cf146f864a02c8270c46f6ba2b92d7",
+   "8f337c5be8b1a0804d2d02e86fa70e9c9e94c9a9",
    "support"
   ],
   "css/css-paint-api/style-first-letter-pseudo.https.html": [
-   "d3c31a0508dc86aa0da95815ff2448bc2e074caf",
+   "67891378035ad776b8511b0c198c84c46bb9d981",
    "reftest"
   ],
   "css/css-paint-api/two-custom-property-animation-ref.html": [
@@ -399261,7 +399351,15 @@
    "support"
   ],
   "css/css-pseudo/marker-content-013.html": [
-   "18f00d173821b22ebce43d792b5888aa8f3ea310",
+   "427578f9c5abfd1be809ea71cfcfdac4298def44",
+   "reftest"
+  ],
+  "css/css-pseudo/marker-content-014-ref.html": [
+   "a4d269444e4df24e2ad7701271106fe26d1b14f6",
+   "support"
+  ],
+  "css/css-pseudo/marker-content-014.html": [
+   "8be9d759e889aeb339257008715637f3c4de4be3",
    "reftest"
   ],
   "css/css-pseudo/marker-default-styles.html": [
@@ -420112,6 +420210,14 @@
    "a131e96e29ef8d6dd0f3cbbc03235ede4f71e014",
    "reftest"
   ],
+  "css/css-ui/outline-offset-table-001-notref.html": [
+   "aafa2b053cb30d77997743a226901d6dd4472724",
+   "support"
+  ],
+  "css/css-ui/outline-offset-table-001.html": [
+   "4b6f46949b7dae8b162b3d41f4efcadc9464a1d0",
+   "reftest"
+  ],
   "css/css-ui/outline-offset.html": [
    "5dee28e3b4f4e98c44be820f9f7ed0dafb661038",
    "reftest"
@@ -421960,6 +422066,10 @@
    "ffb2ecd6dc9c1a1bf4b8f5fc23c851f00e01fd6d",
    "reftest"
   ],
+  "css/css-values/ch-recalc-on-font-load.html": [
+   "625521b8102deb6cb2ca89eced91dda720c8408c",
+   "testharness"
+  ],
   "css/css-values/ch-unit-001.html": [
    "83374e7bb291e45a44e3002635f967611aa1a5b7",
    "reftest"
@@ -429716,6 +429826,10 @@
    "c5a3062cf495fdb5061951c4184156d90ff056d5",
    "testharness"
   ],
+  "css/cssom-view/getClientRects-inline-atomic-child.html": [
+   "f1f6fc5abc679d087d221573456eb9219d1a405c",
+   "testharness"
+  ],
   "css/cssom-view/getClientRects-inline.html": [
    "415e34a6f0430e08441ee32b3f7c0ca8cd11a692",
    "reftest"
@@ -434981,7 +435095,7 @@
    "support"
   ],
   "css/support/interpolation-testcommon.js": [
-   "d1cb7cfbeb07fb16439c2245f12c5fbc174c77b4",
+   "16a1c0e7f7fb83f52b3b5d55fda4d49462fa9fe6",
    "support"
   ],
   "css/support/parsing-testcommon.js": [
@@ -443460,6 +443574,10 @@
    "d988934708116f29f9289511559079544aba1ba6",
    "testharness"
   ],
+  "encoding-detection/__dir__.headers": [
+   "a50d2c8454fd943a3e26a80398ad11e8fa9e9551",
+   "support"
+  ],
   "encoding-detection/ar-ISO-8859-6-late.tentative-expected.txt": [
    "32e1d19abef929ae5183085cc1aeeb7004deba00",
    "support"
@@ -443648,6 +443766,10 @@
    "a2ee62c65f53610691f366ed9eac0f19ae310ff9",
    "testharness"
   ],
+  "encoding-detection/support/__dir__.headers": [
+   "a50d2c8454fd943a3e26a80398ad11e8fa9e9551",
+   "support"
+  ],
   "encoding-detection/support/ar-ISO-8859-6-late.sub.html": [
    "b5d8d50498ec87cc10bebaf586452913f640a26b",
    "support"
@@ -453777,7 +453899,7 @@
    "support"
   ],
   "html/cross-origin-embedder-policy/none.https.html": [
-   "b1bb6fefc6cfa45a217cc3b04534df8065fa1579",
+   "f13a7523011674b0bab6b265d481b58649dc5531",
    "testharness"
   ],
   "html/cross-origin-embedder-policy/none.https.html.headers": [
@@ -453845,7 +453967,7 @@
    "support"
   ],
   "html/cross-origin-embedder-policy/require-corp.https.html": [
-   "446003723a19a1db88569bb3b0bf07540dfb98c8",
+   "49b2eb123b519dc96314b1db31cc4d6797efae92",
    "testharness"
   ],
   "html/cross-origin-embedder-policy/require-corp.https.html.headers": [
@@ -455241,13 +455363,17 @@
    "support"
   ],
   "html/dom/reflection-embedded-expected.txt": [
-   "969c1d2baa53cd695fff85a45bc2942d02426439",
+   "f1fe7410aadd5efb20e93132ab8b2db329805742",
    "support"
   ],
   "html/dom/reflection-embedded.html": [
    "0a362f817a5e7fb630cc4c0317fc80fe59cf4ab3",
    "testharness"
   ],
+  "html/dom/reflection-forms-expected.txt": [
+   "97c98daf132757ef860173f35d4898b0dfd0d064",
+   "support"
+  ],
   "html/dom/reflection-forms.html": [
    "2fe251a6f4c26cd5f679572350717b3b87698a64",
    "testharness"
@@ -455257,7 +455383,7 @@
    "testharness"
   ],
   "html/dom/reflection-metadata-expected.txt": [
-   "69f32cdec37f528dcb696d5f52a83a252bb6ec9e",
+   "bfd647b43547c65a956c1dcb85ab8b4a8f77ae51",
    "support"
   ],
   "html/dom/reflection-metadata.html": [
@@ -455265,7 +455391,7 @@
    "testharness"
   ],
   "html/dom/reflection-misc-expected.txt": [
-   "6456861b66798e7f04897ab4488769bba93b20a3",
+   "13c04358aac2ed10ea424f3be12dcb0a06c25b30",
    "support"
   ],
   "html/dom/reflection-misc.html": [
@@ -455289,7 +455415,7 @@
    "testharness"
   ],
   "html/dom/reflection-text-expected.txt": [
-   "777c18aaa450b41e16bab89389d01d1ff70b878b",
+   "aa7349faf04a1e0c5ec4404f1b81a8d999111339",
    "support"
   ],
   "html/dom/reflection-text.html": [
@@ -455297,7 +455423,7 @@
    "testharness"
   ],
   "html/dom/reflection.js": [
-   "fca9e43f245a9796982685c66ef8ee892d6cd7eb",
+   "a5f7b3fd0a08e60729192a62902a9e9f07805821",
    "support"
   ],
   "html/dom/resources/self-origin-subframe.html": [
@@ -471516,12 +471642,16 @@
    "21c5ea48ad4cadff96c401972594083958f447f3",
    "testharness"
   ],
+  "imagebitmap-renderingcontext/context-creation-offscreen-expected.txt": [
+   "341f3ed3e5368d3ce51bafdf06aecb36215db25a",
+   "support"
+  ],
   "imagebitmap-renderingcontext/context-creation-offscreen-with-alpha.html": [
    "b565def964d0eb422702bc73054b6c4dfa0a3cb3",
    "testharness"
   ],
   "imagebitmap-renderingcontext/context-creation-offscreen.html": [
-   "41cc6dc02a239cf26ea37bbdca1a252f19917ee7",
+   "05a920cd3e605ade63aa4d01171d9d3f5597ed72",
    "testharness"
   ],
   "imagebitmap-renderingcontext/context-creation-with-alpha.html": [
@@ -471532,8 +471662,12 @@
    "3daa3977898cdd21fa5192f6973f0f5a26294cd9",
    "testharness"
   ],
+  "imagebitmap-renderingcontext/context-preserves-canvas-expected.txt": [
+   "8a5d00137f2c38b868e868748d9b66f844d24f5a",
+   "support"
+  ],
   "imagebitmap-renderingcontext/context-preserves-canvas.html": [
-   "eca7afe9ddd18f23e14f9cb2b16208713af7974b",
+   "9c3a1fb39f2a75db8cd89c1b2225ce469a1caeec",
    "testharness"
   ],
   "imagebitmap-renderingcontext/toBlob-origin-clean-offscreen.sub.html": [
@@ -473117,7 +473251,7 @@
    "support"
   ],
   "interfaces/encrypted-media.idl": [
-   "26c03f6f24dc0321332c7e1d16443d350d35975a",
+   "008b68beb1986ccaf55419dd175e8cc788d054c0",
    "support"
   ],
   "interfaces/entries-api.idl": [
@@ -473221,7 +473355,7 @@
    "support"
   ],
   "interfaces/media-playback-quality.idl": [
-   "71c835677a76f454dec5ddaa146d41f0c045c186",
+   "c3ee5237e4ca43656807dfdb36c3fa9c5d7344a8",
    "support"
   ],
   "interfaces/media-source.idl": [
@@ -473481,7 +473615,7 @@
    "support"
   ],
   "interfaces/webrtc.idl": [
-   "3b2be61cedc88b559c2ea86388f86cfe44bdb93a",
+   "e30fc38fd003a283ebb4184786d181c5b4293dc4",
    "support"
   ],
   "interfaces/webusb.idl": [
@@ -475281,11 +475415,11 @@
    "reftest"
   ],
   "mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html": [
-   "d24fbf041afe481c8cab8cb3ffcbe154357b6955",
+   "ebb12a6c6c6789efefdcd313da0700584c352f68",
    "support"
   ],
   "mathml/relations/css-styling/mathsize-attribute-css-keywords.html": [
-   "6390ebfabaf5cf5cf83590d86b3efd3231a55b00",
+   "84c31d743c930d93cbd6993bddb18f1c5d295f33",
    "reftest"
   ],
   "mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html": [
@@ -503393,7 +503527,7 @@
    "support"
   ],
   "resource-timing/resources/sw-install.html": [
-   "0a2fbe2245b865681e88178903e450a6edfe9d73",
+   "2f1dccf1ace2025eefc847a7bf39508249ad603e",
    "support"
   ],
   "resource-timing/resources/sw.js": [
@@ -503441,7 +503575,7 @@
    "support"
   ],
   "resource-timing/workerStart-tao-protected.https.html": [
-   "cf5c2e3d606fba4543e251caa980abc71a901c14",
+   "f9b50f70360dd6e09908bc2d81dff13735aad236",
    "testharness"
   ],
   "resources/.gitignore": [
@@ -510693,7 +510827,7 @@
    "reftest"
   ],
   "svg/embedded/image-fractional-width-vertical-fidelity.svg": [
-   "81f27922b94e031f2dc49ce77a69c6350ea474bc",
+   "4409ee32a93aebf34ed9dbaac9b7592f5bd54b85",
    "reftest"
   ],
   "svg/embedded/reference/green-rect-100x100.svg": [
@@ -517529,7 +517663,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/executors/executorselenium.py": [
-   "d6745018279e74affce1493da3cbb9b01f828fb0",
+   "ceca81211e1140577cc3a5f163ffe17c73dd56a3",
    "support"
   ],
   "tools/wptrunner/wptrunner/executors/executorservo.py": [
@@ -527305,7 +527439,7 @@
    "testharness"
   ],
   "webrtc/idlharness.https.window-expected.txt": [
-   "c615e8edb161d25b542de16ecf843c48b35e7389",
+   "5edbe2136c0019abdbd8a1d1d1e3ee6cecdec0d8",
    "support"
   ],
   "webrtc/idlharness.https.window.js": [
@@ -532441,7 +532575,7 @@
    "testharness"
   ],
   "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [
-   "70e9d6e6e5951aa8c7cfd69e8fcac6e158351153",
+   "0b83b4c6bb13faef3a6114c60f3dcfc14e7757c2",
    "testharness"
   ],
   "webxr/xrSession_requestAnimationFrame_timestamp.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed-ref.html b/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed-ref.html
new file mode 100644
index 0000000..96c2089d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Compatibility Test Reference</title>
+<style>
+  #square {
+    height: 100px;
+    width: 100px;
+    background-image: linear-gradient(to bottom, orange, blue);
+  }
+</style>
+<p>You should see a square, orange at the top, blue at the bottom.</p>
+<div id="square"></div>
diff --git a/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed.html b/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed.html
new file mode 100644
index 0000000..ee49dc4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compat/webkit-linear-gradient-diff-unprefixed.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>Compatibility Test: -webkit-linear-gradient() diff with linear-gradient()</title>
+<link rel="help" href="https://compat.spec.whatwg.org/#css-gradients-webkit-linear-gradient">
+<link rel="match" href="webkit-linear-gradient-diff-unprefixed-ref.html">
+<style>
+  #square {
+    height: 100px;
+    width: 100px;
+  }
+</style>
+<p>You should see a square, orange at the top, blue at the bottom.</p>
+<div id="square"></div>
+<script>
+  square.offsetTop;
+  square.style.backgroundImage = "-webkit-linear-gradient(bottom, orange, blue)";
+  square.offsetTop;
+  square.style.backgroundImage = "linear-gradient(to bottom, orange, blue)";
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-composition.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-composition.html
new file mode 100644
index 0000000..58f0374
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/animations/font-variation-settings-composition.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>font-variation-settings composition</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#propdef-font-variation-settings">
+<meta name="assert" content="font-variation-settings supports animation pairwise by 'like' properties">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<body></body>
+
+<script>
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'test' 50",
+  addFrom: "'test' 100",
+  addTo: "'test' 200",
+}, [
+  {at: -0.3, expect: "'test' 120"},
+  {at: 0, expect: "'test' 150"},
+  {at: 0.5, expect: "'test' 200"},
+  {at: 1, expect: "'test' 250"},
+  {at: 1.5, expect: "'test' 300"},
+]);
+
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'test' 50",
+  addFrom: "'test' 100",
+  replaceTo: "'test' 200",
+}, [
+  {at: -0.3, expect: "'test' 135"},
+  {at: 0, expect: "'test' 150"},
+  {at: 0.5, expect: "'test' 175"},
+  {at: 1, expect: "'test' 200"},
+  {at: 1.5, expect: "'test' 225"},
+]);
+
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'test' 100",
+  addFrom: 'normal',
+  replaceTo: "'test' 200",
+}, [
+  {at: -0.3, expect: 'normal'},
+  {at: 0, expect: 'normal'},
+  {at: 0.5, expect: "'test' 200"},
+  {at: 1, expect: "'test' 200"},
+  {at: 1.5, expect: "'test' 200"},
+]);
+
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'test' 100",
+  addFrom: 'normal',
+  addTo: "'test' 200",
+}, [
+  {at: -0.3, expect: 'normal'},
+  {at: 0, expect: 'normal'},
+  {at: 0.5, expect: "'test' 300"},
+  {at: 1, expect: "'test' 300"},
+  {at: 1.5, expect: "'test' 300"},
+]);
+
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'aaaa' 100, 'bbbb' 200",
+  addFrom: "'aaaa' 20, 'bbbb' 50",
+  addTo: "'aaaa' 30, 'bbbb' 100",
+}, [
+  {at: -0.3, expect: "'aaaa' 117, 'bbbb' 235"},
+  {at: 0, expect: "'aaaa' 120, 'bbbb' 250"},
+  {at: 0.5, expect: "'aaaa' 125, 'bbbb' 275"},
+  {at: 1, expect: "'aaaa' 130, 'bbbb' 300"},
+  {at: 1.5, expect: "'aaaa' 135, 'bbbb' 325"},
+]);
+
+test_composition({
+  property: 'font-variation-settings',
+  underlying: "'test' 100",
+  addFrom: "'aaaa' 20, 'bbbb' 50",
+  addTo: "'aaaa' 30, 'bbbb' 100",
+}, [
+  {at: -0.3, expect: "'aaaa' 17, 'bbbb' 35"},
+  {at: 0, expect: "'aaaa' 20, 'bbbb' 50"},
+  {at: 0.5, expect: "'aaaa' 25, 'bbbb' 75"},
+  {at: 1, expect: "'aaaa' 30, 'bbbb' 100"},
+  {at: 1.5, expect: "'aaaa' 35, 'bbbb' 125"},
+]);
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html
new file mode 100644
index 0000000..7ea0e93b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with the intrinsicSizes function returning a bad value will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.float {
+  float: left;
+  height: 100px;
+  width: 50%;
+}
+
+.fc {
+  display: flow-root;
+  height: 100px;
+}
+
+@supports (display: layout(bad-return)) {
+  .test {
+    display: layout(bad-return);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="float"></div>
+  <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-return', class {
+  async intrinsicSizes() { return 42; }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html
new file mode 100644
index 0000000..2078a49
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#get-a-layout-class-instance">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing constructor will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.float {
+  float: left;
+  width: 50%;
+  height: 100px;
+}
+
+.fc {
+  display: flow-root;
+  height: 100px;
+}
+
+@supports (display: layout(throwing-ctor)) {
+  .test {
+    display: layout(throwing-ctor);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="float"></div>
+  <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-ctor', class {
+  constructor() { throw Error('fail!'); }
+  async intrinsicSizes() {}
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/error.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/error.https.html
new file mode 100644
index 0000000..3a6665d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/error.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing intrinsicSizes function will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.float {
+  float: left;
+  height: 100px;
+  width: 50%;
+}
+
+.fc {
+  display: flow-root;
+  height: 100px;
+}
+
+@supports (display: layout(throwing-intrinsic-sizes)) {
+  .test {
+    display: layout(throwing-intrinsic-sizes);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="float"></div>
+  <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-intrinsic-sizes', class {
+  async intrinsicSizes() { throw Error('fail!'); }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html
new file mode 100644
index 0000000..6808e14
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  border: solid 2px;
+  height: 100px;
+  width: min-content;
+}
+</style>
+
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html
new file mode 100644
index 0000000..c21d157
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class performing intrinsicSizes on an invalid child will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.test > div {
+  height: 100px;
+}
+
+@supports (display: layout(bad-child-layout)) {
+  .test {
+    display: layout(bad-child-layout);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-child-layout', class {
+  static get inputProperties() { return ['--fail']; }
+
+  async intrinsicSizes(children, _, styleMap) {
+    if (styleMap.get('--fail').toString() !== 'true') {
+      this.child = children[0];
+    }
+
+    // Try to perform layout on the child. If its invalid (we skipped the if
+    // statement above) we should fallback to block layout.
+    const childIntrinsicSize = await this.child.intrinsicSizes();
+
+    return { maxContentSize: 100, minContentSize: 100 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+function raf() {
+  return new Promise((resolve) => {
+    requestAnimationFrame(() => {
+      resolve();
+    });
+  });
+}
+
+(async function() {
+  if (typeof CSS.layoutWorklet === 'undefined') {
+    takeScreenshot();
+    return;
+  }
+
+  await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+
+  // Ensure that all instances have a child to perform an invalid intrinsic size upon.
+  const test = document.getElementsByClassName('test')[0];
+  for (let i = 0; i < 100; i++) {
+    test.innerHTML = '<div><div>';
+    await raf();
+  }
+
+  // The next layout should mean that we will fallback to block.
+  test.innerHTML = '<div></div>';
+  test.style.setProperty('--fail', 'true');
+
+  // Finish up the test.
+  await raf();
+  await raf();
+  takeScreenshot();
+})();
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html
new file mode 100644
index 0000000..c5ec721b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with an intrinsicSizes function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.child {
+  height: 100px;
+}
+
+@supports (display: layout(no-promise)) {
+  .test {
+    display: layout(no-promise);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('no-promise', class {
+  intrinsicSizes() { return { minContentSize: 100 }; }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html
new file mode 100644
index 0000000..f56e331
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with an intrinsicSizes function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  width: min-content;
+}
+
+.child {
+  height: 100px;
+}
+
+@supports (display: layout(unresolved-promise)) {
+  .test {
+    display: layout(unresolved-promise);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('unresolved-promise', class {
+  intrinsicSizes() { return new Promise(() => { /* never resolves */ }); }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute-ref.html
new file mode 100644
index 0000000..2f23f68b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute-ref.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<style>
+.test {
+  background: green;
+  position: absolute;
+}
+
+.container-1 {
+  border: solid 2px;
+  position: relative;
+  height: 200px;
+  width: 300px;
+}
+
+.container-2 {
+  border: solid 2px;
+  position: relative;
+  height: 25px;
+  width: 25px;
+}
+
+.horizontal {
+  writing-mode: horizontal-tb;
+}
+
+.vertical {
+  writing-mode: vertical-rl;
+}
+
+</style>
+
+<div class="container-1">
+  <div class="horizontal test" style="height: 100px; width: 100px; bottom: 0px;"></div>
+  <div class="vertical test" style="height: 100px; width: 100px; right: 0px;"></div>
+</div>
+
+<div class="container-2">
+  <div class="horizontal test" style="height: 25px; width: 50px; bottom: 0px;"></div>
+</div>
+
+<div class="container-2">
+  <div class="vertical test" style="height: 50px; width: 25px; right: 0px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute.https.html
new file mode 100644
index 0000000..be654ec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/absolute.https.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="absolute-ref.html">
+<meta name="assert" content="This test checks that the absolute positioning respects the intrinsicSizes function." />
+
+<style>
+.test {
+  background: red;
+  position: absolute;
+}
+
+@supports (display: layout(test-layout)) {
+  .test {
+    display: layout(test-layout);
+    background: green;
+  }
+}
+
+.container-1 {
+  border: solid 2px;
+  position: relative;
+  height: 200px;
+  width: 300px;
+}
+
+.container-2 {
+  border: solid 2px;
+  position: relative;
+  height: 25px;
+  width: 25px;
+}
+
+.horizontal {
+  writing-mode: horizontal-tb;
+}
+
+.vertical {
+  writing-mode: vertical-rl;
+}
+
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="container-1">
+  <div class="horizontal test" style="height: 100px; bottom: 0px;"></div>
+  <div class="vertical test" style="width: 100px; right: 0px;"></div>
+</div>
+
+<div class="container-2">
+  <div class="horizontal test" style="height: 25px; bottom: 0px;"></div>
+</div>
+
+<div class="container-2">
+  <div class="vertical test" style="width: 25px; right: 0px;"></div>
+</div>
+
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+  async intrinsicSizes() {
+    return { maxContentSize: 100, minContentSize: 50 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html
new file mode 100644
index 0000000..0584286
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-replaced-percentage-ref.html">
+<meta name="assert" content="This test checks that intrinsicSizes is calculated correctly for a replaced child element with a percentage height." />
+<style>
+.test {
+  background: red;
+  height: 50px;
+  width: min-content;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <canvas width=100 height=100 style="height: 100%;"></canvas>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == 50 &&
+        childrenSizes[0].maxContentSize == 50) {
+      return { maxContentSize: 100, minContentSize: 50 };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html
new file mode 100644
index 0000000..42e8207b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-replaced-percentage-ref.html">
+<meta name="assert" content="This test checks that intrinsicSizes is calculated correctly for a replaced child element with a percentage height." />
+<style>
+.test {
+  background: red;
+  height: 50px;
+  width: min-content;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div style="height: 50%">
+    <canvas width=100 height=100 style="height: 100%;"></canvas>
+  </div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == 25 &&
+        childrenSizes[0].maxContentSize == 25) {
+      return { maxContentSize: 100, minContentSize: 50 };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html
new file mode 100644
index 0000000..762740f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  height: 50px;
+  width: 50px;
+}
+</style>
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html
new file mode 100644
index 0000000..3702d72
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  height: 100px;
+  width: 50px;
+}
+</style>
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01.https.html
new file mode 100644
index 0000000..c0a00e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-01.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-01-ref.html">
+<meta name="assert" content="This test checks that passing child intrinsicSizes to a parent works correctly." />
+<style>
+.test {
+  background: red;
+  height: 100px;
+  width: min-content;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+
+  .child {
+    display: layout(child);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == MIN_CONTENT_SIZE &&
+        childrenSizes[0].maxContentSize == MAX_CONTENT_SIZE) {
+      return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+
+registerLayout('child', class {
+  async intrinsicSizes() {
+    return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html
new file mode 100644
index 0000000..76c885e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  height: 100px;
+  width: 75px;
+}
+</style>
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02.https.html
new file mode 100644
index 0000000..030ecfc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-02.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-02-ref.html">
+<meta name="assert" content="This test checks that setting a child's intrinsicSizes does not override its min-width." />
+<style>
+.test {
+  background: red;
+  height: 100px;
+  width: min-content;
+}
+
+.child {
+  min-width: 75px;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+
+  .child {
+    display: layout(child);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+  static get childInputProperties() { return ['min-width']; }
+
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == child.styleMap.get('min-width').value &&
+        childrenSizes[0].maxContentSize == MAX_CONTENT_SIZE) {
+      return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+
+registerLayout('child', class {
+  async intrinsicSizes() {
+    return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-03.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-03.https.html
new file mode 100644
index 0000000..8b540cf9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-03.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-02-ref.html">
+<meta name="assert" content="This test checks that setting a child's intrinsicSizes does not override its max-width." />
+<style>
+.test {
+  background: red;
+  height: 100px;
+  width: max-content;
+}
+
+.child {
+  max-width: 75px;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+
+  .child {
+    display: layout(child);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+  static get childInputProperties() { return ['max-width']; }
+
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == MIN_CONTENT_SIZE &&
+        childrenSizes[0].maxContentSize == child.styleMap.get('max-width').value) {
+      return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+
+registerLayout('child', class {
+  async intrinsicSizes() {
+    return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html
new file mode 100644
index 0000000..e21085c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-01-ref.html">
+<meta name="assert" content="This test checks that the child intrinsicSizes returns the min/max size contributions." />
+<style>
+.test {
+  background: red;
+  height: 100px;
+  width: min-content;
+}
+
+@supports (display: layout(parent)) {
+  .test {
+    display: layout(parent);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+  <div style="width: 100px;">
+    <div style="width: 200px;"></div>
+  </div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+  async intrinsicSizes(children, edges, styleMap) {
+    const childrenSizes = await Promise.all(children.map((child) => {
+        return child.intrinsicSizes();
+    }));
+
+    if (childrenSizes[0].minContentSize == 100 &&
+        childrenSizes[0].maxContentSize == 100) {
+      return { maxContentSize: 100, minContentSize: 50 };
+    }
+    return { maxContentSize: 0, minContentSize: 0 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size-ref.html
new file mode 100644
index 0000000..6bccf07
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.test {
+  background: green;
+  border: solid 2px;
+  height: 100px;
+}
+</style>
+
+<div class="test" style="width: 96px"></div>
+<div class="test" style="width: 46px"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size.https.html
new file mode 100644
index 0000000..ed87dd5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/content-size.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="content-size-ref.html">
+<meta name="assert" content="This test checks that the min-content and max-content sizes respect the values returned from the intrinsicSizes function." />
+
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  height: 100px;
+}
+
+.test-1 {
+  width: max-content;
+}
+
+.test-2 {
+  width: min-content;
+}
+
+@supports (display: layout(test-layout)) {
+  .test {
+    display: layout(test-layout);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="test test-1"></div>
+<div class="test test-2"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+  async intrinsicSizes() {
+    return { maxContentSize: 100, minContentSize: 50 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats-ref.html
new file mode 100644
index 0000000..11cdb05
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<style>
+.test {
+  background: green;
+  border: solid 2px;
+}
+
+.container-1 {
+  height: 100px;
+  width: 300px;
+}
+
+.container-2 {
+  height: 50px;
+  width: 50px;
+}
+
+.container-3 {
+  height: 80px;
+  width: 80px;
+}
+
+.left {
+  float: left;
+  writing-mode: horizontal-tb;
+}
+
+.right {
+  float: right;
+  writing-mode: vertical-rl;
+}
+</style>
+
+<div class="container-1">
+  <div class="left test" style="height: 100px; width: 96px;"></div>
+  <div class="right test" style="height: 96px; width: 100px;"></div>
+</div>
+
+<div class="container-2">
+  <div class="left test" style="height: 25px; width: 46px;"></div>
+  <div class="right test" style="height: 46px; width: 25px;"></div>
+</div>
+
+<div class="container-3">
+  <div class="left test" style="height: 25px; width: 76px;"></div>
+  <div class="right test" style="height: 76px; width: 25px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats.https.html
new file mode 100644
index 0000000..5079b193
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/floats.https.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="floats-ref.html">
+<meta name="assert" content="This test checks that if the layout() is a float, the flow layout respects the intrinsicSizes function." />
+
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+}
+
+@supports (display: layout(test-layout)) {
+  .test {
+    display: layout(test-layout);
+    background: green;
+  }
+}
+
+.container-1 {
+  height: 100px;
+  width: 300px;
+}
+
+.container-2 {
+  height: 50px;
+  width: 50px;
+}
+
+.container-3 {
+  height: 80px;
+  width: 80px;
+}
+
+.left {
+  float: left;
+  writing-mode: horizontal-tb;
+}
+
+.right {
+  float: right;
+  writing-mode: vertical-rl;
+}
+
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="container-1">
+  <div class="left test" style="height: 100px"></div>
+  <div class="right test" style="width: 100px"></div>
+</div>
+
+<div class="container-2">
+  <div class="left test" style="height: 25px"></div>
+  <div class="right test" style="width: 25px"></div>
+</div>
+
+<div class="container-3">
+  <div class="left test" style="height: 25px"></div>
+  <div class="right test" style="width: 25px"></div>
+</div>
+
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+  async intrinsicSizes() {
+    return { maxContentSize: 100, minContentSize: 50 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html
new file mode 100644
index 0000000..2b2d8ca
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="invalid-ref.html">
+<meta name="assert" content="This test checks that min-content-size greater than max-content-size is correctly clamped to max-content-size." />
+
+<style>
+.test {
+  background: red;
+  border: solid 2px;
+  height: 100px;
+  width: max-content;
+}
+
+@supports (display: layout(invalid-sizes)) {
+  .test {
+    display: layout(invalid-sizes);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('invalid-sizes', class {
+  async intrinsicSizes() {
+    return { maxContentSize: 10, minContentSize: 200 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-ref.html
new file mode 100644
index 0000000..4159356
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/invalid-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  border: solid 2px;
+  height: 100px;
+  width: 6px;
+}
+</style>
+
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-max.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-max.https.html
new file mode 100644
index 0000000..5788037
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-max.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="negative-ref.html">
+<meta name="assert" content="This test checks that max-content-size is correctly clamped to zero." />
+
+<style>
+
+.test {
+  background: red;
+  border: solid 2px;
+  height: 100px;
+  width: max-content;
+}
+
+@supports (display: layout(max-content-size-negative)) {
+  .test {
+    display: layout(max-content-size-negative);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('max-content-size-negative', class {
+  async intrinsicSizes() {
+    return { maxContentSize: -100 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-min.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-min.https.html
new file mode 100644
index 0000000..c614a2f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-min.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="negative-ref.html">
+<meta name="assert" content="This test checks that min-content-size is correctly clamped to zero." />
+
+<style>
+
+.test {
+  background: red;
+  border: solid 2px;
+  height: 100px;
+  width: min-content;
+}
+
+@supports (display: layout(min-content-size-negative)) {
+  .test {
+    display: layout(min-content-size-negative);
+    background: green;
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('min-content-size-negative', class {
+  async intrinsicSizes() {
+    return { minContentSize: -100 };
+  }
+  async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-ref.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-ref.html
new file mode 100644
index 0000000..6808e14
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/intrinsic-sizes/negative-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+  background: green;
+  border: solid 2px;
+  height: 100px;
+  width: min-content;
+}
+</style>
+
+<div class="result"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha-ref.html
index 519b359..532b1bd 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha-ref.html
@@ -28,9 +28,8 @@
   var canvas = document.getElementById(canvasID);
   var context = canvas.getContext("2d", {alpha: hasAlpha});
   context.clearRect(0, 0, canvas.width, canvas.height);
-  context.strokeStyle = 'blue';
-  context.lineWidth = 4;
-  context.strokeRect(20, 20, 60, 60);
+  context.fillStyle = 'blue';
+  context.fillRect(20, 20, 60, 60);
 };
 
 drawCanvas('opaque', false);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha.https.html
index 7f1e31b..c8fdc85 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/background-image-alpha.https.html
@@ -33,18 +33,16 @@
 registerPaint('opaque', class {
     static get contextOptions() { return {alpha: false}; }
     paint(ctx, geom) {
-        ctx.strokeStyle = 'blue';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(20, 20, 60, 60);
+        ctx.fillStyle = 'blue';
+        ctx.fillRect(20, 20, 60, 60);
     }
 });
 
 registerPaint('nonOpaque', class {
     static get contextOptions() { return {alpha: true}; }
     paint(ctx, geom) {
-        ctx.strokeStyle = 'blue';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(20, 20, 60, 60);
+        ctx.fillStyle = 'blue';
+        ctx.fillRect(20, 20, 60, 60);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001-ref.html
index 83edae1..3e7db50 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 100, 100);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 100, 100);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001.https.html
index eb7f671..50d75a5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-001.https.html
@@ -21,9 +21,8 @@
 <script id="code" type="text/worklet">
 registerPaint('geometry', class {
     paint(ctx, geom) {
-        ctx.strokeStyle = 'green';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+        ctx.fillStyle = 'green';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002-ref.html
index ab964db..b03fcd02 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 200, 200);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 200, 200);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002.https.html
index e636aa7..06be523c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-002.https.html
@@ -21,9 +21,8 @@
 <script id="code" type="text/worklet">
 registerPaint('geometry', class {
     paint(ctx, geom) {
-        ctx.strokeStyle = 'green';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+        ctx.fillStyle = 'green';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-001.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-001.https.html
index 51373a52..dbb4c38 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-001.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-001.https.html
@@ -23,7 +23,6 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         ctx.fillStyle = 'green';
-        ctx.beginPath();
         ctx.rect(0, 0, geom.width, geom.height);
         ctx.fill();
     }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002-ref.html
index f3c65e6..3b3b2bc3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 50, 20);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 50, 20);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html
index d55761b..6f86517 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html
@@ -22,9 +22,8 @@
 <script id="code" type="text/worklet">
 registerPaint('geometry', class {
     paint(ctx, geom) {
-        ctx.strokeStyle = 'green';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+        ctx.fillStyle = 'green';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003-ref.html
index 8e1eb027..a21a990 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 60, 80);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 60, 80);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html
index 6d5bdd2..a3792caa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html
@@ -22,9 +22,8 @@
 <script id="code" type="text/worklet">
 registerPaint('geometry', class {
     paint(ctx, geom) {
-        ctx.strokeStyle = 'green';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+        ctx.fillStyle = 'green';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001-ref.html
index bb0aa40..23a48d5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001-ref.html
@@ -15,9 +15,8 @@
 // So in this ref test, we create a 200*200 canvas. We draw to a 220*220 area
 // and scale it to fit the 200*200 canvas.
 context.scale(200/220, 200/220);
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 220, 220);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 220, 220);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001.https.html
index ff7f56e..76813ea 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-001.https.html
@@ -24,11 +24,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (geom.width == 220 && geom.height == 220)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002-ref.html
index 0eb84ec..050c6a9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 90, 90);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 90, 90);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002.https.html
index d6e47f0..4c686b9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-002.https.html
@@ -24,11 +24,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (geom.width == 90 && geom.height == 90)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003-ref.html
index b17c9ffc..ef14f77 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003-ref.html
@@ -8,9 +8,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 80, 120);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 80, 120);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003.https.html
index 36af043c..ce343df 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-003.https.html
@@ -24,11 +24,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (geom.width == 80 && geom.height == 120)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004-ref.html
index c32fdd8f..764b6e57 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004-ref.html
@@ -15,9 +15,8 @@
 // In this ref html, we draw to a 140*140 area, but scale it to fit the 120*120
 // canvas.
 context.scale(120/140, 120/140);
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 140, 140);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 140, 140);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004.https.html
index 0f483cd5..8dd80c7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/geometry-border-image-004.https.html
@@ -24,11 +24,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (geom.width == 140 && geom.height == 140)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/non-registered-property-value.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/non-registered-property-value.https.html
index 5b237e01..774cb4e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/non-registered-property-value.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/non-registered-property-value.https.html
@@ -23,9 +23,8 @@
   static get inputProperties() { return ['--foo']; }
   paint(ctx, geom, properties) {
     let fooValue = parseFloat(properties.get('--foo').toString());
-    ctx.strokeStyle = 'green';
-    ctx.lineWidth = 4;
-    ctx.strokeRect(0, 0, fooValue, fooValue);
+    ctx.fillStyle = 'green';
+    ctx.fillRect(0, 0, fooValue, fooValue);
   }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments-ref.html
index 3352acf6..3675fc1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments-ref.html
@@ -28,9 +28,8 @@
   var canvas = document.getElementById(canvasID);
   var context = canvas.getContext("2d", {alpha: true});
   context.clearRect(0, 0, canvas.width, canvas.height);
-  context.strokeStyle = color;
-  context.lineWidth = 4;
-  context.strokeRect(20, 20, 60, 60);
+  context.fillStyle = color;
+  context.fillRect(20, 20, 60, 60);
 };
 
 drawCanvas('box-green', 'green');
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments.https.html
index 615027c..c08069c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-arguments.https.html
@@ -35,9 +35,8 @@
     static get contextOptions() { return {alpha: true}; }
     static get inputArguments() { return ['<color>']; }
     paint(ctx, geom, properties, args) {
-        ctx.strokeStyle = args[0].toString();
-        ctx.lineWidth = 4;
-        ctx.strokeRect(20, 20, 60, 60);
+        ctx.fillStyle = args[0].toString();
+        ctx.fillRect(20, 20, 60, 60);
     }
 });
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments-ref.html
index 99adfd27..6391d17f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments-ref.html
@@ -28,13 +28,12 @@
   var canvas = document.getElementById(canvasID);
   var context = canvas.getContext("2d", {alpha: true});
   context.clearRect(0, 0, canvas.width, canvas.height);
-  context.strokeStyle = color;
-  context.lineWidth = width;
-  context.strokeRect(40, 40, 120, 120);
+  context.fillStyle = color;
+  context.fillRect(40, 40, width, width);
 };
 
-drawCanvas('box-1', 'rgb(50, 100, 150)', '5px');
-drawCanvas('box-2', 'rgb(150, 100, 50)', '10px');
+drawCanvas('box-1', 'rgb(50, 100, 150)', '50px');
+drawCanvas('box-2', 'rgb(150, 100, 50)', '100px');
 
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments.https.html
index 3a1e579..fc303bf 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint-function-arguments.https.html
@@ -9,11 +9,11 @@
 }
 
 #canvas-box-1 {
-  background-image: paint(box, rgb(50, 100, 150), 5px);
+  background-image: paint(box, rgb(50, 100, 150), 50px);
 }
 
 #canvas-box-2 {
-  background-image: paint(box, rgb(150, 100, 50), 10px);
+  background-image: paint(box, rgb(150, 100, 50), 100px);
 }
 
 #background {
@@ -35,9 +35,9 @@
     static get contextOptions() { return {alpha: true}; }
     static get inputArguments() { return ['<color>', '<length>']; }
     paint(ctx, geom, properties, args) {
-        ctx.strokeStyle = args[0].toString();
-        ctx.lineWidth = args[1].toString();
-        ctx.strokeRect(40, 40, 120, 120);
+        ctx.fillStyle = args[0].toString();
+        let size = args[1].toString();
+        ctx.fillRect(40, 40, size, size);
     }
 });
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-composite.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-composite.https.html
index edf8a766..d654ba49 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-composite.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-composite.https.html
@@ -72,3 +72,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter-ref.html
index 4ca6383..2e4b979 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter-ref.html
@@ -58,3 +58,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter.https.html
index 9d598c7..a53fff9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-filter.https.html
@@ -105,3 +105,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient-ref.html
index a8064f59..f3644a92 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient-ref.html
@@ -22,3 +22,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient.https.html
index 1887f52..594f42b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-gradient.https.html
@@ -39,3 +39,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths-ref.html
index 7557411b..313a71e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths-ref.html
@@ -30,3 +30,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths.https.html
index 0e04168f..ae29930 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-paths.https.html
@@ -47,3 +47,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows-ref.html
index 268db49..94aea6ff 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows-ref.html
@@ -21,3 +21,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows.https.html
index b641dab8..124819f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-shadows.https.html
@@ -38,3 +38,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform-ref.html
index e863f36..08893127 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform-ref.html
@@ -20,3 +20,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform.https.html
index d052b8c..b264d1d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/paint2d-transform.https.html
@@ -37,3 +37,4 @@
 </script>
 </body>
 </html>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-001.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-001.https.html
index 486f379d..d18259e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-001.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-001.https.html
@@ -33,11 +33,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html
index 5c7b3aca0..c597558 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html
index 81904ee6..4d5daa7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html
index 9bf264b..bd1e5651 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html
index 24769f47..16744ec 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html
@@ -31,11 +31,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-006.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-006.https.html
index a6fcc16c..2fbbec7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-006.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-006.https.html
@@ -30,11 +30,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html
index 462cfb6..1fc435fc 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html
@@ -33,11 +33,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-008.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-008.https.html
index d5c18b0..9543d2d88 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-008.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-008.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html
index 7cfdf91..41e8411a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html
@@ -32,11 +32,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html
index 142ca0c..44bbab5b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html
@@ -32,11 +32,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html
index 23eb9d3..09f8b02 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html
@@ -30,11 +30,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html
index fa2c6b5..4a05b6fcf 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html
index adc1c03..ef8bf905 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html
@@ -29,11 +29,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-014.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-014.https.html
index d041ae3..715dab8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-014.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-014.https.html
@@ -31,11 +31,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-015.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-015.https.html
index 8ebe3e7c..4c8cfeb 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-015.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-015.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-016.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-016.https.html
index ccd0595..aa5eda8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-016.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-016.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html
index 476e29f..2ba8d99 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html
@@ -32,11 +32,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018-ref.html
index 05da4ed..55b841f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018-ref.html
@@ -1,12 +1,11 @@
 <!DOCTYPE html>
 <html>
 <body>
-<p>This test result should show a rect with black border, where the rect is
-filled with green on the lower right corner. The registerPaint('failureIndicator')
+<p>This test result should show a green rect. The registerPaint('failureIndicator')
 will be called twice and the inputArguments will return two different strings,
 which will throw an exception and the paint function with 'failureIndicator'
 should never be called. In other words, there should be no red painted in the result.</p>
-<canvas id ="canvas" width="100" height="100" style="border:1px solid black"></canvas>
+<canvas id ="canvas" width="100" height="100"></canvas>
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html
index e6a31cb..1554cc6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html
@@ -9,15 +9,13 @@
 }
 
 #canvas-geometry {
-    border:1px solid black;
     background-image: paint(failureIndicator), paint(geometry);
 }
 </style>
 <script src="/common/reftest-wait.js"></script>
 <script src="/common/worklet-reftest.js"></script>
 <body>
-<p>This test result should show a rect with black border, where the rect is
-filled with green on the lower right corner. The registerPaint('failureIndicator')
+<p>This test result should show a green rect. The registerPaint('failureIndicator')
 will be called twice and the inputArguments will return two different strings,
 which will throw an exception and the paint function with 'failureIndicator'
 should never be called. In other words, there should be no red painted in the result.</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-019.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-019.https.html
index 309ec800..d0a6285 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-019.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-019.https.html
@@ -32,11 +32,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-020.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-020.https.html
index 7e00b641..7797eb4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-020.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-020.https.html
@@ -31,11 +31,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html
index 8fa043a8..22d6d5a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html
@@ -34,11 +34,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html
index 2ff27d7..9434807 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html
@@ -32,11 +32,10 @@
 registerPaint('geometry', class {
     paint(ctx, geom) {
         if (testsPassed)
-            ctx.strokeStyle = 'green';
+            ctx.fillStyle = 'green';
         else
-            ctx.strokeStyle = 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-ref.html
index 086bc7b..8622120 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/parse-input-arguments-ref.html
@@ -5,9 +5,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 100, 100);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 100, 100);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html
index 133b923..408ba497 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html
@@ -18,9 +18,8 @@
 registerPaint('geometry', class {
   static get inputProperties() { return ['--color']; }
   paint(ctx, geom, styleMap) {
-    ctx.strokeStyle = styleMap.get('--color').toString();
-    ctx.lineWidth = 4;
-    ctx.strokeRect(0, 0, geom.width, geom.height);
+    ctx.fillStyle = styleMap.get('--color').toString();
+    ctx.fillRect(0, 0, geom.width, geom.height);
   }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html
index aadbfec..b65bcd5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html
@@ -21,9 +21,8 @@
   paint(ctx, geom, styleMap) {
     let value = styleMap.get('--length');
     let pass = value.value === 100 && value.unit === 'px';
-    ctx.strokeStyle = pass ? 'green' : 'red';
-    ctx.lineWidth = 4;
-    ctx.strokeRect(0, 0, geom.width, geom.height);
+    ctx.fillStyle = pass ? 'green' : 'red';
+    ctx.fillRect(0, 0, geom.width, geom.height);
   }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-stylemap.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-stylemap.https.html
index 4a6b4db5..3dec98d9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-stylemap.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/registered-property-stylemap.https.html
@@ -41,9 +41,8 @@
             pass &= Array.from(styleMap).filter(e => e[0] == '--prop')[0][1].length == 4;
             pass &= Array.from(styleMap).filter(e => e[0] == '--prop')[0][1].every(isExpected);
 
-            ctx.strokeStyle = pass ? 'green' : 'red';
-            ctx.lineWidth = 4;
-            ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = pass ? 'green' : 'red';
+            ctx.fillRect(0, 0, geom.width, geom.height);
           }
         });`
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/resources/utils.js b/third_party/blink/web_tests/external/wpt/css/css-paint-api/resources/utils.js
index 7efe85f2..e968644 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/resources/utils.js
@@ -44,9 +44,8 @@
         let serialize = (v) => '[' + v.constructor.name + ' ' + v.toString() + ']';
         let actual = expectedKeys.map(k => styleMap.getAll(k).map(serialize).join(', ')).join(' | ');
         let expected = expectedKeys.map(k => expectedData[k].join(', ')).join(' | ');
-        ctx.strokeStyle = (actual === expected) ? 'green' : 'red';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+        ctx.fillStyle = (actual === expected) ? 'green' : 'red';
+        ctx.fillRect(0, 0, geom.width, geom.height);
       }
     });`
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image-ref.html
index 2fe4d0c..ac936dd 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image-ref.html
@@ -5,9 +5,8 @@
 <script>
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext("2d");
-context.strokeStyle = 'green';
-context.lineWidth = 4;
-context.strokeRect(0, 0, 100, 100);
+context.fillStyle = 'green';
+context.fillRect(0, 0, 100, 100);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image.https.html
index 8e5f2f8..6a58da3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-background-image.https.html
@@ -41,17 +41,16 @@
                 serialized = properties[i].toString() + ': [null]';
             serializedStrings.push(serialized);
         }
-        ctx.strokeStyle = 'green';
+        ctx.fillStyle = 'green';
         if (serializedStrings[0] != "--bar: [CSSUnparsedValue=]")
-            ctx.strokeStyle = 'red';
+            ctx.fillStyle = 'red';
         if (serializedStrings[1] != "--foo: [CSSUnparsedValue= bar]")
-            ctx.strokeStyle = 'blue';
+            ctx.fillStyle = 'blue';
         if (serializedStrings[2] != "empty-cells: [CSSKeywordValue=show]")
-            ctx.strokeStyle = 'yellow';
+            ctx.fillStyle = 'yellow';
         if (serializedStrings[3] != "margin-left: [CSSUnitValue=2px]")
-            ctx.strokeStyle = 'cyan';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'cyan';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo-ref.html
index cd8ea6b..823fc257 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo-ref.html
@@ -25,9 +25,8 @@
 document.addEventListener('DOMContentLoaded', function() {
     var canvas = document.querySelector('canvas');
     var context = canvas.getContext("2d");
-    context.strokeStyle = 'green';
-    context.lineWidth = 4;
-    context.strokeRect(0, 0, 30, 10);
+    context.fillStyle = 'green';
+    context.fillRect(0, 0, 30, 10);
 });
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo.https.html
index 017b23a..7fde66ec 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-before-pseudo.https.html
@@ -45,15 +45,14 @@
                 serialized = properties[i].toString() + ': [null]';
             serializedStrings.push(serialized);
         }
-        ctx.strokeStyle = 'green';
+        ctx.fillStyle = 'green';
         if (serializedStrings[0] != "--bar: [CSSUnparsedValue=]")
-            ctx.strokeStyle = 'red';
+            ctx.fillStyle = 'red';
         if (serializedStrings[1] != "--foo: [CSSUnparsedValue= bar]")
-            ctx.strokeStyle = 'blue';
+            ctx.fillStyle = 'blue';
         if (serializedStrings[2] != "margin-left: [CSSUnitValue=2px]")
-            ctx.strokeStyle = 'yellow';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'yellow';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo-ref.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo-ref.html
index f9b116dc..8f337c5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo-ref.html
@@ -22,9 +22,8 @@
 document.addEventListener('DOMContentLoaded', function() {
     var canvas = document.querySelector('canvas');
     var context = canvas.getContext("2d");
-    context.strokeStyle = 'green';
-    context.lineWidth = 4;
-    context.strokeRect(0, 0, 10, 10);
+    context.fillStyle = 'green';
+    context.fillRect(0, 0, 10, 10);
 });
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html
index d3c31a05..6789137 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html
@@ -41,13 +41,12 @@
                 serialized = properties[i].toString() + ': [null]';
             serializedStrings.push(serialized);
         }
-        ctx.strokeStyle = 'green';
+        ctx.fillStyle = 'green';
         if (serializedStrings[0] != "color: [CSSStyleValue=rgb(255, 0, 0)]")
-            ctx.strokeStyle = 'red';
+            ctx.fillStyle = 'red';
         if (serializedStrings[1] != "line-height: [CSSUnitValue=2px]")
-            ctx.strokeStyle = 'blue';
-        ctx.lineWidth = 4;
-        ctx.strokeRect(0, 0, geom.width, geom.height);
+            ctx.fillStyle = 'blue';
+        ctx.fillRect(0, 0, geom.width, geom.height);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-013.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-013.html
index 18f00d17..427578f9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-013.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-013.html
@@ -28,6 +28,7 @@
   <li class="string">item</li>
   <li class="content">item</li>
 </ol>
+<script src="/common/reftest-wait.js"></script>
 <script>
 "use strict";
 addEventListener("load", function() {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001-notref.html b/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001-notref.html
new file mode 100644
index 0000000..aafa2b0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001-notref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Rest Reference</title>
+<style>
+table {
+  outline: 1px solid blue;
+  outline-offset: 10px;
+}
+</style>
+<table>
+  Some content
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001.html b/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001.html
new file mode 100644
index 0000000..4b6f469
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/outline-offset-table-001.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>outline-offset applies to tables</title>
+<link rel="help" href="https://drafts.csswg.org/css-ui/#propdef-outline">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1603049">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="mismatch" href="outline-offset-table-001-notref.html">
+<style>
+table { outline: 1px solid blue }
+</style>
+<table>
+  Some content
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/ch-recalc-on-font-load.html b/third_party/blink/web_tests/external/wpt/css/css-values/ch-recalc-on-font-load.html
new file mode 100644
index 0000000..625521b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/ch-recalc-on-font-load.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<title>Length unit 'ch' should be recalculated after loading a web font</title>
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.container {
+  font: 25px/1 "custom font", monospace;
+}
+
+.test {
+  width: 1ch;
+}
+</style>
+
+<div class="container">
+  <div class="test"></div>
+</div>
+
+<div class="container" style="display: contents">
+  <div class="test"></div>
+</div>
+
+<div class="container" style="display: none">
+  <div class="test"></div>
+</div>
+
+<script>
+function parseWidthInPx(element) {
+  const value = CSSNumericValue.parse(getComputedStyle(element).width);
+  if (!value || !(value instanceof CSSUnitValue) || value.unit !== 'px')
+    throw 'Cannot parse width in pixels';
+  return value.value;
+}
+
+const testCases = document.querySelectorAll('.test');
+
+const asyncTests = [
+  async_test('ch in a normal div should be recalculated after loading a web font'),
+  async_test('ch in display:contents should be recalculated after loading a web font'),
+  async_test('ch in display:none should be recalculated after loading a web font')
+];
+
+// Before loading custom font, tests should be rendered with monospace
+// fallback and have a '1ch' measurement much shorter than 25px.
+for (let i = 0; i < testCases.length; ++i) {
+  asyncTests[i].step(() => {
+    const widthPx = parseWidthInPx(testCases[i]);
+    assert_less_than(widthPx, 24);
+  });
+}
+
+// Insert custom font into style sheet and load it
+const customFont = new FontFace('custom font', 'url(/fonts/Ahem.ttf)');
+document.fonts.add(customFont);
+
+// After loading custom font, tests should be rendered with the custom font,
+// which is Ahem, and have a '1ch' measurement that equals 25px.
+customFont.load().then(
+    () => {
+      for (let i = 0; i < testCases.length; ++i) {
+        asyncTests[i].step(() => {
+          const widthPx = parseWidthInPx(testCases[i]);
+          assert_approx_equals(widthPx, 25, 0.1);
+          asyncTests[i].done();
+        });
+      }
+    },
+    () => {
+      for (let i = 0; i < testCases.length; ++i) {
+        asyncTests[i].step(() => {
+          assert_unreached('Failed to load font');
+        });
+      }
+    }
+);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/getClientRects-inline-atomic-child.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/getClientRects-inline-atomic-child.html
new file mode 100644
index 0000000..f1f6fc5a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/getClientRects-inline-atomic-child.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#dom-element-getclientrects">
+<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+inline-block {
+  display: inline-block;
+  height: 100px;
+}
+</style>
+<body>
+  <div>
+    <span class="target">
+      <inline-block></inline-block>
+    </span>
+  </div>
+  <div>
+    <span class="target">
+      <span>
+        <inline-block></inline-block>
+      </span>
+    </span>
+  </div>
+  <div>
+    <span class="target">
+      <span>
+        <span>
+          <inline-block></inline-block>
+        </span>
+      </span>
+    </span>
+  </div>
+<script>
+for (let element of document.getElementsByClassName('target')) {
+  let rects = element.getClientRects();
+  test(() => {
+    assert_equals(rects.length, 1);
+    for (let rect of rects)
+      assert_not_equals(rect.height, 100);
+  });
+}
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js
index d1cb7cf..16a1c0e 100644
--- a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js
+++ b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js
@@ -1,6 +1,7 @@
 'use strict';
 (function() {
   var interpolationTests = [];
+  var compositionTests = [];
   var cssAnimationsData = {
     sharedStyle: null,
     nextID: 0,
@@ -301,7 +302,75 @@
     });
   }
 
-  function createTestTargets(interpolationMethods, interpolationTests, container) {
+  function createCompositionTestTargets(compositionContainer, compositionTest) {
+    var options = compositionTest.options;
+    var property = options.property;
+    var underlying = options.underlying;
+    var comparisonFunction = options.comparisonFunction;
+    var from = options.accumulateFrom || options.addFrom || options.replaceFrom;
+    var to = options.accumulateTo || options.addTo || options.replaceTo;
+    var fromComposite = 'accumulateFrom' in options ? 'accumulate' : 'addFrom' in options ? 'add' : 'replace';
+    var toComposite = 'accumulateTo' in options ? 'accumulate' : 'addTo' in options ? 'add' : 'replace';
+    const invalidFrom = 'addFrom' in options === 'replaceFrom' in options
+        && 'addFrom' in options === 'accumulateFrom' in options;
+    const invalidTo = 'addTo' in options === 'replaceTo' in options
+        && 'addTo' in options === 'accumulateTo' in options;
+    if (invalidFrom || invalidTo) {
+      test(function() {
+        assert_false(invalidFrom, 'Exactly one of accumulateFrom, addFrom, or replaceFrom must be specified');
+        assert_false(invalidTo, 'Exactly one of accumulateTo, addTo, or replaceTo must be specified');
+      }, `Composition tests must have valid setup`);
+    }
+
+    var testText = `Compositing: property <${property}> underlying [${underlying}] from ${fromComposite} [${from}] to ${toComposite} [${to}]`;
+    var testContainer = createElement(compositionContainer, 'div');
+    createElement(testContainer);
+
+    // Setup a standard equality function if an override is not provided.
+    if (!comparisonFunction) {
+      comparisonFunction = (actual, expected) => {
+        assert_equals(normalizeValue(actual), normalizeValue(expected));
+      };
+    }
+
+    return compositionTest.expectations.map(function(expectation) {
+      var actualTargetContainer = createTargetContainer(testContainer, 'actual');
+      var expectedTargetContainer = createTargetContainer(testContainer, 'expected');
+      var expectedStr = expectation.option || expectation.expect;
+      if (!isNeutralKeyframe(expectedStr)) {
+        expectedTargetContainer.target.style.setProperty(property, expectedStr);
+      }
+      var target = actualTargetContainer.target;
+      target.style.setProperty(property, underlying);
+      target.interpolate = function() {
+        webAnimationsInterpolation.interpolateComposite(property, from, fromComposite, to, toComposite, expectation.at, target);
+      };
+      target.measure = function() {
+        var expectedValue = getComputedStyle(expectedTargetContainer.target).getPropertyValue(property);
+        test(function() {
+
+          if (from && from !== neutralKeyframe) {
+            assert_true(CSS.supports(property, from), '\'from\' value should be supported');
+          }
+          if (to && to !== neutralKeyframe) {
+            assert_true(CSS.supports(property, to), '\'to\' value should be supported');
+          }
+          if (typeof underlying !== 'undefined') {
+            assert_true(CSS.supports(property, underlying), '\'underlying\' value should be supported');
+          }
+
+          comparisonFunction(
+              getComputedStyle(target).getPropertyValue(property),
+              expectedValue);
+        }, `${testText} at (${expectation.at}) should be [${sanitizeUrls(expectedStr)}]`);
+      };
+      return target;
+    });
+  }
+
+
+
+  function createTestTargets(interpolationMethods, interpolationTests, compositionTests, container) {
     var targets = [];
     for (var interpolationMethod of interpolationMethods) {
       var interpolationMethodContainer = createElement(container);
@@ -309,15 +378,17 @@
         [].push.apply(targets, createInterpolationTestTargets(interpolationMethod, interpolationMethodContainer, interpolationTest));
       }
     }
+    var compositionContainer = createElement(container);
+    for (var compositionTest of compositionTests) {
+      [].push.apply(targets, createCompositionTestTargets(compositionContainer, compositionTest));
+    }
     return targets;
   }
 
   function test_no_interpolation(options) {
     test_interpolation(options, expectNoInterpolation);
   }
-
-  function test_interpolation(options, expectations) {
-    interpolationTests.push({options, expectations});
+  function create_tests() {
     var interpolationMethods = [
       cssTransitionsInterpolation,
       cssTransitionAllInterpolation,
@@ -325,7 +396,7 @@
       webAnimationsInterpolation,
     ];
     var container = createElement(document.body);
-    var targets = createTestTargets(interpolationMethods, interpolationTests, container);
+    var targets = createTestTargets(interpolationMethods, interpolationTests, compositionTests, container);
     // Separate interpolation and measurement into different phases to avoid O(n^2) of the number of targets.
     for (var target of targets) {
       target.interpolate();
@@ -334,10 +405,20 @@
       target.measure();
     }
     container.remove();
-    interpolationTests = [];
   }
 
+  function test_interpolation(options, expectations) {
+    interpolationTests.push({options, expectations});
+    create_tests();
+    interpolationTests = [];
+  }
+  function test_composition(options, expectations) {
+    compositionTests.push({options, expectations});
+    create_tests();
+    compositionTests = [];
+  }
   window.test_interpolation = test_interpolation;
   window.test_no_interpolation = test_no_interpolation;
+  window.test_composition = test_composition;
   window.neutralKeyframe = neutralKeyframe;
 })();
diff --git a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-html.html b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-html.html
index ad65cc58..2660d1d6 100644
--- a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-html.html
+++ b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-html.html
@@ -76,4 +76,17 @@
         new DOMParser().parseFromString("", "text/foo-this-is-invalid");
     })
 }, "DOMParser throws on an invalid enum value")
+
+test(() => {
+   const doc = new DOMParser().parseFromString(`
+<html><body>
+<style>
+  @import url(/dummy.css)
+</style>
+<script>x = 8<\/script>
+</body></html>`, 'text/html');
+
+  assert_not_equals(doc.querySelector('script'), null, 'script must be found');
+  assert_equals(doc.x, undefined, 'script must not be executed');
+}, 'script is found synchronously even when there is a css import');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/encoding-detection/__dir__.headers b/third_party/blink/web_tests/external/wpt/encoding-detection/__dir__.headers
new file mode 100644
index 0000000..a50d2c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/encoding-detection/__dir__.headers
@@ -0,0 +1 @@
+X-Content-Type-Options: nosniff
diff --git a/third_party/blink/web_tests/external/wpt/encoding-detection/support/__dir__.headers b/third_party/blink/web_tests/external/wpt/encoding-detection/support/__dir__.headers
new file mode 100644
index 0000000..a50d2c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/encoding-detection/support/__dir__.headers
@@ -0,0 +1 @@
+X-Content-Type-Options: nosniff
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/fetch-destination-frame.https-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/fetch-destination-frame.https-expected.txt
deleted file mode 100644
index 4b0507d..0000000
--- a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/fetch-destination-frame.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Initialize global state
-FAIL frame fetches with a "frame" Request.destination assert_unreached: Wrong destination. Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js b/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js
index c1b6c50..a583b12 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js
@@ -4,7 +4,8 @@
         event.waitUntil(async function() {
             let destination = new URL(url).searchParams.get("dest");
             var result = "FAIL";
-            if (event.request.destination == destination) {
+            if (event.request.destination == destination ||
+                (event.request.destination == "empty" && destination == "")) {
               result = "PASS";
             }
             let cl = await clients.matchAll({includeUncontrolled: true});
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker.js b/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker.js
index f8e8e26..904009c 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/request/destination/resources/fetch-destination-worker.js
@@ -1,7 +1,8 @@
 self.addEventListener('fetch', function(event) {
     if (event.request.url.includes('dummy')) {
         let destination = new URL(event.request.url).searchParams.get("dest");
-        if (event.request.destination == destination) {
+        if (event.request.destination == destination ||
+            (event.request.destination == "empty" && destination == "")) {
             event.respondWith(fetch(event.request));
         } else {
             event.respondWith(Response.error());
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html
index e137a7e..806606c 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html
+++ b/third_party/blink/web_tests/external/wpt/fetch/api/request/request-structure.html
@@ -58,7 +58,7 @@
             break;
 
           case "destination":
-            defaultValue = "";
+            defaultValue = "empty";
             newValue = "worker";
             break;
 
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/download.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/fetch/metadata/download.tentative.https.sub.html
new file mode 100644
index 0000000..6f2a0434
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/download.tentative.https.sub.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=/fetch/metadata/resources/helper.js></script>
+<script src=/common/utils.js></script>
+<body>
+<script>
+  function create_test(host, expectations) {
+    async_test(t => {
+      let nonce = token();
+      let a = document.createElement('a');
+      a.download = '';
+      a.text = nonce;
+
+      let url = `https://${host}/fetch/metadata/resources/record-header.py?file=download` + nonce;
+      a.href = url;
+      document.body.appendChild(a);
+
+      test_driver.click(a);
+
+      t.step_timeout(_ => {
+        validate_expectations("download" + nonce, expectations, `{{host}} -> ${host} download`);
+        t.done();
+      }, 1000);
+    }, `{{host}} -> ${host} download`);
+  }
+
+  // Only testing same-origin a download because same-site and cross-site is not supported.
+  create_test("{{host}}:{{ports[https][0]}}", {
+    "site": "same-origin",
+    "user": "",
+    "mode": "navigate",
+    "dest": "empty"
+  });
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade-prefetch.optional.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade-prefetch.optional.tentative.sub.html
index e2715a6..970eb337 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade-prefetch.optional.tentative.sub.html
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade-prefetch.optional.tentative.sub.html
@@ -8,7 +8,7 @@
 <script>
   "use strict";
   let nonce = "{{uuid()}}";
-  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": ""};
+  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": "empty"};
 
   testPrefetch(nonce, "Https downgrade-upgrade", MultipleRedirectTo, expected);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.tentative.sub.html
index 37b24151..907cf5c 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.tentative.sub.html
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.tentative.sub.html
@@ -19,9 +19,9 @@
 <div id="fontTest">Downgraded then upgraded font</div>
 <script>
   let nonce = "{{$id}}";
-  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": ""};
+  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": "font"};
 
-  // Validate various scenarios handle a request that redirects from https => http
+  // Validate various scenarios handle a request that redirects from https => http => https
   // correctly and avoids disclosure of any Sec- headers.
   RunCommonRedirectTests("Https downgrade-upgrade", MultipleRedirectTo, expected);
 
@@ -54,7 +54,7 @@
             "site": "cross-site",
             "user": undefined,
             "mode": "cors",
-            "dest": undefined
+            "dest": "image"
           }, "Https downgrade-upgrade image => No headers");
         });
   }, "Https downgrade-upgrade image => No headers");
@@ -66,7 +66,7 @@
     t.add_cleanup(_ => {
       header = null;
     });
-    assert_header_equals(header, {"site": "cross-site", "user": "", "mode": "no-cors", "dest": ""},
+    assert_header_equals(header, {"site": "cross-site", "user": "", "mode": "no-cors", "dest": "script"},
         "Https downgrade-upgrade script => No headers");
   }, "Https downgrade-upgrade script => No headers");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade-prefetch.optional.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade-prefetch.optional.tentative.sub.html
index 45fd4ef..c69f0e9 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade-prefetch.optional.tentative.sub.html
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade-prefetch.optional.tentative.sub.html
@@ -8,7 +8,7 @@
 <script>
   "use strict";
   let nonce = "{{uuid()}}";
-  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": ""};
+  let expected = {"site": "cross-site", "user": "", "mode": "cors", "dest": "empty"};
 
   testPrefetch(nonce, "Http upgrade", upgradeRedirectTo, expected);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade.tentative.sub.html
index c471906..133576c 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade.tentative.sub.html
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/redirect/redirect-http-upgrade.tentative.sub.html
@@ -19,7 +19,7 @@
     <div id="fontTest">Upgraded font</div>
     <script>
   let nonce = "{{$id}}";
-  let expected = { "site": "cross-site", "user": "", "mode": "cors", "dest": "" };
+  let expected = { "site": "cross-site", "user": "", "mode": "cors", "dest": "font" };
 
   // Validate various scenarios handle a request that redirects from http => https correctly and add the proper Sec- headers.
   RunCommonRedirectTests("Http upgrade", upgradeRedirectTo, expected);
@@ -51,7 +51,7 @@
            "site": "cross-site",
            "user": undefined,
            "mode": "cors",
-           "dest": undefined,
+           "dest": "image",
          }, "Http upgrade image => No headers");
       });
   }, "Http upgrade image => No headers");
@@ -61,7 +61,7 @@
 <script>
   test(t => {
     t.add_cleanup(_ => { header = null; });
-    assert_header_equals(header, { "site": "cross-site", "user": "", "mode": "no-cors", "dest": "" }, "Http upgrade script => No headers");
+    assert_header_equals(header, { "site": "cross-site", "user": "", "mode": "no-cors", "dest": "script" }, "Http upgrade script => No headers");
   }, "Http upgrade script => No headers");
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/resources/redirectTestHelper.sub.js b/third_party/blink/web_tests/external/wpt/fetch/metadata/resources/redirectTestHelper.sub.js
index e5547e7..8654356 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/metadata/resources/redirectTestHelper.sub.js
+++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/resources/redirectTestHelper.sub.js
@@ -79,6 +79,8 @@
       let expectation = { ...expectedResults };
       if (expectation['mode'] != '')
         expectation['mode'] = 'navigate';
+      if (expectation['dest'] == 'font')
+        expectation['dest'] = 'iframe';
       assert_header_equals(e.data, expectation, testNamePrefix + ' iframe');
       t.done();
     }));
@@ -97,6 +99,8 @@
       let expectation = { ...expectedResults };
       if (expectation['mode'] != '')
         expectation['mode'] = 'navigate';
+      if (expectation['dest'] == 'font')
+        expectation['dest'] = 'document';
       assert_header_equals(e.data, expectation, testNamePrefix + ' top level navigation');
       t.done();
     }));
@@ -111,6 +115,8 @@
         let expectation = { ...expectedResults };
         if (expectation['mode'] != '')
           expectation['mode'] = 'navigate';
+        if (expectation['dest'] == 'font')
+          expectation['dest'] = 'embed';
         fetch('/fetch/metadata/resources/record-header.py?retrieve=true&file=' + key)
           .then(response => response.text())
           .then(t.step_func(text => assert_header_equals(text, expectation, testNamePrefix + ' embed')))
@@ -126,7 +132,7 @@
     let expectation = { ...expectedResults };
     if (expectation['mode'] != '')
       expectation['mode'] = 'cors';
-    if (expectation['dest'] == '' && testNamePrefix != "Https downgrade")
+    if (expectation['dest'] == 'font')
       expectation['dest'] = 'empty';
     return fetch(urlHelperMethod('resources/echo-as-json.py?' + key))
       .then(r => r.json())
@@ -142,6 +148,8 @@
         let expectation = { ...expectedResults };
         if (expectation['mode'] != '')
           expectation['mode'] = 'navigate';
+        if (expectation['dest'] == 'font')
+          expectation['dest'] = 'object';
         fetch('/fetch/metadata/resources/record-header.py?retrieve=true&file=' + key)
           .then(response => response.text())
           .then(t.step_func(text => assert_header_equals(text, expectation, testNamePrefix + ' object')))
@@ -182,6 +190,8 @@
         let expectation = { ...expectedResults };
         if (expectation['mode'] != '')
           expectation['mode'] = 'no-cors';
+        if (expectation['dest'] == 'font')
+          expectation['dest'] = 'style';
         fetch('/fetch/metadata/resources/record-header.py?retrieve=true&file=' + key)
           .then(response => response.text())
           .then(t.step_func(text => assert_header_equals(text, expectation, testNamePrefix + ' stylesheet')))
@@ -202,9 +212,11 @@
         let expectation = { ...expectedResults };
         if (expectation['mode'] != '')
           expectation['mode'] = 'cors';
+        if (expectation['dest'] == 'font')
+          expectation['dest'] = 'track';
         fetch('/fetch/metadata/resources/record-header.py?retrieve=true&file=' + key)
           .then(response => response.text())
-          .then(t.step_func(text => assert_header_equals(text, expectedResults, testNamePrefix + ' track')))
+          .then(t.step_func(text => assert_header_equals(text, expectation, testNamePrefix + ' track')))
           .then(resolve);
       });
       video.appendChild(el);
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/none.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/none.https.html
index b1bb6fe..f13a752 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/none.https.html
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/none.https.html
@@ -54,10 +54,17 @@
   let pageLoaded = false;
   const bc = new BroadcastChannel(token());
   let finished = false;
+  let doneCheck = _ => {
+    if (finished && pageLoaded) {
+      t.done();
+    }
+  }
   bc.onmessage = t.step_func((event) => {
     pageLoaded = true;
     let payload = event.data;
     assert_equals(payload, "loaded");
+
+    doneCheck();
   });
 
   const bc2 = new BroadcastChannel(token());
@@ -65,15 +72,11 @@
     finished = true;
     let payload = event.data;
     assert_equals(payload, "loaded");
+
+    doneCheck();
   });
 
   const win = window.open(`resources/navigate-require-corp.sub.html?channelName=${bc.name}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", "noopener");
   assert_equals(win, null);
-
-  t.step_timeout(() => {
-    assert_true(pageLoaded);
-    assert_true(finished);
-    t.done();
-  }, 500);
 }, `"require-corp" top-level noopener popup: navigating to "none" should succeed`);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html
index 4460037..49b2eb1 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html
@@ -72,10 +72,6 @@
 
   const win = window.open(`resources/navigate-none.sub.html?channelName=${bc.name}&to=/common/blank.html`, "_blank");
   t.add_cleanup(() => win.close());
-  t.step_timeout(() => {
-    assert_equals(pageLoaded, true);
-    t.done();
-  }, 2000);
 }, `"require-corp" top-level: creating a "none" popup should succeed.`);
 
 [
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen-expected.txt b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen-expected.txt
new file mode 100644
index 0000000..341f3ed3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Test that canvas.getContext('bitmaprenderer') returns an instance of ImageBitmapRenderingContext and ctx.canvas on a ImageBitmapRenderingContext returns the original OffscreenCanvas assert_object_equals: unexpected property "width"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen.html b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen.html
index 41cc6dc..05a920c 100644
--- a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen.html
+++ b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-creation-offscreen.html
@@ -3,15 +3,16 @@
 <title>Canvas's ImageBitmapRenderingContext test</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#the-imagebitmap-rendering-context">
 <script>
-var width = 10;
-var height = 10;
-
 test(function() {
-    var canvas = new OffscreenCanvas(60,60);
+    var width = 10;
+    var height = 10;
+    var canvas = new OffscreenCanvas(width, height);
     var ctx = canvas.getContext('bitmaprenderer');
     assert_true(ctx instanceof ImageBitmapRenderingContext);
-}, "Test that canvas.getContext('bitmaprenderer') returns an instance of ImageBitmapRenderingContext");
+    assert_true("canvas" in ctx);
+    assert_object_equals(canvas, ctx.canvas);
+}, "Test that canvas.getContext('bitmaprenderer') returns an instance of ImageBitmapRenderingContext and ctx.canvas on a ImageBitmapRenderingContext returns the original OffscreenCanvas");
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas-expected.txt b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas-expected.txt
new file mode 100644
index 0000000..8a5d001
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Test that ctx.canvas on a ImageBitmapRenderingContext returns the original canvas assert_object_equals: unexpected property "width"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas.html b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas.html
index eca7afe..9c3a1fb 100644
--- a/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas.html
+++ b/third_party/blink/web_tests/external/wpt/imagebitmap-renderingcontext/context-preserves-canvas.html
@@ -3,7 +3,7 @@
 <title>Canvas's ImageBitmapRenderingContext test</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#the-imagebitmap-rendering-context">
 <script>
 var width = 10;
 var height = 10;
@@ -14,6 +14,8 @@
     canvas.height = height;
     var ctx = canvas.getContext('bitmaprenderer');
     var dstCanvas = ctx.canvas;
+    assert_true("canvas" in ctx);
+    assert_object_equals(canvas, ctx.canvas);
     assert_equals(dstCanvas.width, width);
     assert_equals(dstCanvas.height, height);
 }, "Test that ctx.canvas on a ImageBitmapRenderingContext returns the original canvas");
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/encrypted-media.idl b/third_party/blink/web_tests/external/wpt/interfaces/encrypted-media.idl
index 26c03f6..008b68b 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/encrypted-media.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/encrypted-media.idl
@@ -25,8 +25,9 @@
 };
 
 dictionary MediaKeySystemMediaCapability {
-             DOMString contentType = "";
-             DOMString robustness = "";
+   DOMString contentType = "";
+   DOMString? encryptionScheme = null;
+   DOMString robustness = "";
 };
 
 [Exposed=Window, SecureContext] interface MediaKeySystemAccess {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/media-playback-quality.idl b/third_party/blink/web_tests/external/wpt/interfaces/media-playback-quality.idl
index 71c83567..c3ee523 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/media-playback-quality.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/media-playback-quality.idl
@@ -12,4 +12,7 @@
   readonly attribute DOMHighResTimeStamp creationTime;
   readonly attribute unsigned long droppedVideoFrames;
   readonly attribute unsigned long totalVideoFrames;
+
+  // Deprecated!
+  readonly attribute unsigned long corruptedVideoFrames;
 };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
index 3b2be61c..e30fc38 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
@@ -559,12 +559,12 @@
 
 [Exposed=Window]
 interface RTCDTMFToneChangeEvent : Event {
-  constructor(DOMString type, RTCDTMFToneChangeEventInit eventInitDict);
+  constructor(DOMString type, optional RTCDTMFToneChangeEventInit eventInitDict = {});
   readonly attribute DOMString tone;
 };
 
 dictionary RTCDTMFToneChangeEventInit : EventInit {
-  required DOMString tone;
+  DOMString tone = "";
 };
 
 partial interface RTCPeerConnection {
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html
index d24fbf04..ebb12a6 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html
+++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html
@@ -5,7 +5,7 @@
     <title>mathsize and css keywords</title>
   </head>
   <body>
-    <p>Test passes if you see ten "A" of equal size:</p>
+    <p>Test passes if you see 14 "A" of equal size:</p>
     <math>
       <mtext>A</mtext>
       <mtext>A</mtext>
@@ -17,6 +17,10 @@
       <mtext>A</mtext>
       <mtext>A</mtext>
       <mtext>A</mtext>
+      <mtext>A</mtext>
+      <mtext>A</mtext>
+      <mtext>A</mtext>
+      <mtext>A</mtext>
     </math>
   </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords.html
index 6390ebf..84c31d7 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords.html
+++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/mathsize-attribute-css-keywords.html
@@ -10,7 +10,7 @@
     <script src="/mathml/support/feature-detection.js"></script>
   </head>
   <body>
-    <p>Test passes if you see ten "A" of equal size:</p>
+    <p>Test passes if you see 14 "A" of equal size:</p>
     <math>
       <mtext>A</mtext>
       <mtext mathsize="xx-small">A</mtext>
@@ -22,6 +22,10 @@
       <mtext mathsize="xx-large">A</mtext>
       <mtext mathsize="larger">A</mtext>
       <mtext mathsize="smaller">A</mtext>
+      <mtext mathsize="xx-ſmall">A</mtext>
+      <mtext mathsize="x-ſmall">A</mtext>
+      <mtext mathsize="ſmall">A</mtext>
+      <mtext mathsize="ſmaller">A</mtext>
     </math>
    <script src="/mathml/support/feature-detection.js"></script>
    <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mathsize");</script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/sw-install.html b/third_party/blink/web_tests/external/wpt/resource-timing/resources/sw-install.html
index 0a2fbe2..2f1dccf1a 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/resources/sw-install.html
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/sw-install.html
@@ -1,31 +1,33 @@
 <!DOCTYPE html>
 <script>
-function service_worker_unregister(documentUrl) {
-  return navigator.serviceWorker.getRegistration(documentUrl)
-    .then(function(registration) {
-        if (registration)
-          return registration.unregister();
-      })
+async function service_worker_unregister(scope) {
+  var absoluteScope = (new URL(scope, window.location).href);
+  const registration = await navigator.serviceWorker.getRegistration(scope);
+  if (registration && registration.scope === absoluteScope)
+    return registration.unregister();
 }
 
-function service_worker_unregister_and_register(url, scope, options = {}) {
+async function service_worker_unregister_and_register(url, scope, options = {}) {
   if (!scope || scope.length == 0)
     return Promise.reject(new Error('tests must define a scope'));
 
   options.scope = scope;
-  return service_worker_unregister(scope)
-    .then(function() {
-        return navigator.serviceWorker.register(url, options);
-      })
+  await service_worker_unregister(scope);
+  return navigator.serviceWorker.register(url, options);
 }
 
-function wait_for_activation_event(worker) {
+function wait_for_state_activated(worker) {
+  if (worker.state === 'activated')
+    return Promise.resolve();
+
+  if (worker.state === 'redundant') {
+    return Promise.reject(new Error('worker is redundant'));
+  }
+
   return new Promise(function(resolve) {
-      worker.addEventListener('statechange', function(event) {
-          if (worker.state == 'activated')
-            resolve(true);
-          else if (worker.state == 'redundant')
-            resolve(false);
+      worker.addEventListener('statechange', function() {
+          if (worker.state === 'activated')
+            resolve();
         });
     });
 }
@@ -33,15 +35,20 @@
 (async () => {
   var script = '/resource-timing/resources/sw.js';
   var scope = '/resource-timing/resources/';
-  await service_worker_unregister_and_register(script, scope)
-    .then(function(registration) {
-        return wait_for_activation_event(registration.installing);
-    })
-    .then(function(did_install) {
-      if (window.opener) {
-        window.opener.postMessage("installed", "*");
-      }
-    })
+  const registration = await service_worker_unregister_and_register(script, scope);
+  await wait_for_state_activated(registration.installing);
+  const opener = window.opener;
+  if (!opener)
+    return;
+
+  opener.postMessage("installed", "*");
+  async function unregister(e) {
+    if (e.data === "unregister") {
+      await registration.unregister();
+      opener.postMessage("unregistered", "*");
+    }
+  }
+  window.addEventListener("message", e => unregister(e));
 })();
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/workerStart-tao-protected.https.html b/third_party/blink/web_tests/external/wpt/resource-timing/workerStart-tao-protected.https.html
index cf5c2e3..f9b50f7 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/workerStart-tao-protected.https.html
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/workerStart-tao-protected.https.html
@@ -24,9 +24,7 @@
 promise_test(t => {
   return new Promise(resolve => {
     addEventListener("message", e => {
-      if (e.data == "installed") {
-        // Close window once we get an event that it was installed
-        openee.close();
+      if (e.data === 'installed') {
         performance.clearResourceTimings();
         resolve();
       }
@@ -59,6 +57,19 @@
 
 // Add iframe to remote origin - page with TAO
 promise_test(t => {
+  let unregisterPromise = new Promise(resolve => {
+    addEventListener("message", e => {
+      if (e.data === "unregistered") {
+        resolve();
+      }
+    });
+  });
+  t.add_cleanup(async () => {
+    openee.postMessage("unregister", "*");
+    await unregisterPromise;
+    // Close the window.
+    openee.close();
+  });
   return new Promise((resolve, reject) => {
     const observer = new PerformanceObserver(list => {
       const entries = list.getEntries();
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
index 50421b4..e0ddac7 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
@@ -120,7 +120,7 @@
       credentials: expected_credentials,
       redirect: 'follow',
       integrity: '',
-      destination: '',
+      destination: 'empty',
       message: 'fetch (url:' + actual_url + ' mode:' + mode + ' credentials:' +
                credentials + ')'
     };
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies-expected.txt b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies-expected.txt
deleted file mode 100644
index b80d771..0000000
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/click-focus-delegatesFocus-tabindex-varies-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL click on host with delegatesFocus, #aboveSlot tabindex = 2, #slot and #slotted tabindex = 1 assert_equals: expected Element node <div tabindex="2">aboveSlot</div> but got null
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-method-delegatesFocus-expected.txt b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-method-delegatesFocus-expected.txt
deleted file mode 100644
index 0f2b44e..0000000
--- a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-method-delegatesFocus-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS focus() on host with delegatesFocus, all tabindex=0
-PASS focus() on host with delegatesFocus & tabindex =-1, all other tabindex=0
-PASS focus() on host with delegatesFocus & no tabindex, all other tabindex=0
-FAIL focus() on host with delegatesFocus & tabindex = 0, all other tabindex=-1 assert_equals: expected Element node <div tabindex="-1">aboveSlots</div> but got null
-PASS focus() on host with delegatesFocus, all without tabindex
-FAIL focus() on host with delegatesFocus, all tabindex=-1 assert_equals: expected Element node <div tabindex="-1">aboveSlots</div> but got null
-PASS focus() on host with delegatesFocus & tabindex=0, #belowSlots with tabindex=0
-PASS focus() on host with delegatesFocus & tabindex=0, #outside with tabindex=0
-PASS focus() on host with delegatesFocus & tabindex=0, #aboveSlots and #belowSlots with tabindex=0
-FAIL focus() on host with delegatesFocus & tabindex=0, #aboveSlots with tabindex=0 and #belowSlots with tabindex=1 assert_equals: expected Element node <div tabindex="0">aboveSlots</div> but got Element node <div tabindex="1">belowSlots</div>
-PASS focus() on host with delegatesFocus & tabindex=0, #slottedToFirstSlot, #slottedToSecondSlot, #belowSlots  with tabindex=0
-PASS focus() on host with delegatesFocus and already-focused non-first shadow descendant
-PASS focus() on host with delegatesFocus with another host with no delegatesFocus and a focusable child
-PASS focus() on host with delegatesFocus with another host with delegatesFocus and a focusable child
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/svg/embedded/image-fractional-width-vertical-fidelity.svg b/third_party/blink/web_tests/external/wpt/svg/embedded/image-fractional-width-vertical-fidelity.svg
index 81f27922..4409ee32 100644
--- a/third_party/blink/web_tests/external/wpt/svg/embedded/image-fractional-width-vertical-fidelity.svg
+++ b/third_party/blink/web_tests/external/wpt/svg/embedded/image-fractional-width-vertical-fidelity.svg
@@ -2,10 +2,11 @@
   <title>Vertical fidelity of &#x3c;image&#x3e; element with fractional width</title>
   <h:link rel="help" href="https://svgwg.org/svg2-draft/embedded.html#ImageElement"/>
   <h:link rel="match" href="reference/green-rect-100x100.svg"/>
-  <rect width="100" height="100" fill="red"/>
+  <rect x="95" width="5" height="100" fill="green"/>
+  <rect width="95" height="100" fill="red"/>
   <g clip-path="url(#c)">
     <clipPath id="c">
-      <rect width="100" height="100"/>
+      <rect width="95" height="100"/>
     </clipPath>
     <image href="data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='xMinYMin'%3e
                  %3crect width='100' height='100' fill='green'/%3e%3c/svg%3e"
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
index d674501..ceca8121 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
@@ -60,6 +60,9 @@
     def set_window(self, handle):
         self.webdriver.switch_to_window(handle)
 
+    def load(self, url):
+        self.webdriver.get(url)
+
     def wait(self):
         while True:
             try:
@@ -269,7 +272,7 @@
 
     def __init__(self, browser, server_config, timeout_multiplier=1,
                  close_after_done=True, capabilities=None, debug_info=None,
-                 **kwargs):
+                 supports_eager_pageload=True, **kwargs):
         """Selenium-based executor for testharness.js tests"""
         TestharnessExecutor.__init__(self, browser, server_config,
                                      timeout_multiplier=timeout_multiplier,
@@ -279,6 +282,7 @@
             self.script_resume = f.read()
         self.close_after_done = close_after_done
         self.window_id = str(uuid.uuid4())
+        self.supports_eager_pageload = supports_eager_pageload
 
     def is_alive(self):
         return self.protocol.is_alive()
@@ -308,10 +312,15 @@
         parent_window = protocol.testharness.close_old_windows()
         # Now start the test harness
         protocol.base.execute_script("window.open('about:blank', '%s', 'noopener')" % self.window_id)
-        test_window = protocol.testharness.get_test_window(self.window_id, parent_window,
+        test_window = protocol.testharness.get_test_window(self.window_id,
+                                                           parent_window,
                                                            timeout=5*self.timeout_multiplier)
         self.protocol.base.set_window(test_window)
-        protocol.webdriver.get(url)
+        protocol.base.load(url)
+
+        if not self.supports_eager_pageload:
+            self.wait_for_load(protocol)
+
         handler = CallbackHandler(self.logger, protocol, test_window)
         while True:
             result = protocol.base.execute_script(
@@ -321,6 +330,29 @@
                 break
         return rv
 
+    def wait_for_load(self, protocol):
+        # pageLoadStrategy=eager doesn't work in Chrome so try to emulate in user script
+        loaded = False
+        seen_error = False
+        while not loaded:
+            try:
+                loaded = protocol.base.execute_script("""
+var callback = arguments[arguments.length - 1];
+if (location.href === "about:blank") {
+  callback(false);
+} else if (document.readyState !== "loading") {
+  callback(true);
+} else {
+  document.addEventListener("readystatechange", () => {if (document.readyState !== "loading") {callback(true)}});
+}""", asynchronous=True)
+            except Exception:
+                # We can get an error here if the script runs in the initial about:blank
+                # document before it has navigated, with the driver returning an error
+                # indicating that the document was unloaded
+                if seen_error:
+                    raise
+                seen_error = True
+
 
 class SeleniumRefTestExecutor(RefTestExecutor):
     def __init__(self, browser, server_config, timeout_multiplier=1,
@@ -339,7 +371,7 @@
         self.close_after_done = close_after_done
         self.has_window = False
 
-        with open(os.path.join(here, "reftest-wait_webdriver.js")) as f:
+        with open(os.path.join(here, "test-wait.js" % {"classname": "reftest-wait"})) as f:
             self.wait_script = f.read()
 
     def reset(self):
@@ -355,8 +387,8 @@
             """return [window.outerWidth - window.innerWidth,
                        window.outerHeight - window.innerHeight];"""
         )
-        self.protocol.webdriver.set_window_size(0, 0)
-        self.protocol.webdriver.set_window_position(800 + width_offset, 600 + height_offset)
+        self.protocol.webdriver.set_window_position(0, 0)
+        self.protocol.webdriver.set_window_size(800 + width_offset, 600 + height_offset)
 
         result = self.implementation.run_test(test)
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
index c615e8e..5edbe21 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 497 tests; 468 PASS, 29 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 497 tests; 467 PASS, 30 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Test driver for asyncInitCertificate
@@ -471,7 +471,7 @@
 PASS RTCDTMFSender interface: attribute canInsertDTMF
 PASS RTCDTMFSender interface: attribute toneBuffer
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface object
-PASS RTCDTMFToneChangeEvent interface object length
+FAIL RTCDTMFToneChangeEvent interface object length assert_equals: wrong value for RTCDTMFToneChangeEvent.length expected 1 but got 2
 PASS RTCDTMFToneChangeEvent interface object name
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object's "constructor" property
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
index 70e9d6e6..0b83b4c 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
+++ b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
@@ -37,7 +37,6 @@
         .then((referenceSpace) => new Promise((resolve, reject) => {
           let counter = 0;
           function onFrame(time, vrFrame) {
-            session.requestAnimationFrame(onFrame);
             if (counter == 0) {
               t.step( () => {
                 // Expecting to not get a pose since none has been supplied
@@ -48,6 +47,14 @@
                 // Check that pose does not update pose within the same frame.
                 assert_equals(vrFrame.getViewerPose(referenceSpace), null);
               });
+
+              // In order to avoid race conditions, after we've set the viewer
+              // pose, we queue up the next requestAnimationFrame. This should
+              // ensure that the next frame will be able to get the appropriate
+              // pose.
+              // Note that since the next frame will immediately resolve and end
+              // the test we only need to request a new frame once, here.
+              session.requestAnimationFrame(onFrame);
             } else {
               t.step( () => {
                 let pose = vrFrame.getViewerPose(referenceSpace);
diff --git a/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-expected.png b/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-expected.png
index 4428e2e..55a0832 100644
--- a/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-expected.png
+++ b/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png b/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png
index 66435fe..3237c05 100644
--- a/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png
+++ b/third_party/blink/web_tests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/fast/css/counters/counterValueForElementById-expected.txt b/third_party/blink/web_tests/fast/css/counters/counterValueForElementById-expected.txt
index 61ab336..db24c333 100644
--- a/third_party/blink/web_tests/fast/css/counters/counterValueForElementById-expected.txt
+++ b/third_party/blink/web_tests/fast/css/counters/counterValueForElementById-expected.txt
@@ -1,8 +1,12 @@
 This is the test for internals.counterValueForElementById
    
+PASS internals.counterValue(document.getElementById('marker')) is '0'
 PASS internals.counterValue(document.getElementById('before')) is '0'
 PASS internals.counterValue(document.getElementById('after')) is '0'
+PASS internals.counterValue(document.getElementById('marker_before')) is '0 0'
+PASS internals.counterValue(document.getElementById('marker_after')) is '0 0'
 PASS internals.counterValue(document.getElementById('before_after')) is '0 0'
+PASS internals.counterValue(document.getElementById('marker_before_after')) is '0 0 0'
 PASS internals.counterValue(document.getElementById('twice')) is '0 0'
 PASS internals.counterValue(document.getElementById('point')) is '0.1'
 PASS internals.counterValue(document.getElementById('two-points')) is '0.1.2'
diff --git a/third_party/blink/web_tests/fast/css/counters/counterValueForElementById.html b/third_party/blink/web_tests/fast/css/counters/counterValueForElementById.html
index a9595c6..d3b3f38 100644
--- a/third_party/blink/web_tests/fast/css/counters/counterValueForElementById.html
+++ b/third_party/blink/web_tests/fast/css/counters/counterValueForElementById.html
@@ -4,6 +4,8 @@
         .reset { counter-reset: c; }
         .increment { counter-increment: c; }
         .increment2 { counter-increment: c 2; }
+        .show-marker { display: list-item; }
+        .show-marker::marker { content: counters(c, "."); }
         .show-before:before { content: counters(c, "."); }
         .show-after:after { content: counters(c, "."); }
         .show-twice:before { content: counters(c, ".") counters(c, "."); }
@@ -16,9 +18,13 @@
 <body>
     <div>This is the test for internals.counterValueForElementById</div>
 
+    <div class="reset"><span id="marker" class="show-marker"></span></div>
     <div class="reset"><span id="before" class="show-before"></span></div>
     <div class="reset"><span id="after" class="show-after"></span></div>
+    <div class="reset"><span id="marker_before" class="show-marker show-before"></span></div>
+    <div class="reset"><span id="marker_after" class="show-marker show-after"></span></div>
     <div class="reset"><span id="before_after" class="show-before show-after"></span></div>
+    <div class="reset"><span id="marker_before_after" class="show-marker show-before show-after"></span></div>
     <div class="reset"><span id="twice" class="show-twice"></span></div>
     <div class="reset">
         <span id="point" class="reset increment show-before">
@@ -35,9 +41,13 @@
         if (window.testRunner) {
             testRunner.dumpAsText();
 
+            shouldBe("internals.counterValue(document.getElementById('marker'))", "'0'");
             shouldBe("internals.counterValue(document.getElementById('before'))", "'0'");
             shouldBe("internals.counterValue(document.getElementById('after'))", "'0'");
+            shouldBe("internals.counterValue(document.getElementById('marker_before'))", "'0 0'");
+            shouldBe("internals.counterValue(document.getElementById('marker_after'))", "'0 0'");
             shouldBe("internals.counterValue(document.getElementById('before_after'))", "'0 0'");
+            shouldBe("internals.counterValue(document.getElementById('marker_before_after'))", "'0 0 0'");
             shouldBe("internals.counterValue(document.getElementById('twice'))", "'0 0'");
             shouldBe("internals.counterValue(document.getElementById('point'))", "'0.1'");
             shouldBe("internals.counterValue(document.getElementById('two-points'))", "'0.1.2'");
diff --git a/third_party/blink/web_tests/fast/events/drag-dataTransferItemList-file-handling.html b/third_party/blink/web_tests/fast/events/drag-dataTransferItemList-file-handling.html
index 32379544..0d3b110 100644
--- a/third_party/blink/web_tests/fast/events/drag-dataTransferItemList-file-handling.html
+++ b/third_party/blink/web_tests/fast/events/drag-dataTransferItemList-file-handling.html
@@ -14,9 +14,26 @@
     width: 200px;
 }
 </style>
+
+</head>
+<body>
+<p>To manually test, select a text file for the file input element, and then drag 'Drag Me' to 'Drop Here' and drop.
+<!-- TODO(https://crbug.com/438479): File handling has never been fully
+  implemented for DataTransferItemList.add, but is implemented in eventSender.
+  Therefore, this test succeeds when run through content_shell, but fails
+  when run manually. -->
+<input id="inputElement" type="file"></input>
+<div draggable="true" id="drag" ondragstart="dragstart(event)">Drag Me</div>
+<div id="drop" ondragenter="dragenter(event)" ondragover="dragover(event)" ondrop="drop(event)">Drop Here</div>
+</div>
+<div id="console"></div>
+
 <script>
-var testFile;
-var testItem;
+let testFile = null;
+const inputElement = document.getElementById('inputElement');
+inputElement.onchange = event => { testFile = inputElement.files[0]; };
+
+let testItem;
 function dragstart(event)
 {
     testItem = event.dataTransfer.items.add(testFile);
@@ -48,39 +65,27 @@
 
 function runTest()
 {
-    if (!window.testRunner)
-        return;
+  if (!window.testRunner)
+    return;
 
-    // First, we need to generate a File object to use for our tests.
-    eventSender.beginDragWithFiles(['test.txt']);
-    var inputElement = document.getElementsByTagName('input')[0];
-    eventSender.mouseMoveTo(inputElement.offsetLeft + inputElement.offsetWidth / 2,
-                            inputElement.offsetTop + inputElement.offsetHeight / 2);
-    eventSender.mouseUp();
-    testFile = inputElement.files[0];
+  // First, we need to generate a File object to use for our tests.
+  eventSender.beginDragWithFiles(['test.txt']);
+  eventSender.mouseMoveTo(inputElement.offsetLeft + inputElement.offsetWidth / 2,
+                          inputElement.offsetTop + inputElement.offsetHeight / 2);
+  eventSender.mouseUp();
 
-    // Now run the actual test.
-    var dragElement = document.getElementById('drag');
-    eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2,
-                            dragElement.offsetTop + dragElement.offsetHeight / 2);
-    eventSender.mouseDown();
-    eventSender.leapForward(100);
-    var dropElement = document.getElementById('drop');
-    eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2,
-                            dropElement.offsetTop + dropElement.offsetHeight / 2);
-    eventSender.mouseUp();
+  // Now run the actual test.
+  const dragElement = document.getElementById('drag');
+  eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2,
+                          dragElement.offsetTop + dragElement.offsetHeight / 2);
+  eventSender.mouseDown();
+  eventSender.leapForward(100);
+  const dropElement = document.getElementById('drop');
+  eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2,
+                          dropElement.offsetTop + dropElement.offsetHeight / 2);
+  eventSender.mouseUp();
 }
 
-</script>
-</head>
-<body>
-<p>To manually test, select a text file for the file input element, and then drag 'Drag Me' to 'Drop Here' and drop.
-<input type="file"></input>
-<div draggable="true" id="drag" ondragstart="dragstart(event)">Drag Me</div>
-<div id="drop" ondragenter="dragenter(event)" ondragover="dragover(event)" ondrop="drop(event)">Drop Here</div>
-</div>
-<div id="console"></div>
-<script>
 description("Tests DataTransferItemList file handling");
 window.jsTestIsAsync = true;
 
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-repeat-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-repeat-expected.png
deleted file mode 100644
index 1f8d2bda..0000000
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/svg/as-background-image/background-repeat-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/counters/counterValueForElementById-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/counters/counterValueForElementById-expected.txt
new file mode 100644
index 0000000..8d6b7d8
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/css/counters/counterValueForElementById-expected.txt
@@ -0,0 +1,18 @@
+This is the test for internals.counterValueForElementById
+   
+FAIL internals.counterValue(document.getElementById('marker')) should be 0. Was .
+PASS internals.counterValue(document.getElementById('before')) is '0'
+PASS internals.counterValue(document.getElementById('after')) is '0'
+FAIL internals.counterValue(document.getElementById('marker_before')) should be 0 0. Was 0.
+FAIL internals.counterValue(document.getElementById('marker_after')) should be 0 0. Was 0.
+PASS internals.counterValue(document.getElementById('before_after')) is '0 0'
+FAIL internals.counterValue(document.getElementById('marker_before_after')) should be 0 0 0. Was 0 0.
+PASS internals.counterValue(document.getElementById('twice')) is '0 0'
+PASS internals.counterValue(document.getElementById('point')) is '0.1'
+PASS internals.counterValue(document.getElementById('two-points')) is '0.1.2'
+PASS internals.counterValue(document.getElementById('greek')) is '0.α.β'
+PASS internals.counterValue(document.getElementById('three-greeks')) is '0.α.β 0.α.β 0.α.β'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/blink/web_tests/flag-specific/enable-gpu-rasterization/images/color-profile-mask-image-svg-expected.png
index 3981d053..ed88c12 100644
--- a/third_party/blink/web_tests/flag-specific/enable-gpu-rasterization/images/color-profile-mask-image-svg-expected.png
+++ b/third_party/blink/web_tests/flag-specific/enable-gpu-rasterization/images/color-profile-mask-image-svg-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom-expected.html b/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom-expected.html
index c96893e..7e6a765a 100644
--- a/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom-expected.html
+++ b/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom-expected.html
@@ -11,9 +11,8 @@
 var canvas = document.getElementById('output');
 var ctx = canvas.getContext('2d');
 ctx.rotate(10 * Math.PI / 180);
-ctx.strokeStyle = 'blue';
-ctx.lineWidth = 12;
-ctx.strokeRect(90, 30, 90, 90);
+ctx.fillStyle = 'blue';
+ctx.fillRect(90, 30, 90, 90);
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom.html b/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom.html
index 9015592..f52c334 100644
--- a/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom.html
+++ b/third_party/blink/web_tests/http/tests/csspaint/paint2d-zoom.html
@@ -16,9 +16,8 @@
 registerPaint('worklet', class {
     paint(ctx, geom) {
          ctx.rotate(10 * Math.PI / 180);
-         ctx.strokeStyle = 'blue';
-         ctx.lineWidth = 4;
-         ctx.strokeRect(30, 10, 30, 30);
+         ctx.fillStyle = 'blue';
+         ctx.fillRect(30, 10, 30, 30);
     }
 });
 </script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/global-listeners-sidebar-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/global-listeners-sidebar-a11y-test-expected.txt
index ff53d95c3..016cd8e 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/global-listeners-sidebar-a11y-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/global-listeners-sidebar-a11y-test-expected.txt
@@ -4,10 +4,10 @@
 ======== touchstart ========
 == Raw
 [expanded] WindowRemoveToggle Passiveglobal-listeners-sidebar-a11y-test.js:13
-    handler: () => console.log
-    once: false
-    passive: true
     useCapture: false
+    passive: true
+    once: false
+    handler: () => console.log
 Running the axe-core linter on the global listeners pane.
 aXe violations: []
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/datagrid.js b/third_party/blink/web_tests/http/tests/devtools/components/datagrid.js
index 98e86ba..8b6be25 100644
--- a/third_party/blink/web_tests/http/tests/devtools/components/datagrid.js
+++ b/third_party/blink/web_tests/http/tests/devtools/components/datagrid.js
@@ -40,7 +40,7 @@
   }
 
   var columns = [{id: 'id'}];
-  var dataGrid = new DataGrid.DataGrid(columns);
+  var dataGrid = new DataGrid.DataGrid({displayName: 'Test', columns});
   var a = new DataGrid.DataGridNode({id: 'a'});
   var aa = new DataGrid.DataGridNode({id: 'aa'});
   var aaa = new DataGrid.DataGridNode({id: 'aaa'});
@@ -111,7 +111,7 @@
   dumpNodes();
 
   var columns = [{id: 'id'}];
-  var dataGrid = new DataGrid.DataGrid(columns);
+  var dataGrid = new DataGrid.DataGrid({displayName: 'Test', columns});
   var a = new DataGrid.DataGridNode({id: 'TextData', secondCol: 'a foo'});
   var b = new DataGrid.DataGridNode({id: 'NullData', secondCol: null});
   var root = dataGrid.rootNode();
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/viewport-datagrid.js b/third_party/blink/web_tests/http/tests/devtools/components/viewport-datagrid.js
index a296f907..c161ae3 100644
--- a/third_party/blink/web_tests/http/tests/devtools/components/viewport-datagrid.js
+++ b/third_party/blink/web_tests/http/tests/devtools/components/viewport-datagrid.js
@@ -58,7 +58,7 @@
   }
 
   var columns = [{id: 'id', title: 'ID column', width: '250px'}];
-  var dataGrid = new DataGrid.ViewportDataGrid(columns);
+  var dataGrid = new DataGrid.ViewportDataGrid({displayName: 'Test', columns});
   var a = new DataGrid.ViewportDataGridNode({id: 'a'});
   var aa = new DataGrid.ViewportDataGridNode({id: 'aa'});
   var aaa = new DataGrid.ViewportDataGridNode({id: 'aaa'});
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt
index f075c857..7047e39a 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt
@@ -4,7 +4,7 @@
     foo: 239
     value: 239
     __proto__: A
-        foo: 239
         constructor: ƒ ()
+        foo: 239
         __proto__: Object
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-dir-es6-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-dir-es6-expected.txt
index 3a2e3bf..0eba6fd 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-dir-es6-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-dir-es6-expected.txt
@@ -9,85 +9,74 @@
     __proto__: Object
 console-dir-es6.js:23 Symbol()
 console-dir-es6.js:27 Map(1)
+    [[Entries]]
+        0: {Object => Object}
     size: (...)
     __proto__: Map
-    [[Entries]]: Array(1)
-        0: {Object => Object}
-        length: 1
 console-dir-es6.js:27 WeakMap
-    __proto__: WeakMap
-    [[Entries]]: Array(1)
+    [[Entries]]
         0: {Object => Object}
-        length: 1
-console-dir-es6.js:31 Set(1)
-    size: (...)
-    __proto__: Set
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
-console-dir-es6.js:31 WeakSet
-    __proto__: WeakSet
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
-console-dir-es6.js:39 Set(1)
-    size: (...)
-    __proto__: Set
-    [[Entries]]: Array(1)
-        0: Set(1)
-        length: 1
-console-dir-es6.js:42 WeakMap
     __proto__: WeakMap
-    [[Entries]]: Array(0)
-        length: 0
+console-dir-es6.js:31 Set(1)
+    [[Entries]]
+        0: Object
+    size: (...)
+    __proto__: Set
+console-dir-es6.js:31 WeakSet
+    [[Entries]]
+        0: Object
+    __proto__: WeakSet
+console-dir-es6.js:39 Set(1)
+    [[Entries]]
+        0: Set(1)
+    size: (...)
+    __proto__: Set
+console-dir-es6.js:42 WeakMap
+    [[Entries]]
+        No properties
+    __proto__: WeakMap
 console-dir-es6.js:50 MapIterator
+    [[Entries]]
+        0: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "keys"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-dir-es6.js:51 MapIterator
+    [[Entries]]
+        0: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-dir-es6.js:52 MapIterator
+    [[Entries]]
+        0: {Object => Object}
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(1)
-        0: {Object => Object}
-        length: 1
 console-dir-es6.js:50 SetIterator
+    [[Entries]]
+        0: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-dir-es6.js:51 SetIterator
+    [[Entries]]
+        0: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-dir-es6.js:52 SetIterator
+    [[Entries]]
+        0: {Object => Object}
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-dir-es6.js:90 Array(27)
     0: class 
     1: class classWithWhitespace
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-dir-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-dir-expected.txt
index 3bc64a1..22b6e3d 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-dir-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-dir-expected.txt
@@ -6,32 +6,32 @@
     length: 2
     __proto__: Array(0)
 console-dir.js:13 NodeList(1)
-    length: 1
     0: html
+    length: 1
     __proto__: NodeList
 console-dir.js:14 XPathResult
-    resultType: 4
-    numberValue: (...)
-    stringValue: (...)
     booleanValue: (...)
-    singleNodeValue: (...)
     invalidIteratorState: false
+    numberValue: (...)
+    resultType: 4
+    singleNodeValue: (...)
     snapshotLength: (...)
+    stringValue: (...)
     __proto__: XPathResult
 console-dir.js:24 Object
-    $foo5_: 0
-    " a b ": " a b "
-    c d: "c d"
     "": ""
     "  ": "  "
+    " a b ": " a b "
+    $foo5_: 0
     "a↵↵b↵c": "a↵↵b↵c"
+    c d: "c d"
     negZero: -0
     __proto__: Object
 console-dir.js:27 ƒ anonymous()
-    length: 0
-    name: ""
     arguments: null
     caller: null
+    length: 0
+    name: ""
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-dir.js:27
@@ -58,19 +58,19 @@
     [300000000 … 399999999]
     __proto__: TypedArray
 console-dir.js:47 Event
-    isTrusted: false
-    type: ""
-    target: null
-    currentTarget: null
-    eventPhase: 0
     bubbles: false
-    cancelable: false
-    defaultPrevented: false
-    composed: false
-    srcElement: null
-    returnValue: true
     cancelBubble: false
+    cancelable: false
+    composed: false
+    currentTarget: null
+    defaultPrevented: false
+    eventPhase: 0
+    isTrusted: false
     path: []
+    returnValue: true
+    srcElement: null
+    target: null
+    type: ""
     timeStamp: 0
     __proto__: Event
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-2-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-2-expected.txt
index a4f09e0..f18db6f 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-2-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-2-expected.txt
@@ -34,183 +34,167 @@
 SetIterator {{…}}
 Expanded all messages
 console-format-es6-2.js:15 MapIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "keys"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:16 [MapIterator]
     0: MapIterator {41, {…}}
     length: 1
     __proto__: Array(0)
 globals[0]
 MapIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "keys"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:15 MapIterator {42, {…}}
+    [[Entries]]
+        0: 42
+        1: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 42
-        1: Object
-        length: 2
 console-format-es6-2.js:16 [MapIterator]
     0: MapIterator {42, {…}}
     length: 1
     __proto__: Array(0)
 globals[1]
 MapIterator {42, {…}}
+    [[Entries]]
+        0: 42
+        1: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 42
-        1: Object
-        length: 2
 console-format-es6-2.js:15 MapIterator {41 => 42, {…} => {…}}
+    [[Entries]]
+        0: {41 => 42}
+        1: {Object => Object}
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(2)
-        0: {41 => 42}
-        1: {Object => Object}
-        length: 2
 console-format-es6-2.js:16 [MapIterator]
     0: MapIterator {41 => 42, {…} => {…}}
     length: 1
     __proto__: Array(0)
 globals[2]
 MapIterator {41 => 42, {…} => {…}}
+    [[Entries]]
+        0: {41 => 42}
+        1: {Object => Object}
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(2)
-        0: {41 => 42}
-        1: {Object => Object}
-        length: 2
 console-format-es6-2.js:15 SetIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:16 [SetIterator]
     0: SetIterator {41, {…}}
     length: 1
     __proto__: Array(0)
 globals[3]
 SetIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:15 SetIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:16 [SetIterator]
     0: SetIterator {41, {…}}
     length: 1
     __proto__: Array(0)
 globals[4]
 SetIterator {41, {…}}
+    [[Entries]]
+        0: 41
+        1: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
-console-format-es6-2.js:15 SetIterator {41, {…}}
+console-format-es6-2.js:15 SetIterator {41 => 41, {…} => {…}}
+    [[Entries]]
+        0: {41 => 41}
+        1: {Object => Object}
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:16 [SetIterator]
-    0: SetIterator {41, {…}}
+    0: SetIterator {41 => 41, {…} => {…}}
     length: 1
     __proto__: Array(0)
 globals[5]
-SetIterator {41, {…}}
+SetIterator {41 => 41, {…} => {…}}
+    [[Entries]]
+        0: {41 => 41}
+        1: {Object => Object}
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 0
     [[IteratorKind]]: "entries"
-    [[Entries]]: Array(2)
-        0: 41
-        1: Object
-        length: 2
 console-format-es6-2.js:15 MapIterator {{…}}
+    [[Entries]]
+        0: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 1
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-format-es6-2.js:16 [MapIterator]
     0: MapIterator {{…}}
     length: 1
     __proto__: Array(0)
 globals[6]
 MapIterator {{…}}
+    [[Entries]]
+        0: Object
     __proto__: Map Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 1
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-format-es6-2.js:15 SetIterator {{…}}
+    [[Entries]]
+        0: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 1
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 console-format-es6-2.js:16 [SetIterator]
     0: SetIterator {{…}}
     length: 1
     __proto__: Array(0)
 globals[7]
 SetIterator {{…}}
+    [[Entries]]
+        0: Object
     __proto__: Set Iterator
     [[IteratorHasMore]]: true
     [[IteratorIndex]]: 1
     [[IteratorKind]]: "values"
-    [[Entries]]: Array(1)
-        0: Object
-        length: 1
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-expected.txt
index 6df270c..b7c5528f 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-format-es6-expected.txt
@@ -119,8 +119,8 @@
 globals[4]
 Symbol(a)
 console-format-es6.js:15 {a: Symbol(), Symbol(a): 2}
-    getter: (...)
     a: Symbol()
+    getter: (...)
     Symbol(a): 2
     get getter: ƒ getter()
     __proto__: Object
@@ -130,8 +130,8 @@
     __proto__: Array(0)
 globals[5]
 {a: Symbol(), Symbol(a): 2}
-    getter: (...)
     a: Symbol()
+    getter: (...)
     Symbol(a): 2
     get getter: ƒ getter()
     __proto__: Object
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-format-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-format-expected.txt
index 54ab1e7..b9017637 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-format-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-format-expected.txt
@@ -465,12 +465,12 @@
 globals[25]
     <svg id="svg-node"></svg>
 console-format.js:21 {enumerableProp: 4, __underscoreEnumerableProp__: 5, __underscoreNonEnumerableProp: 2, abc: 3, getFoo: ƒ, …}
-    bar: (...)
     enumerableProp: 4
     __underscoreEnumerableProp__: 5
-    __underscoreNonEnumerableProp: 2
     abc: 3
+    bar: (...)
     getFoo: ƒ ()
+    __underscoreNonEnumerableProp: 2
     get bar: ƒ ()
     set bar: ƒ (x)
     __proto__: Object
@@ -480,12 +480,12 @@
     __proto__: Array(0)
 globals[26]
 {enumerableProp: 4, __underscoreEnumerableProp__: 5, __underscoreNonEnumerableProp: 2, abc: 3, getFoo: ƒ, …}
-    bar: (...)
     enumerableProp: 4
     __underscoreEnumerableProp__: 5
-    __underscoreNonEnumerableProp: 2
     abc: 3
+    bar: (...)
     getFoo: ƒ ()
+    __underscoreNonEnumerableProp: 2
     get bar: ƒ ()
     set bar: ƒ (x)
     __proto__: Object
@@ -514,16 +514,16 @@
 ƒ Object() { [native code] }
 console-format.js:21 {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
     constructor: ƒ Object()
-    __defineGetter__: ƒ __defineGetter__()
-    __defineSetter__: ƒ __defineSetter__()
     hasOwnProperty: ƒ hasOwnProperty()
-    __lookupGetter__: ƒ __lookupGetter__()
-    __lookupSetter__: ƒ __lookupSetter__()
     isPrototypeOf: ƒ isPrototypeOf()
     propertyIsEnumerable: ƒ propertyIsEnumerable()
+    toLocaleString: ƒ toLocaleString()
     toString: ƒ toString()
     valueOf: ƒ valueOf()
-    toLocaleString: ƒ toLocaleString()
+    __defineGetter__: ƒ __defineGetter__()
+    __defineSetter__: ƒ __defineSetter__()
+    __lookupGetter__: ƒ __lookupGetter__()
+    __lookupSetter__: ƒ __lookupSetter__()
     get __proto__: ƒ __proto__()
     set __proto__: ƒ __proto__()
 console-format.js:22 [{…}]
@@ -533,16 +533,16 @@
 globals[30]
 {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
     constructor: ƒ Object()
-    __defineGetter__: ƒ __defineGetter__()
-    __defineSetter__: ƒ __defineSetter__()
     hasOwnProperty: ƒ hasOwnProperty()
-    __lookupGetter__: ƒ __lookupGetter__()
-    __lookupSetter__: ƒ __lookupSetter__()
     isPrototypeOf: ƒ isPrototypeOf()
     propertyIsEnumerable: ƒ propertyIsEnumerable()
+    toLocaleString: ƒ toLocaleString()
     toString: ƒ toString()
     valueOf: ƒ valueOf()
-    toLocaleString: ƒ toLocaleString()
+    __defineGetter__: ƒ __defineGetter__()
+    __defineSetter__: ƒ __defineSetter__()
+    __lookupGetter__: ƒ __lookupGetter__()
+    __lookupSetter__: ƒ __lookupSetter__()
     get __proto__: ƒ __proto__()
     set __proto__: ƒ __proto__()
 console-format.js:21 ƒ ( /**/ foo/**/, /*/**/bar,
@@ -585,13 +585,13 @@
     __proto__: String
     [[PrimitiveValue]]: "abc"
 console-format.js:21 Uint16Array(3) [1, 2, 3]
+    0: 1
+    1: 2
+    2: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 1
-    1: 2
-    2: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format.js:22 [Uint16Array(3)]
@@ -600,13 +600,13 @@
     __proto__: Array(0)
 globals[34]
 Uint16Array(3) [1, 2, 3]
+    0: 1
+    1: 2
+    2: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 1
-    1: 2
-    2: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format.js:21 #text
@@ -624,11 +624,11 @@
 globals[36]
 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
 console-format.js:21 Uint8Array [3]
+    0: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format.js:22 [Uint8Array(1)]
@@ -637,11 +637,11 @@
     __proto__: Array(0)
 globals[37]
 Uint8Array [3]
+    0: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format.js:21 Uint8Array(400) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …]
@@ -734,10 +734,10 @@
     [[PrimitiveValue]]: 42
 console-format.js:21 String {"abc", 3: "foo", 01: "foo", a: "bar"}
     0: "a"
+    01: "foo"
     1: "b"
     2: "c"
     3: "foo"
-    01: "foo"
     a: "bar"
     length: 3
     __proto__: String
@@ -749,10 +749,10 @@
 globals[44]
 String {"abc", 3: "foo", 01: "foo", a: "bar"}
     0: "a"
+    01: "foo"
     1: "b"
     2: "c"
     3: "foo"
-    01: "foo"
     a: "bar"
     length: 3
     __proto__: String
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
index 11ada2c..1a32b572 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
@@ -2,10 +2,10 @@
 
 console-functions.js:27 ƒ simple() {}
 console-functions.js:28 ƒ simple()
-    length: 0
-    name: "simple"
     arguments: null
     caller: null
+    length: 0
+    name: "simple"
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:13
@@ -32,50 +32,50 @@
     [[Scopes]]: Scopes[1]
 console-functions.js:27 ƒ (){}
 console-functions.js:28 ƒ anonymous()
-    length: 0
-    name: ""
     arguments: null
     caller: null
+    length: 0
+    name: ""
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:16
     [[Scopes]]: Scopes[1]
 console-functions.js:27 ƒ (x, y){}
 console-functions.js:28 ƒ anonymous(x, y)
-    length: 2
-    name: ""
     arguments: null
     caller: null
+    length: 2
+    name: ""
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:17
     [[Scopes]]: Scopes[1]
 console-functions.js:27 ƒ namedArgs(x) {}
 console-functions.js:28 ƒ namedArgs(x)
-    length: 1
-    name: "namedArgs"
     arguments: null
     caller: null
+    length: 1
+    name: "namedArgs"
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:18
     [[Scopes]]: Scopes[1]
 console-functions.js:27 ƒ namedArgs2(x, y) {}
 console-functions.js:28 ƒ namedArgs2(x, y)
-    length: 2
-    name: "namedArgs2"
     arguments: null
     caller: null
+    length: 2
+    name: "namedArgs2"
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:19
     [[Scopes]]: Scopes[1]
 console-functions.js:27 ƒ ({}) {}
 console-functions.js:28 ƒ anonymous({})
-    length: 1
-    name: ""
     arguments: null
     caller: null
+    length: 1
+    name: ""
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: console-functions.js:20
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-log-object-with-getter-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-log-object-with-getter-expected.txt
index 686c13c..ed8b0ca 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-log-object-with-getter-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-log-object-with-getter-expected.txt
@@ -5,5 +5,5 @@
 console-log-object-with-getter.js:32 {}
 console-log-object-with-getter.js:30 {}foo: Objectget foo: ƒ ()set bar: ƒ (x)__proto__: Object
 console-log-object-with-getter.js:31 (2) [(...), empty]0: 1length: 2get 0: ƒ ()set 1: ƒ (x)__proto__: Array(0)
-console-log-object-with-getter.js:32 {}error: [Exception: custom stack]string: [Exception: "myString"]number: [Exception: 123]function: [Exception: ƒ ()]get error: ƒ error()get string: ƒ string()get number: ƒ number()get function: ƒ ()__proto__: Object
+console-log-object-with-getter.js:32 {}error: [Exception: custom stack]function: [Exception: ƒ ()]number: [Exception: 123]string: [Exception: "myString"]get error: ƒ error()get function: ƒ ()get number: ƒ number()get string: ƒ string()__proto__: Object
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-log-short-hand-method-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-log-short-hand-method-expected.txt
index 2a495519..5fdcaf3 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-log-short-hand-method-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-log-short-hand-method-expected.txt
@@ -2,8 +2,8 @@
 
 console-log-short-hand-method.js:24 {foo: ƒ, boo: ƒ, gen: ƒ}
     baz: (...)
-    foo: ƒ foo(a,b)
     boo: ƒ (c,d)
+    foo: ƒ foo(a,b)
     gen: ƒ* gen()
     get baz: ƒ baz()
     set baz: ƒ baz(x)
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-object-preview-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-object-preview-expected.txt
index 7179575..06fb11b4 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-object-preview-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-object-preview-expected.txt
@@ -56,13 +56,13 @@
 console-object-preview.js:62 Dense array with indexes and propeties
 console-object-preview.js:68 (150) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, …][0 … 99][100 … 149]property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9property_10: 10property_11: 11property_12: 12property_13: 13property_14: 14property_15: 15property_16: 16property_17: 17property_18: 18property_19: 19property_20: 20property_21: 21property_22: 22property_23: 23property_24: 24property_25: 25property_26: 26property_27: 27property_28: 28property_29: 29property_30: 30property_31: 31property_32: 32property_33: 33property_34: 34property_35: 35property_36: 36property_37: 37property_38: 38property_39:
 console-object-preview.js:70 Object with properties containing whitespaces
-console-object-preview.js:77 {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"}" a b ": " a b "c d: "c d""": """  ": "  ""a↵↵b↵c": "a↵↵b↵c"__proto__: Object
+console-object-preview.js:77 {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"}"": """  ": "  "" a b ": " a b ""a↵↵b↵c": "a↵↵b↵c"c d: "c d"__proto__: Object
 console-object-preview.js:79 Object with a document.all property
 console-object-preview.js:80 {all: HTMLAllCollection(4)}all: HTMLAllCollection(4) [html, head, base, body]__proto__: Object
 console-object-preview.js:82 Object with special numbers
-console-object-preview.js:84 {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0}nan: NaNposInf: InfinitynegInf: -InfinitynegZero: -0__proto__: Object
+console-object-preview.js:84 {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0}nan: NaNnegInf: -InfinitynegZero: -0posInf: Infinity__proto__: Object
 console-object-preview.js:86 Object with exactly 5 properties: expected to be lossless
 console-object-preview.js:87 {a: 1, b: 2, c: 3, d: 4, e: 5}a: 1b: 2c: 3d: 4e: 5__proto__: Object
-console-object-preview.js:89 {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false}null: nullundef: undefinedregexp: /^[regexp]$/gbool: false__proto__: Object
+console-object-preview.js:89 {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false}bool: falsenull: nullregexp: /^[regexp]$/gundef: undefined__proto__: Object
 console-object-preview.js:96 IHavePrivateProperties {regularProperty: 3, #privateProperty1: 1, #privateProperty2: 2}regularProperty: 3#privateProperty1: 1#privateProperty2: 2__proto__: Object
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-custom-framework-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-custom-framework-expected.txt
index 63e3c7c..07639ca8 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-custom-framework-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-custom-framework-expected.txt
@@ -5,6 +5,9 @@
 ======== click ========
 == Framework
 [expanded] button#inspectedNodeRemoveevent-listener-sidebar-custom-framework.js:30
+    useCapture: false
+    passive: false
+    once: false
     handler: function internalHandler(e)
           {
               console.log("I'm internal event handler");
@@ -13,36 +16,36 @@
               if (e.type === "customSecond")
                   customSecondEventListener(e);
           }
-    once: false
-    passive: false
-    useCapture: false
 
 ======== customFirst ========
 == FrameworkUser
 [expanded] button#inspectedNodeevent-listener-sidebar-custom-framework.js:20
+    useCapture: true
+    passive: false
+    once: false
     handler: function customFirstEventListener(e)
           {
               console.log("I'm first custom event listener");
           }
-    once: false
-    passive: false
-    useCapture: true
 
 ======== customSecond ========
 == FrameworkUser
 [expanded] button#inspectedNodeevent-listener-sidebar-custom-framework.js:25
+    useCapture: false
+    passive: false
+    once: false
     handler: function customSecondEventListener(e)
           {
               console.log("I'm second custom event listener");
           }
-    once: false
-    passive: false
-    useCapture: false
 == Exception in fetchers' getter
 
 ======== click ========
 == Raw
 [expanded] button#inspectedNodeRemoveevent-listener-sidebar-custom-framework.js:30
+    useCapture: false
+    passive: false
+    once: false
     handler: function internalHandler(e)
           {
               console.log("I'm internal event handler");
@@ -51,9 +54,6 @@
               if (e.type === "customSecond")
                   customSecondEventListener(e);
           }
-    once: false
-    passive: false
-    useCapture: false
 Framework Event Listeners API Errors:
 	fetcher call produced error: Error in fetcher
 	fetcher call produced error: TypeError: Cannot read property 'eventListeners' of null
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-expected.txt
index 30586d0..b4000f9 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-expected.txt
@@ -4,69 +4,69 @@
 ======== click ========
 == Raw
 [expanded] documentRemoveevent-listener-sidebar.js:15
-    handler: function documentClickHandler(event) { console.log("click - document - attribute"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function documentClickHandler(event) { console.log("click - document - attribute"); }
 == Raw
 [expanded] documentRemoveevent-listener-sidebar.js:40
-    handler: function() { console.log("click - document - handleEvent"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function() { console.log("click - document - handleEvent"); }
 == Raw
 [expanded] documentRemoveevent-listener-sidebar.js:28
-    handler: function(event) { console.log("click - document - capturing"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(event) { console.log("click - document - capturing"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar.js:26
-    handler: function(event) { console.log("click - button - bubbling (registered after attribute)"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function(event) { console.log("click - button - bubbling (registered after attribute)"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar.js:25
-    handler: function(event) { console.log("click - button - attribute"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function(event) { console.log("click - button - attribute"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar.js:21
-    handler: function clickHandler(event) { console.log("click - button - bubbling (registered before attribute)"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function clickHandler(event) { console.log("click - button - bubbling (registered before attribute)"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar.js:24
-    handler: function(event) { console.log("click - button - capturing"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(event) { console.log("click - button - capturing"); }
 
 ======== custom event ========
 == Raw
 [expanded] bodyRemoveevent-listener-sidebar.js:19
-    handler: function f() {}
-    once: true
-    passive: false
     useCapture: true
+    passive: false
+    once: true
+    handler: function f() {}
 
 ======== hover ========
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar.js:23
-    handler: function hoverHandler(event) { console.log("hover - button - bubbling"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function hoverHandler(event) { console.log("hover - button - bubbling"); }
 
 ======== wheel ========
 == Raw
 [expanded] bodyRemoveToggle Passiveevent-listener-sidebar.js:19
-    handler: function f() {}
-    once: false
-    passive: true
     useCapture: false
+    passive: true
+    once: false
+    handler: function f() {}
 Listeners for selected node only(should be no listeners):
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery1-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery1-expected.txt
index 1ecae1959..503c1777 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery1-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery1-expected.txt
@@ -4,26 +4,26 @@
 ======== click ========
 == FrameworkUser
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery1.js:18
-    handler: function(){ console.log("second jquery"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(){ console.log("second jquery"); }
 == FrameworkUser
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery1.js:17
-    handler: function(){ console.log("first jquery"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(){ console.log("first jquery"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery1.js:19
-    handler: function() { console.log("addEventListener"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function() { console.log("addEventListener"); }
 == Framework
 [expanded] button#nodeRemovejquery-1.11.3.min.js:4
-    handler: function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery2-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery2-expected.txt
index 57d5cc1c..c03a22066f8 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery2-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-jquery2-expected.txt
@@ -4,33 +4,33 @@
 ======== click ========
 == FrameworkUser
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery2.js:18
-    handler: function(){ console.log("second jquery"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(){ console.log("second jquery"); }
 == FrameworkUser
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery2.js:17
-    handler: function(){ console.log("first jquery"); }
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function(){ console.log("first jquery"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery2.js:20
-    handler: function() { console.log("onclick"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function() { console.log("onclick"); }
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-jquery2.js:19
-    handler: function() { console.log("addEventListener"); }
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function() { console.log("addEventListener"); }
 == Framework
 [expanded] button#nodeRemovejquery-2.1.4.min.js:3
-    handler: function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}
 Remove listeners..
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-remove-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-remove-expected.txt
index 06e793c..381809d 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-remove-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listener-sidebar-remove-expected.txt
@@ -4,42 +4,42 @@
 ======== click ========
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-remove.js:16
-    handler: function f() {}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function f() {}
 
 ======== mouseover ========
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-remove.js:16
-    handler: function f() {}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function f() {}
 Listeners after removal:
 
 ======== mouseover ========
 == Raw
 [expanded] button#nodeRemoveevent-listener-sidebar-remove.js:16
-    handler: function f() {}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function f() {}
 Listeners for sibling node:
 
 ======== click ========
 == Raw
 [expanded] button#node-siblingRemoveevent-listener-sidebar-remove.js:17
-    handler: function g() {}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function g() {}
 
 ======== mouseover ========
 == Raw
 [expanded] button#node-siblingRemoveevent-listener-sidebar-remove.js:17
-    handler: function g() {}
-    once: false
-    passive: false
     useCapture: false
+    passive: false
+    once: false
+    handler: function g() {}
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-about-blank-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-about-blank-expected.txt
index 9d7cc62b..1ea4a89 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-about-blank-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-about-blank-expected.txt
@@ -4,24 +4,24 @@
 ======== click ========
 == Raw
 [expanded] bodyRemoveevent-listeners-about-blank.js:16
-    handler: function f() {}
-    once: false
-    passive: false
     useCapture: true
+    passive: false
+    once: false
+    handler: function f() {}
 
 ======== hover ========
 == Raw
 [expanded] div#div-in-iframeRemoveevent-listeners-about-blank.js:16
-    handler: function f() {}
-    once: true
-    passive: false
     useCapture: true
+    passive: false
+    once: true
+    handler: function f() {}
 
 ======== wheel ========
 == Raw
 [expanded] bodyRemoveToggle Passiveevent-listeners-about-blank.js:16
-    handler: function f() {}
-    once: false
-    passive: true
     useCapture: false
+    passive: true
+    once: false
+    handler: function f() {}
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
index da397e4..cbd6eb14 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
@@ -10,10 +10,10 @@
 ======== load ========
 == Raw
 [expanded] WindowRemoveinspected-page.html:1
+    useCapture: false
+    passive: false
+    once: false
     handler: function onload(event) {
 testFunction()
 }
-    once: false
-    passive: false
-    useCapture: false
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js b/third_party/blink/web_tests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js
index 36cb862..afd72df 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js
@@ -11,6 +11,8 @@
       <div id="inspected2" style="color: #ffffee">inspected2</div>
     `);
 
+  let treeElement;
+
   TestRunner.runTestSuite([
     function init(next) {
       ElementsTestRunner.selectNodeAndWaitForStyles('inspected1', next);
@@ -77,7 +79,7 @@
     setFormat(format, onFormatSet);
 
     function onFormatSet() {
-      var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem(propertyName);
+      treeElement = ElementsTestRunner.getElementStylePropertyTreeItem(propertyName);
       treeElement.startEditing(treeElement.valueElement);
       TestRunner.addResult(treeElement.valueElement.textContent);
       treeElement.valueElement.dispatchEvent(TestRunner.createKeyEvent('Escape'));
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/set-return-value-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/set-return-value-expected.txt
index d55d76b..95f05fd 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/set-return-value-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/set-return-value-expected.txt
@@ -5,40 +5,40 @@
 Expanded property: Return value
 Scope variables sidebar pane:
 Local
-    x: 42
-    this: undefined
     Return value: 42
+    this: undefined
+    x: 42
 WindowGlobal
     <section collapsed>
 Set return value to {a:1}
 Expanded property: Return value
 Scope variables sidebar pane:
 Local
-    x: 42
-    this: undefined
     Return value: Object
         a: 1
         __proto__: Object
+    this: undefined
+    x: 42
 WindowGlobal
     <section collapsed>
 Try to remove return value
 Expanded property: Return value
 Scope variables sidebar pane:
 Local
-    x: 42
-    this: undefined
     Return value: Object
         a: 1
         __proto__: Object
+    this: undefined
+    x: 42
 WindowGlobal
     <section collapsed>
 Set return value to 239
 Expanded property: Return value
 Scope variables sidebar pane:
 Local
-    x: 42
-    this: undefined
     Return value: 239
+    this: undefined
+    x: 42
 WindowGlobal
     <section collapsed>
 Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
index 44744a84..5c0cc59 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/debugger-expand-scope-expected.txt
@@ -9,14 +9,14 @@
     at innerFunction (...)
     at testFunction (...)
 Local
-    x: 2010
     innerFunctionLocalVar: 2012
     negInf: -Infinity
     negZero: -0
     this: Window
+    x: 2010
 Closure (makeClosure)
-    n: "TextParam"
     makeClosureLocalVar: "local.TextParam"
+    n: "TextParam"
 WindowGlobal
     <section collapsed>
 Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt
index d606d90..4e768b75 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt
@@ -122,10 +122,10 @@
     length: 300
     __proto__: Array(0)
 func: function() {return a + b;}
-    length: 0
-    name: 
     arguments: null
     caller: null
+    length: 0
+    name:
     prototype: Object
     __proto__: function () { [native code] }
     [[FunctionLocation]]: Object
@@ -249,10 +249,10 @@
     length: 300
     __proto__: Array(0)
 func: function() {return a + b;}
-    length: 0
-    name: 
     arguments: null
     caller: null
+    length: 0
+    name:
     prototype: Object
     __proto__: function () { [native code] }
     [[FunctionLocation]]: Object
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
index b8b18e4..fa559246 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes-expected.txt
@@ -15,22 +15,22 @@
     block1: "block {...}"
     const1: 1
 Local
-    x: 2014
     innerFunctionBlockVar: 2116
     innerFunctionLocalVar: 2016
     negInf: -Infinity
     negZero: -0
     this: undefined
+    x: 2014
 Block
     makeClosureDeeperBlockVar: "block.deep.TextParam"
 Closure (window.makeClosure)
-    n: "TextParam"
     makeClosureBlockVar: "block.TextParam"
-    makeClosureLocalVar: "local.TextParam"
     makeClosureDeeperLocalVar: "local.deep.TextParam"
+    makeClosureLocalVar: "local.TextParam"
+    n: "TextParam"
 Script
-    globalScriptLet: 41
     globalScriptConst: 42
+    globalScriptLet: 41
 WindowGlobal
     <section collapsed>
 Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
index 9a20758..6778500 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/debugger-scope-minified-variables-expected.txt
@@ -7,10 +7,10 @@
 Catch
     error: "boom!"
 Local
+    longMap: Map(1) {100 => "hello"}
+    longObject: {}
     parameter1: 100
     parameter2: "hello"
-    longObject: {}
-    longMap: Map(1) {100 => "hello"}
     this: Window
 WindowGlobal
     <section collapsed>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
index ebff8982..8aaa146 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
@@ -3,10 +3,10 @@
     __proto__: Boolean
     [[PrimitiveValue]]: true
 properties-special.js:12 ƒ anonymous(a,b)
-    length: 2
-    name: ""
     arguments: null
     caller: null
+    length: 2
+    name: ""
     prototype: {constructor: ƒ}
     __proto__: ƒ ()
     [[FunctionLocation]]: properties-special.js:12
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/console/console-format-startup-expected.txt b/third_party/blink/web_tests/http/tests/devtools/startup/console/console-format-startup-expected.txt
index a49f5a94..f5369586 100644
--- a/third_party/blink/web_tests/http/tests/devtools/startup/console/console-format-startup-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/startup/console/console-format-startup-expected.txt
@@ -374,8 +374,8 @@
     __proto__: Array(0)
 console-format-startup.html:164 Object table
 console-format-startup.html:165 Object
-    foo: {a: 1, b: 2}
     bar: {a: 3, b: 4}
+    foo: {a: 1, b: 2}
     __proto__: Object
 console-format-startup.html:167 Null as columns
 console-format-startup.html:168 Array(2)
@@ -452,22 +452,21 @@
     length: 3
     __proto__: Array(0)
 console-format-startup.html:206 HTMLCollection(1)
-    length: 1
     0: select#sel
+    length: 1
     sel: select#sel
     __proto__: HTMLCollection
 console-format-startup.html:210 HTMLCollection(1)
-    length: 1
     0: script
+    length: 1
     __proto__: HTMLCollection
 console-format-startup.html:214 HTMLOptionsCollection(2)
-    length: 2
-    selectedIndex: 0
     0: option
     1: option
+    length: 2
+    selectedIndex: 0
     __proto__: HTMLOptionsCollection
 console-format-startup.html:218 HTMLAllCollection(14)
-    length: 14
     0: html
     1: head
     2: script
@@ -482,25 +481,26 @@
     11: option
     12: input
     13: input
-    x: HTMLCollection(3) [div#x, input, input, x: div#x]
-    p: p#p
-    svg-node: svg#svg-node
+    length: 14
     f: form#f
+    p: p#p
     sel: select#sel
+    svg-node: svg#svg-node
+    x: HTMLCollection(3) [div#x, input, input, x: div#x]
     __proto__: HTMLAllCollection
 console-format-startup.html:222 HTMLFormControlsCollection(3)
-    length: 3
     0: select#sel
     1: input
     2: input
+    length: 3
     sel: select#sel
     x: RadioNodeList(2) [input, input, value: ""]
     __proto__: HTMLFormControlsCollection
 console-format-startup.html:226 RadioNodeList(2)
-    value: ""
-    length: 2
     0: input
     1: input
+    length: 2
+    value: ""
     __proto__: RadioNodeList
 console-format-startup.html:232 Array(2)
     0: 1
@@ -508,14 +508,14 @@
     length: 2
     __proto__: Array(0)
 console-format-startup.html:235 NonArrayWithLength
-    length: (...)
     keys: []
+    length: (...)
     __proto__: Object
 console-format-startup.html:242 Arguments(2)
     0: 1
     1: "2"
-    length: 2
     callee: ƒ generateArguments(foo, bar)
+    length: 2
     Symbol(Symbol.iterator): ƒ values()
     __proto__: Object
 console-format-startup.html:246 DOMTokenList(0)
@@ -775,12 +775,12 @@
 globals[25]
     <svg id="svg-node"></svg>
 console-format-startup.html:7 {enumerableProp: 4, __underscoreEnumerableProp__: 5, __underscoreNonEnumerableProp: 2, abc: 3, getFoo: ƒ, …}
-    bar: (...)
     enumerableProp: 4
     __underscoreEnumerableProp__: 5
-    __underscoreNonEnumerableProp: 2
     abc: 3
+    bar: (...)
     getFoo: ƒ ()
+    __underscoreNonEnumerableProp: 2
     get bar: ƒ ()
     set bar: ƒ (x)
     __proto__: Object
@@ -790,12 +790,12 @@
     __proto__: Array(0)
 globals[26]
 {enumerableProp: 4, __underscoreEnumerableProp__: 5, __underscoreNonEnumerableProp: 2, abc: 3, getFoo: ƒ, …}
-    bar: (...)
     enumerableProp: 4
     __underscoreEnumerableProp__: 5
-    __underscoreNonEnumerableProp: 2
     abc: 3
+    bar: (...)
     getFoo: ƒ ()
+    __underscoreNonEnumerableProp: 2
     get bar: ƒ ()
     set bar: ƒ (x)
     __proto__: Object
@@ -824,16 +824,16 @@
 ƒ Object() { [native code] }
 console-format-startup.html:7 {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
     constructor: ƒ Object()
-    __defineGetter__: ƒ __defineGetter__()
-    __defineSetter__: ƒ __defineSetter__()
     hasOwnProperty: ƒ hasOwnProperty()
-    __lookupGetter__: ƒ __lookupGetter__()
-    __lookupSetter__: ƒ __lookupSetter__()
     isPrototypeOf: ƒ isPrototypeOf()
     propertyIsEnumerable: ƒ propertyIsEnumerable()
+    toLocaleString: ƒ toLocaleString()
     toString: ƒ toString()
     valueOf: ƒ valueOf()
-    toLocaleString: ƒ toLocaleString()
+    __defineGetter__: ƒ __defineGetter__()
+    __defineSetter__: ƒ __defineSetter__()
+    __lookupGetter__: ƒ __lookupGetter__()
+    __lookupSetter__: ƒ __lookupSetter__()
     get __proto__: ƒ __proto__()
     set __proto__: ƒ __proto__()
 console-format-startup.html:8 [{…}]
@@ -843,16 +843,16 @@
 globals[30]
 {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
     constructor: ƒ Object()
-    __defineGetter__: ƒ __defineGetter__()
-    __defineSetter__: ƒ __defineSetter__()
     hasOwnProperty: ƒ hasOwnProperty()
-    __lookupGetter__: ƒ __lookupGetter__()
-    __lookupSetter__: ƒ __lookupSetter__()
     isPrototypeOf: ƒ isPrototypeOf()
     propertyIsEnumerable: ƒ propertyIsEnumerable()
+    toLocaleString: ƒ toLocaleString()
     toString: ƒ toString()
     valueOf: ƒ valueOf()
-    toLocaleString: ƒ toLocaleString()
+    __defineGetter__: ƒ __defineGetter__()
+    __defineSetter__: ƒ __defineSetter__()
+    __lookupGetter__: ƒ __lookupGetter__()
+    __lookupSetter__: ƒ __lookupSetter__()
     get __proto__: ƒ __proto__()
     set __proto__: ƒ __proto__()
 console-format-startup.html:7 ƒ ( /**/ foo/**/, /*/**/bar,
@@ -895,13 +895,13 @@
     __proto__: String
     [[PrimitiveValue]]: "abc"
 console-format-startup.html:7 Uint16Array(3) [1, 2, 3]
+    0: 1
+    1: 2
+    2: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 1
-    1: 2
-    2: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format-startup.html:8 [Uint16Array(3)]
@@ -910,13 +910,13 @@
     __proto__: Array(0)
 globals[34]
 Uint16Array(3) [1, 2, 3]
+    0: 1
+    1: 2
+    2: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 1
-    1: 2
-    2: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format-startup.html:7 #text
@@ -934,11 +934,11 @@
 globals[36]
 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
 console-format-startup.html:7 Uint8Array [3]
+    0: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format-startup.html:8 [Uint8Array(1)]
@@ -947,11 +947,11 @@
     __proto__: Array(0)
 globals[37]
 Uint8Array [3]
+    0: 3
     buffer: (...)
     byteLength: (...)
     byteOffset: (...)
     length: (...)
-    0: 3
     Symbol(Symbol.toStringTag): (...)
     __proto__: TypedArray
 console-format-startup.html:7 Uint8Array(400) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …]
@@ -1044,10 +1044,10 @@
     [[PrimitiveValue]]: 42
 console-format-startup.html:7 String {"abc", 3: "foo", 01: "foo", a: "bar"}
     0: "a"
+    01: "foo"
     1: "b"
     2: "c"
     3: "foo"
-    01: "foo"
     a: "bar"
     length: 3
     __proto__: String
@@ -1059,10 +1059,10 @@
 globals[44]
 String {"abc", 3: "foo", 01: "foo", a: "bar"}
     0: "a"
+    01: "foo"
     1: "b"
     2: "c"
     3: "foo"
-    01: "foo"
     a: "bar"
     length: 3
     __proto__: String
@@ -1121,8 +1121,8 @@
 globals[49]
 Symbol(a)
 console-format-startup.html:7 {a: Symbol(), Symbol(a): 2}
-    getter: (...)
     a: Symbol()
+    getter: (...)
     Symbol(a): 2
     get getter: ƒ getter()
     __proto__: Object
@@ -1132,8 +1132,8 @@
     __proto__: Array(0)
 globals[50]
 {a: Symbol(), Symbol(a): 2}
-    getter: (...)
     a: Symbol()
+    getter: (...)
     Symbol(a): 2
     get getter: ƒ getter()
     __proto__: Object
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-bound-function-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-bound-function-expected.txt
index 4151574..7e67668 100644
--- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-bound-function-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-bound-function-expected.txt
@@ -1,5 +1,3 @@
 Tests extracting information about original functions from bound ones
 
 
-FunctionCall timeline-bound-function.html:7
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-editable-longtext.js b/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-editable-longtext.js
index 4879c8a..01988728 100644
--- a/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-editable-longtext.js
+++ b/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-editable-longtext.js
@@ -7,7 +7,7 @@
     {id: "key", title: "Key column", editable: true, longText: false},
     {id: "value", title: "Value column", editable: true, longText: true}
   ];
-  var dataGrid = new DataGrid.DataGrid(columns, onEdit);
+  var dataGrid = new DataGrid.DataGrid({displayName: 'Test', columns, editCallback: onEdit});
   UI.inspectorView.element.appendChild(dataGrid.element);
 
   var rootNode = dataGrid.rootNode();
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-items-attached-to-dom.js b/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-items-attached-to-dom.js
index 0e7c6e6..0870209 100644
--- a/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-items-attached-to-dom.js
+++ b/third_party/blink/web_tests/http/tests/devtools/unit/datagrid-items-attached-to-dom.js
@@ -7,7 +7,7 @@
   UI.inspectorView.element.appendChild(div);
 
   var columns = [{id: "id", title: "ID column", width: "250px"}];
-  var dataGrid = new DataGrid.DataGrid(columns);
+  var dataGrid = new DataGrid.DataGrid({displayName: 'Test', columns});
   div.appendChild(dataGrid.element);
   dataGrid.element.style.height = '150px';
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-attached-to-dom.js b/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-attached-to-dom.js
index 62f4ef1..c767c434 100644
--- a/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-attached-to-dom.js
+++ b/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-attached-to-dom.js
@@ -7,7 +7,7 @@
   UI.inspectorView.element.appendChild(div);
 
   var columns = [{id: "id", title: "ID column", width: "250px"}];
-  var dataGrid = new DataGrid.ViewportDataGrid(columns);
+  var dataGrid = new DataGrid.ViewportDataGrid({displayName: 'Test', columns});
   div.appendChild(dataGrid.element);
   dataGrid.element.style.height = '150px';
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-expandable-attached-to-dom.js b/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-expandable-attached-to-dom.js
index 3d42831..8902241e 100644
--- a/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-expandable-attached-to-dom.js
+++ b/third_party/blink/web_tests/http/tests/devtools/unit/viewport-datagrid-items-expandable-attached-to-dom.js
@@ -7,7 +7,7 @@
   UI.inspectorView.element.appendChild(div);
 
   var columns = [{id: "id", title: "ID column", width: "250px"}];
-  var dataGrid = new DataGrid.ViewportDataGrid(columns);
+  var dataGrid = new DataGrid.ViewportDataGrid({displayName: 'Test', columns});
   div.appendChild(dataGrid.element);
   dataGrid.element.style.height = '150px';
 
diff --git a/third_party/blink/web_tests/http/tests/forms/date-picker-keyboard-cross-domain.html b/third_party/blink/web_tests/http/tests/forms/date-picker-keyboard-cross-domain.html
new file mode 100644
index 0000000..9b07a148
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/forms/date-picker-keyboard-cross-domain.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script src="../../../resources/testharness.js"></script>
+  <script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body >
+  <script>
+    let t = async_test("Test input date popup's keyboard usability when inside cross-process iframe.");
+
+    let iframe = document.createElement("iframe");
+    iframe.src = "http://localhost:8000/forms/resources/date-picker-keyboard-cross-domain-iframe.html";
+
+    const runTest = t.step_func((event) => {
+      // The eventSender.keyDown() invocations in the iframe create extra window messages.
+      // Ignore those.
+      if (typeof(event.data) !== "string" || !event.data.includes("Date result:")) {
+        return;
+      }
+
+      // iframe should be cross-origin (and cross-process)
+      assert_equals(iframe.contentDocument, null);
+
+      assert_equals(event.data, "Date result: 2019-12-13");
+      t.done();
+    }, "Check date of picker in cross-domain iframe.");
+
+    window.onmessage = runTest;
+
+    document.body.appendChild(iframe);
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html b/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html
new file mode 100644
index 0000000..e85ccf3
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html
@@ -0,0 +1,28 @@
+<html>
+  <input type="date" id="date" value="2019-12-12">
+
+  <script>
+      let input_date = document.getElementById('date');
+
+      input_date.focus();
+
+      if (internals.runtimeFlags.formControlsRefreshEnabled) {
+         eventSender.keyDown("Enter");
+      } else {
+         // Old picker needs Alt+Enter
+         eventSender.keyDown("ArrowDown", ["altKey"]);
+      }
+
+      // Advance date to the next day
+      eventSender.keyDown("ArrowRight");
+
+     // Make the chosen value apply synchronously so we don't need to insert
+     // an artificial delay in the test
+     internals.pagePopupWindow.CalendarPicker.commitDelayMs = 0;
+
+     // Close the popup and commit the value
+     eventSender.keyDown("Enter");
+
+     window.top.postMessage(`Date result: ${input_date.value}`, "*");
+  </script>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/security/no-referrer.html b/third_party/blink/web_tests/http/tests/security/no-referrer.html
index 3c89e0c..c7223063 100644
--- a/third_party/blink/web_tests/http/tests/security/no-referrer.html
+++ b/third_party/blink/web_tests/http/tests/security/no-referrer.html
@@ -2,7 +2,7 @@
 if (window.testRunner) {
     testRunner.waitUntilDone();
     testRunner.dumpAsText();
-    testRunner.setWillSendRequestClearHeader("Referer");
+    testRunner.setWillSendRequestClearReferrer();
 }
 </script>
 <div id=log></div>
diff --git a/third_party/blink/web_tests/images/color-profile-mask-image-svg-expected.png b/third_party/blink/web_tests/images/color-profile-mask-image-svg-expected.png
index 4b17ac0..d5d1f19 100644
--- a/third_party/blink/web_tests/images/color-profile-mask-image-svg-expected.png
+++ b/third_party/blink/web_tests/images/color-profile-mask-image-svg-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/as-background-image/svg-as-background-5-expected.png b/third_party/blink/web_tests/platform/linux/svg/as-background-image/svg-as-background-5-expected.png
index c8cd04785..9b028806 100644
--- a/third_party/blink/web_tests/platform/linux/svg/as-background-image/svg-as-background-5-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/as-background-image/svg-as-background-5-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/wicd/test-scalable-background-image1-expected.png b/third_party/blink/web_tests/platform/linux/svg/wicd/test-scalable-background-image1-expected.png
index 35e0a51d..957049a 100644
--- a/third_party/blink/web_tests/platform/linux/svg/wicd/test-scalable-background-image1-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/wicd/test-scalable-background-image1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-image-tiled-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-image-tiled-expected.png
new file mode 100644
index 0000000..0ab39c1
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-image-tiled-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-images-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-images-expected.png
new file mode 100644
index 0000000..d88d68d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-background-images-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png
new file mode 100644
index 0000000..c2345bb
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-relative-image-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-relative-image-expected.png
new file mode 100644
index 0000000..77c2b3a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-svg-as-relative-image-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png
new file mode 100644
index 0000000..33d5e415
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
index 933d226..2689d5c4 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
index f109141..7de1f9d 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index 93f626a..f483a70 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
index 62e9825..94601bd 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
index 2e95ba21..bb7c202 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
index a7b44eb..1801151 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
index e0c837f..ac54e69a 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index 47491a68..2f0a0bd 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
index de661e9a..210785e22 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
index 1be6833..149271a 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
deleted file mode 100644
index a807f46..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
deleted file mode 100644
index cf210d6..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 4b430c1..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
deleted file mode 100644
index 9b215f1..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
index 4c9e79b..aff4296 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
deleted file mode 100644
index a807f46..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
deleted file mode 100644
index cf210d6..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 4b430c1..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
deleted file mode 100644
index 9b215f1..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
index 1fd1adaa..8e7f165b 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
deleted file mode 100644
index a807f46..0000000
--- a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
deleted file mode 100644
index cf210d6..0000000
--- a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index 4b430c1..0000000
--- a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
deleted file mode 100644
index 9b215f1..0000000
--- a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-004-expected.png b/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-004-expected.png
index 01b8d3c..2eb0a792 100644
--- a/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-004-expected.png
+++ b/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-004-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-005-expected.png b/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-005-expected.png
index 76ea28b..5669afa 100644
--- a/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-005-expected.png
+++ b/third_party/blink/web_tests/platform/mac/css2.1/20110323/background-intrinsic-005-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png b/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
index dd1d06b..4e04974 100644
--- a/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-repeat-expected.png b/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-repeat-expected.png
index 8ed74ac..af2b9c9 100644
--- a/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-repeat-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/as-background-image/background-repeat-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/as-background-image/svg-as-background-5-expected.png b/third_party/blink/web_tests/platform/mac/svg/as-background-image/svg-as-background-5-expected.png
index f85fbdb9..9f28c50 100644
--- a/third_party/blink/web_tests/platform/mac/svg/as-background-image/svg-as-background-5-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/as-background-image/svg-as-background-5-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/wicd/test-scalable-background-image1-expected.png b/third_party/blink/web_tests/platform/mac/svg/wicd/test-scalable-background-image1-expected.png
index 62437c2..e676fa53 100644
--- a/third_party/blink/web_tests/platform/mac/svg/wicd/test-scalable-background-image1-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/wicd/test-scalable-background-image1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-background-images-expected.png b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-background-images-expected.png
index d63b25c..539a50ee 100644
--- a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-background-images-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-background-images-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
index 6ab6d2c..ee481cb 100644
--- a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
index c8e8ea6..972c39a9 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
index 9427d938..0ab2c57 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index 2f6e059..3cc52ea 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
index b180169f..28db6b7c 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
index 886b0c6..054c6d04 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
index a807f46..30327b75 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
index cf210d6..24fd9bd 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index 4b430c1..66bec53 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
index 9b215f1..a6ca12a 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
index d9f6506f..b162677 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/forced-colors-mode-04-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/forced-colors-mode-04-expected.txt
new file mode 100644
index 0000000..29a12151
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/forced-high-contrast-cascade/external/wpt/forced-colors-mode/forced-colors-mode-04-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Checks hyperlinks are overridden in forced colors mode. assert_equals: expected "rgba(0, 0, 0, 0.18)" but got "rgba(0, 0, 0, 0.4)"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-004-expected.png b/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-004-expected.png
index d6a2bc9..d621ce8 100644
--- a/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-004-expected.png
+++ b/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-004-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-005-expected.png b/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-005-expected.png
index 89e9434..19ad553 100644
--- a/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-005-expected.png
+++ b/third_party/blink/web_tests/platform/win/css2.1/20110323/background-intrinsic-005-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png b/third_party/blink/web_tests/platform/win/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
index 74ce6943..e2631ad 100644
--- a/third_party/blink/web_tests/platform/win/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/as-background-image/background-repeat-expected.png b/third_party/blink/web_tests/platform/win/svg/as-background-image/background-repeat-expected.png
index 00d1eaff..a3befd5 100644
--- a/third_party/blink/web_tests/platform/win/svg/as-background-image/background-repeat-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/as-background-image/background-repeat-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/as-background-image/svg-as-background-5-expected.png b/third_party/blink/web_tests/platform/win/svg/as-background-image/svg-as-background-5-expected.png
index ac622e2..898d9b5 100644
--- a/third_party/blink/web_tests/platform/win/svg/as-background-image/svg-as-background-5-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/as-background-image/svg-as-background-5-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/wicd/test-scalable-background-image1-expected.png b/third_party/blink/web_tests/platform/win/svg/wicd/test-scalable-background-image1-expected.png
index dd23b71..6f972ea 100644
--- a/third_party/blink/web_tests/platform/win/svg/wicd/test-scalable-background-image1-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/wicd/test-scalable-background-image1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-background-images-expected.png b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-background-images-expected.png
index d88d68d..218c89e 100644
--- a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-background-images-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-background-images-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
index c155bf0..83319d8 100644
--- a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
new file mode 100644
index 0000000..715b7dcf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
new file mode 100644
index 0000000..c630408c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
new file mode 100644
index 0000000..f2d00fc
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
new file mode 100644
index 0000000..1bde656
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
index 19a112eb..44cd61d 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
index e492bf5e..26cae8f0 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
index 13d9e1e..e19397e 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index b239d18..4ab6622 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
index 4439411..41bd3eb 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
index 0652b554..8003c168 100644
--- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png b/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png
index 19f0e99b..cca204c 100644
--- a/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png
+++ b/third_party/blink/web_tests/platform/win7/svg/as-background-image/svg-as-background-5-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index c618e8d2..ae5a251 100644
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
index 23d56158..a9caba9 100644
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/calendar-picker/date-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
deleted file mode 100644
index e492bf5e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
deleted file mode 100644
index 13d9e1e..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
index d622ee9..c09f1ec 100644
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
deleted file mode 100644
index 4439411..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
index 443a186..3933b47 100644
--- a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
+++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh/month-picker/month-picker-appearance-zoom150-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
deleted file mode 100644
index 60132bc..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
+++ /dev/null
@@ -1,509 +0,0 @@
-This is a testharness.js-based test.
-Found 497 tests; 402 PASS, 95 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Test driver for asyncInitCertificate
-FAIL Test driver for asyncInitTransports assert_unreached: Failed to run asyncInitTransports: Error: assert_true: Expect pc.sctp to be instance of RTCSctpTransport expected true got false Reached unreachable code
-PASS Test driver for asyncInitMediaStreamTrack
-PASS Partial dictionary RTCOfferOptions: original dictionary defined
-PASS Partial dictionary RTCOfferOptions: member names are unique
-PASS Partial interface RTCPeerConnection: original interface defined
-PASS Partial interface RTCPeerConnection: member names are unique
-PASS Partial interface RTCPeerConnection[2]: original interface defined
-PASS Partial interface RTCPeerConnection[2]: member names are unique
-PASS Partial interface RTCPeerConnection[3]: original interface defined
-PASS Partial interface RTCPeerConnection[3]: member names are unique
-PASS Partial interface RTCRtpSender: original interface defined
-PASS Partial interface RTCRtpSender: member names are unique
-PASS Partial interface RTCPeerConnection[4]: original interface defined
-PASS Partial interface RTCPeerConnection[4]: member names are unique
-PASS RTCPeerConnection interface: existence and properties of interface object
-PASS RTCPeerConnection interface object length
-PASS RTCPeerConnection interface object name
-PASS RTCPeerConnection interface: existence and properties of interface prototype object
-PASS RTCPeerConnection interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCPeerConnection interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCPeerConnection interface: operation createOffer(RTCOfferOptions)
-PASS RTCPeerConnection interface: operation createAnswer(RTCAnswerOptions)
-PASS RTCPeerConnection interface: operation setLocalDescription(RTCSessionDescriptionInit)
-PASS RTCPeerConnection interface: attribute localDescription
-PASS RTCPeerConnection interface: attribute currentLocalDescription
-PASS RTCPeerConnection interface: attribute pendingLocalDescription
-FAIL RTCPeerConnection interface: operation setRemoteDescription(RTCSessionDescriptionInit) assert_equals: property has wrong .length expected 0 but got 1
-PASS RTCPeerConnection interface: attribute remoteDescription
-PASS RTCPeerConnection interface: attribute currentRemoteDescription
-PASS RTCPeerConnection interface: attribute pendingRemoteDescription
-FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit) assert_equals: property has wrong .length expected 0 but got 1
-PASS RTCPeerConnection interface: attribute signalingState
-PASS RTCPeerConnection interface: attribute iceGatheringState
-PASS RTCPeerConnection interface: attribute iceConnectionState
-PASS RTCPeerConnection interface: attribute connectionState
-FAIL RTCPeerConnection interface: attribute canTrickleIceCandidates assert_true: The prototype object must have a property "canTrickleIceCandidates" expected true got false
-PASS RTCPeerConnection interface: operation restartIce()
-PASS RTCPeerConnection interface: operation getConfiguration()
-PASS RTCPeerConnection interface: operation setConfiguration(RTCConfiguration)
-PASS RTCPeerConnection interface: operation close()
-PASS RTCPeerConnection interface: attribute onnegotiationneeded
-PASS RTCPeerConnection interface: attribute onicecandidate
-PASS RTCPeerConnection interface: attribute onicecandidateerror
-PASS RTCPeerConnection interface: attribute onsignalingstatechange
-PASS RTCPeerConnection interface: attribute oniceconnectionstatechange
-PASS RTCPeerConnection interface: attribute onicegatheringstatechange
-PASS RTCPeerConnection interface: attribute onconnectionstatechange
-PASS RTCPeerConnection interface: operation createOffer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback, RTCOfferOptions)
-PASS RTCPeerConnection interface: operation setLocalDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)
-PASS RTCPeerConnection interface: operation createAnswer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback)
-FAIL RTCPeerConnection interface: operation setRemoteDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback) assert_equals: property has wrong .length expected 0 but got 1
-FAIL RTCPeerConnection interface: operation addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback) assert_equals: property has wrong .length expected 0 but got 1
-PASS RTCPeerConnection interface: operation generateCertificate(AlgorithmIdentifier)
-PASS RTCPeerConnection interface: operation getSenders()
-PASS RTCPeerConnection interface: operation getReceivers()
-PASS RTCPeerConnection interface: operation getTransceivers()
-PASS RTCPeerConnection interface: operation addTrack(MediaStreamTrack, MediaStream)
-PASS RTCPeerConnection interface: operation removeTrack(RTCRtpSender)
-PASS RTCPeerConnection interface: operation addTransceiver([object Object],[object Object], RTCRtpTransceiverInit)
-PASS RTCPeerConnection interface: attribute ontrack
-PASS RTCPeerConnection interface: attribute sctp
-PASS RTCPeerConnection interface: operation createDataChannel(USVString, RTCDataChannelInit)
-PASS RTCPeerConnection interface: attribute ondatachannel
-PASS RTCPeerConnection interface: operation getStats(MediaStreamTrack)
-PASS RTCPeerConnection must be primary interface of new RTCPeerConnection()
-PASS Stringification of new RTCPeerConnection()
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "createOffer(RTCOfferOptions)" with the proper type
-PASS RTCPeerConnection interface: calling createOffer(RTCOfferOptions) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "createAnswer(RTCAnswerOptions)" with the proper type
-PASS RTCPeerConnection interface: calling createAnswer(RTCAnswerOptions) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "setLocalDescription(RTCSessionDescriptionInit)" with the proper type
-PASS RTCPeerConnection interface: calling setLocalDescription(RTCSessionDescriptionInit) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "localDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "currentLocalDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "pendingLocalDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "setRemoteDescription(RTCSessionDescriptionInit)" with the proper type
-PASS RTCPeerConnection interface: calling setRemoteDescription(RTCSessionDescriptionInit) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "remoteDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "currentRemoteDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "pendingRemoteDescription" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "addIceCandidate(RTCIceCandidateInit)" with the proper type
-PASS RTCPeerConnection interface: calling addIceCandidate(RTCIceCandidateInit) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "signalingState" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "iceGatheringState" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "iceConnectionState" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "connectionState" with the proper type
-FAIL RTCPeerConnection interface: new RTCPeerConnection() must inherit property "canTrickleIceCandidates" with the proper type assert_inherits: property "canTrickleIceCandidates" not found in prototype chain
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "restartIce()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "getConfiguration()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "setConfiguration(RTCConfiguration)" with the proper type
-PASS RTCPeerConnection interface: calling setConfiguration(RTCConfiguration) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "close()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onnegotiationneeded" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onicecandidate" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onicecandidateerror" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onsignalingstatechange" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "oniceconnectionstatechange" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onicegatheringstatechange" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "onconnectionstatechange" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "createOffer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback, RTCOfferOptions)" with the proper type
-PASS RTCPeerConnection interface: calling createOffer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback, RTCOfferOptions) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "setLocalDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)" with the proper type
-PASS RTCPeerConnection interface: calling setLocalDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "createAnswer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback)" with the proper type
-PASS RTCPeerConnection interface: calling createAnswer(RTCSessionDescriptionCallback, RTCPeerConnectionErrorCallback) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "setRemoteDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback)" with the proper type
-PASS RTCPeerConnection interface: calling setRemoteDescription(RTCSessionDescriptionInit, VoidFunction, RTCPeerConnectionErrorCallback) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback)" with the proper type
-PASS RTCPeerConnection interface: calling addIceCandidate(RTCIceCandidateInit, VoidFunction, RTCPeerConnectionErrorCallback) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "generateCertificate(AlgorithmIdentifier)" with the proper type
-PASS RTCPeerConnection interface: calling generateCertificate(AlgorithmIdentifier) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "getSenders()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "getReceivers()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "getTransceivers()" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "addTrack(MediaStreamTrack, MediaStream)" with the proper type
-PASS RTCPeerConnection interface: calling addTrack(MediaStreamTrack, MediaStream) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "removeTrack(RTCRtpSender)" with the proper type
-PASS RTCPeerConnection interface: calling removeTrack(RTCRtpSender) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "addTransceiver([object Object],[object Object], RTCRtpTransceiverInit)" with the proper type
-PASS RTCPeerConnection interface: calling addTransceiver([object Object],[object Object], RTCRtpTransceiverInit) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "ontrack" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "sctp" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "createDataChannel(USVString, RTCDataChannelInit)" with the proper type
-PASS RTCPeerConnection interface: calling createDataChannel(USVString, RTCDataChannelInit) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "ondatachannel" with the proper type
-PASS RTCPeerConnection interface: new RTCPeerConnection() must inherit property "getStats(MediaStreamTrack)" with the proper type
-PASS RTCPeerConnection interface: calling getStats(MediaStreamTrack) on new RTCPeerConnection() with too few arguments must throw TypeError
-PASS RTCSessionDescription interface: existence and properties of interface object
-PASS RTCSessionDescription interface object length
-PASS RTCSessionDescription interface object name
-PASS RTCSessionDescription interface: existence and properties of interface prototype object
-PASS RTCSessionDescription interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCSessionDescription interface: existence and properties of interface prototype object's @@unscopables property
-FAIL RTCSessionDescription interface: attribute type assert_equals: setter must be undefined for readonly attributes expected (undefined) undefined but got (function) function "function set type() { [native code] }"
-FAIL RTCSessionDescription interface: attribute sdp assert_equals: setter must be undefined for readonly attributes expected (undefined) undefined but got (function) function "function set sdp() { [native code] }"
-PASS RTCSessionDescription interface: operation toJSON()
-PASS RTCSessionDescription must be primary interface of new RTCSessionDescription({ type: 'offer' })
-PASS Stringification of new RTCSessionDescription({ type: 'offer' })
-PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "type" with the proper type
-FAIL RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "sdp" with the proper type assert_equals: expected "string" but got "object"
-PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "toJSON()" with the proper type
-FAIL RTCSessionDescription interface: default toJSON operation on new RTCSessionDescription({ type: 'offer' }) assert_equals: expected "string" but got "object"
-PASS RTCIceCandidate interface: existence and properties of interface object
-PASS RTCIceCandidate interface object length
-PASS RTCIceCandidate interface object name
-PASS RTCIceCandidate interface: existence and properties of interface prototype object
-PASS RTCIceCandidate interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCIceCandidate interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCIceCandidate interface: attribute candidate
-PASS RTCIceCandidate interface: attribute sdpMid
-PASS RTCIceCandidate interface: attribute sdpMLineIndex
-PASS RTCIceCandidate interface: attribute foundation
-PASS RTCIceCandidate interface: attribute component
-PASS RTCIceCandidate interface: attribute priority
-PASS RTCIceCandidate interface: attribute address
-PASS RTCIceCandidate interface: attribute protocol
-PASS RTCIceCandidate interface: attribute port
-PASS RTCIceCandidate interface: attribute type
-PASS RTCIceCandidate interface: attribute tcpType
-PASS RTCIceCandidate interface: attribute relatedAddress
-PASS RTCIceCandidate interface: attribute relatedPort
-PASS RTCIceCandidate interface: attribute usernameFragment
-PASS RTCIceCandidate interface: operation toJSON()
-PASS RTCIceCandidate must be primary interface of new RTCIceCandidate({ sdpMid: 1 })
-PASS Stringification of new RTCIceCandidate({ sdpMid: 1 })
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "candidate" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "sdpMid" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "sdpMLineIndex" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "foundation" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "component" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "priority" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "address" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "protocol" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "port" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "type" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "tcpType" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "relatedAddress" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "relatedPort" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "usernameFragment" with the proper type
-PASS RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "toJSON()" with the proper type
-PASS RTCIceCandidate interface: toJSON operation on new RTCIceCandidate({ sdpMid: 1 })
-PASS RTCPeerConnectionIceEvent interface: existence and properties of interface object
-PASS RTCPeerConnectionIceEvent interface object length
-PASS RTCPeerConnectionIceEvent interface object name
-PASS RTCPeerConnectionIceEvent interface: existence and properties of interface prototype object
-PASS RTCPeerConnectionIceEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCPeerConnectionIceEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCPeerConnectionIceEvent interface: attribute candidate
-FAIL RTCPeerConnectionIceEvent interface: attribute url assert_true: The prototype object must have a property "url" expected true got false
-PASS RTCPeerConnectionIceEvent must be primary interface of new RTCPeerConnectionIceEvent('ice')
-PASS Stringification of new RTCPeerConnectionIceEvent('ice')
-PASS RTCPeerConnectionIceEvent interface: new RTCPeerConnectionIceEvent('ice') must inherit property "candidate" with the proper type
-FAIL RTCPeerConnectionIceEvent interface: new RTCPeerConnectionIceEvent('ice') must inherit property "url" with the proper type assert_inherits: property "url" not found in prototype chain
-PASS RTCPeerConnectionIceErrorEvent interface: existence and properties of interface object
-PASS RTCPeerConnectionIceErrorEvent interface object length
-PASS RTCPeerConnectionIceErrorEvent interface object name
-PASS RTCPeerConnectionIceErrorEvent interface: existence and properties of interface prototype object
-PASS RTCPeerConnectionIceErrorEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCPeerConnectionIceErrorEvent interface: existence and properties of interface prototype object's @@unscopables property
-FAIL RTCPeerConnectionIceErrorEvent interface: attribute address assert_true: The prototype object must have a property "address" expected true got false
-FAIL RTCPeerConnectionIceErrorEvent interface: attribute port assert_true: The prototype object must have a property "port" expected true got false
-PASS RTCPeerConnectionIceErrorEvent interface: attribute url
-PASS RTCPeerConnectionIceErrorEvent interface: attribute errorCode
-PASS RTCPeerConnectionIceErrorEvent interface: attribute errorText
-PASS RTCPeerConnectionIceErrorEvent must be primary interface of new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 });
-PASS Stringification of new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 });
-FAIL RTCPeerConnectionIceErrorEvent interface: new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 }); must inherit property "address" with the proper type assert_inherits: property "address" not found in prototype chain
-FAIL RTCPeerConnectionIceErrorEvent interface: new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 }); must inherit property "port" with the proper type assert_inherits: property "port" not found in prototype chain
-PASS RTCPeerConnectionIceErrorEvent interface: new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 }); must inherit property "url" with the proper type
-PASS RTCPeerConnectionIceErrorEvent interface: new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 }); must inherit property "errorCode" with the proper type
-PASS RTCPeerConnectionIceErrorEvent interface: new RTCPeerConnectionIceErrorEvent('ice-error', { errorCode: 701 }); must inherit property "errorText" with the proper type
-PASS RTCCertificate interface: existence and properties of interface object
-PASS RTCCertificate interface object length
-PASS RTCCertificate interface object name
-PASS RTCCertificate interface: existence and properties of interface prototype object
-PASS RTCCertificate interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCCertificate interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCCertificate interface: attribute expires
-PASS RTCCertificate interface: operation getFingerprints()
-PASS RTCCertificate must be primary interface of idlTestObjects.certificate
-PASS Stringification of idlTestObjects.certificate
-PASS RTCCertificate interface: idlTestObjects.certificate must inherit property "expires" with the proper type
-PASS RTCCertificate interface: idlTestObjects.certificate must inherit property "getFingerprints()" with the proper type
-PASS RTCRtpSender interface: existence and properties of interface object
-PASS RTCRtpSender interface object length
-PASS RTCRtpSender interface object name
-PASS RTCRtpSender interface: existence and properties of interface prototype object
-PASS RTCRtpSender interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCRtpSender interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCRtpSender interface: attribute track
-PASS RTCRtpSender interface: attribute transport
-PASS RTCRtpSender interface: operation getCapabilities(DOMString)
-FAIL RTCRtpSender interface: operation setParameters(RTCRtpSendParameters) assert_equals: property has wrong .length expected 1 but got 0
-PASS RTCRtpSender interface: operation getParameters()
-PASS RTCRtpSender interface: operation replaceTrack(MediaStreamTrack)
-PASS RTCRtpSender interface: operation setStreams(MediaStream)
-PASS RTCRtpSender interface: operation getStats()
-PASS RTCRtpSender interface: attribute dtmf
-FAIL RTCRtpSender must be primary interface of new RTCPeerConnection().addTransceiver('audio').sender assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL Stringification of new RTCPeerConnection().addTransceiver('audio').sender assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "track" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "transport" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "getCapabilities(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: calling getCapabilities(DOMString) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "setParameters(RTCRtpSendParameters)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: calling setParameters(RTCRtpSendParameters) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "getParameters()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "replaceTrack(MediaStreamTrack)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: calling replaceTrack(MediaStreamTrack) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "setStreams(MediaStream)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: calling setStreams(MediaStream) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "getStats()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "dtmf" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-PASS RTCRtpReceiver interface: existence and properties of interface object
-PASS RTCRtpReceiver interface object length
-PASS RTCRtpReceiver interface object name
-PASS RTCRtpReceiver interface: existence and properties of interface prototype object
-PASS RTCRtpReceiver interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCRtpReceiver interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCRtpReceiver interface: attribute track
-PASS RTCRtpReceiver interface: attribute transport
-PASS RTCRtpReceiver interface: operation getCapabilities(DOMString)
-PASS RTCRtpReceiver interface: operation getParameters()
-PASS RTCRtpReceiver interface: operation getContributingSources()
-PASS RTCRtpReceiver interface: operation getSynchronizationSources()
-PASS RTCRtpReceiver interface: operation getStats()
-FAIL RTCRtpReceiver must be primary interface of new RTCPeerConnection().addTransceiver('audio').receiver assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL Stringification of new RTCPeerConnection().addTransceiver('audio').receiver assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "track" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "transport" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getCapabilities(DOMString)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: calling getCapabilities(DOMString) on new RTCPeerConnection().addTransceiver('audio').receiver with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getParameters()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getContributingSources()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getSynchronizationSources()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "getStats()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-PASS RTCRtpTransceiver interface: existence and properties of interface object
-PASS RTCRtpTransceiver interface object length
-PASS RTCRtpTransceiver interface object name
-PASS RTCRtpTransceiver interface: existence and properties of interface prototype object
-PASS RTCRtpTransceiver interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCRtpTransceiver interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCRtpTransceiver interface: attribute mid
-PASS RTCRtpTransceiver interface: attribute sender
-PASS RTCRtpTransceiver interface: attribute receiver
-PASS RTCRtpTransceiver interface: attribute direction
-PASS RTCRtpTransceiver interface: attribute currentDirection
-FAIL RTCRtpTransceiver interface: operation stop() assert_own_property: interface prototype object missing non-static operation expected property "stop" missing
-PASS RTCRtpTransceiver interface: operation setCodecPreferences([object Object])
-FAIL RTCRtpTransceiver must be primary interface of new RTCPeerConnection().addTransceiver('audio') assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL Stringification of new RTCPeerConnection().addTransceiver('audio') assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "mid" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "sender" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "receiver" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "direction" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "currentDirection" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "stop()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "setCodecPreferences([object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCRtpTransceiver interface: calling setCodecPreferences([object Object]) on new RTCPeerConnection().addTransceiver('audio') with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-PASS RTCDtlsTransport interface: existence and properties of interface object
-PASS RTCDtlsTransport interface object length
-PASS RTCDtlsTransport interface object name
-PASS RTCDtlsTransport interface: existence and properties of interface prototype object
-PASS RTCDtlsTransport interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCDtlsTransport interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCDtlsTransport interface: attribute iceTransport
-PASS RTCDtlsTransport interface: attribute state
-PASS RTCDtlsTransport interface: operation getRemoteCertificates()
-PASS RTCDtlsTransport interface: attribute onstatechange
-PASS RTCDtlsTransport interface: attribute onerror
-FAIL RTCDtlsTransport must be primary interface of idlTestObjects.dtlsTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of idlTestObjects.dtlsTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "iceTransport" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "state" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "getRemoteCertificates()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "onstatechange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCDtlsTransport interface: idlTestObjects.dtlsTransport must inherit property "onerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: existence and properties of interface object assert_throws: interface object didn't throw TypeError when called as a constructor function "function() {
-                new interface_object();
-            }" did not throw
-PASS RTCIceTransport interface object length
-PASS RTCIceTransport interface object name
-PASS RTCIceTransport interface: existence and properties of interface prototype object
-PASS RTCIceTransport interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCIceTransport interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCIceTransport interface: attribute role
-FAIL RTCIceTransport interface: attribute component assert_true: The prototype object must have a property "component" expected true got false
-PASS RTCIceTransport interface: attribute state
-PASS RTCIceTransport interface: attribute gatheringState
-PASS RTCIceTransport interface: operation getLocalCandidates()
-PASS RTCIceTransport interface: operation getRemoteCandidates()
-PASS RTCIceTransport interface: operation getSelectedCandidatePair()
-PASS RTCIceTransport interface: operation getLocalParameters()
-PASS RTCIceTransport interface: operation getRemoteParameters()
-PASS RTCIceTransport interface: attribute onstatechange
-PASS RTCIceTransport interface: attribute ongatheringstatechange
-PASS RTCIceTransport interface: attribute onselectedcandidatepairchange
-FAIL RTCIceTransport must be primary interface of idlTestObjects.iceTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of idlTestObjects.iceTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "role" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "component" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "state" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "gatheringState" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "getLocalCandidates()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "getRemoteCandidates()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "getSelectedCandidatePair()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "getLocalParameters()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "getRemoteParameters()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "onstatechange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "ongatheringstatechange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCIceTransport interface: idlTestObjects.iceTransport must inherit property "onselectedcandidatepairchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-PASS RTCTrackEvent interface: existence and properties of interface object
-PASS RTCTrackEvent interface object length
-PASS RTCTrackEvent interface object name
-PASS RTCTrackEvent interface: existence and properties of interface prototype object
-PASS RTCTrackEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCTrackEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCTrackEvent interface: attribute receiver
-PASS RTCTrackEvent interface: attribute track
-PASS RTCTrackEvent interface: attribute streams
-PASS RTCTrackEvent interface: attribute transceiver
-FAIL RTCTrackEvent must be primary interface of initTrackEvent() assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL Stringification of initTrackEvent() assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "receiver" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "track" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "streams" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-FAIL RTCTrackEvent interface: initTrackEvent() must inherit property "transceiver" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
-PASS RTCSctpTransport interface: existence and properties of interface object
-PASS RTCSctpTransport interface object length
-PASS RTCSctpTransport interface object name
-PASS RTCSctpTransport interface: existence and properties of interface prototype object
-PASS RTCSctpTransport interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCSctpTransport interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCSctpTransport interface: attribute transport
-PASS RTCSctpTransport interface: attribute state
-PASS RTCSctpTransport interface: attribute maxMessageSize
-PASS RTCSctpTransport interface: attribute maxChannels
-PASS RTCSctpTransport interface: attribute onstatechange
-FAIL RTCSctpTransport must be primary interface of idlTestObjects.sctpTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of idlTestObjects.sctpTransport assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCSctpTransport interface: idlTestObjects.sctpTransport must inherit property "transport" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCSctpTransport interface: idlTestObjects.sctpTransport must inherit property "state" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCSctpTransport interface: idlTestObjects.sctpTransport must inherit property "maxMessageSize" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCSctpTransport interface: idlTestObjects.sctpTransport must inherit property "maxChannels" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL RTCSctpTransport interface: idlTestObjects.sctpTransport must inherit property "onstatechange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-PASS RTCDataChannel interface: existence and properties of interface object
-PASS RTCDataChannel interface object length
-PASS RTCDataChannel interface object name
-PASS RTCDataChannel interface: existence and properties of interface prototype object
-PASS RTCDataChannel interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCDataChannel interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCDataChannel interface: attribute label
-PASS RTCDataChannel interface: attribute ordered
-PASS RTCDataChannel interface: attribute maxPacketLifeTime
-PASS RTCDataChannel interface: attribute maxRetransmits
-PASS RTCDataChannel interface: attribute protocol
-PASS RTCDataChannel interface: attribute negotiated
-PASS RTCDataChannel interface: attribute id
-PASS RTCDataChannel interface: attribute readyState
-PASS RTCDataChannel interface: attribute bufferedAmount
-PASS RTCDataChannel interface: attribute bufferedAmountLowThreshold
-PASS RTCDataChannel interface: attribute onopen
-PASS RTCDataChannel interface: attribute onbufferedamountlow
-PASS RTCDataChannel interface: attribute onerror
-FAIL RTCDataChannel interface: attribute onclosing assert_true: The prototype object must have a property "onclosing" expected true got false
-PASS RTCDataChannel interface: attribute onclose
-PASS RTCDataChannel interface: operation close()
-PASS RTCDataChannel interface: attribute onmessage
-PASS RTCDataChannel interface: attribute binaryType
-PASS RTCDataChannel interface: operation send(USVString)
-PASS RTCDataChannel interface: operation send(Blob)
-PASS RTCDataChannel interface: operation send(ArrayBuffer)
-PASS RTCDataChannel interface: operation send(ArrayBufferView)
-PASS RTCDataChannel must be primary interface of new RTCPeerConnection().createDataChannel('')
-PASS Stringification of new RTCPeerConnection().createDataChannel('')
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "label" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "ordered" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "maxPacketLifeTime" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "maxRetransmits" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "protocol" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "negotiated" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "id" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "readyState" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "bufferedAmount" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "bufferedAmountLowThreshold" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onopen" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onbufferedamountlow" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onerror" with the proper type
-FAIL RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onclosing" with the proper type assert_inherits: property "onclosing" not found in prototype chain
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onclose" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "close()" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "onmessage" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "binaryType" with the proper type
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "send(USVString)" with the proper type
-PASS RTCDataChannel interface: calling send(USVString) on new RTCPeerConnection().createDataChannel('') with too few arguments must throw TypeError
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "send(Blob)" with the proper type
-PASS RTCDataChannel interface: calling send(Blob) on new RTCPeerConnection().createDataChannel('') with too few arguments must throw TypeError
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "send(ArrayBuffer)" with the proper type
-PASS RTCDataChannel interface: calling send(ArrayBuffer) on new RTCPeerConnection().createDataChannel('') with too few arguments must throw TypeError
-PASS RTCDataChannel interface: new RTCPeerConnection().createDataChannel('') must inherit property "send(ArrayBufferView)" with the proper type
-PASS RTCDataChannel interface: calling send(ArrayBufferView) on new RTCPeerConnection().createDataChannel('') with too few arguments must throw TypeError
-PASS RTCDataChannelEvent interface: existence and properties of interface object
-PASS RTCDataChannelEvent interface object length
-PASS RTCDataChannelEvent interface object name
-PASS RTCDataChannelEvent interface: existence and properties of interface prototype object
-PASS RTCDataChannelEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCDataChannelEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCDataChannelEvent interface: attribute channel
-PASS RTCDataChannelEvent must be primary interface of new RTCDataChannelEvent('channel', {
-          channel: new RTCPeerConnection().createDataChannel('')
-        })
-PASS Stringification of new RTCDataChannelEvent('channel', {
-          channel: new RTCPeerConnection().createDataChannel('')
-        })
-PASS RTCDataChannelEvent interface: new RTCDataChannelEvent('channel', {
-          channel: new RTCPeerConnection().createDataChannel('')
-        }) must inherit property "channel" with the proper type
-PASS RTCDTMFSender interface: existence and properties of interface object
-PASS RTCDTMFSender interface object length
-PASS RTCDTMFSender interface object name
-PASS RTCDTMFSender interface: existence and properties of interface prototype object
-PASS RTCDTMFSender interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCDTMFSender interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCDTMFSender interface: operation insertDTMF(DOMString, unsigned long, unsigned long)
-PASS RTCDTMFSender interface: attribute ontonechange
-PASS RTCDTMFSender interface: attribute canInsertDTMF
-PASS RTCDTMFSender interface: attribute toneBuffer
-PASS RTCDTMFToneChangeEvent interface: existence and properties of interface object
-PASS RTCDTMFToneChangeEvent interface object length
-PASS RTCDTMFToneChangeEvent interface object name
-PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object
-PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCDTMFToneChangeEvent interface: attribute tone
-PASS RTCStatsReport interface: existence and properties of interface object
-PASS RTCStatsReport interface object length
-PASS RTCStatsReport interface object name
-PASS RTCStatsReport interface: existence and properties of interface prototype object
-PASS RTCStatsReport interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCStatsReport interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCError interface: existence and properties of interface object
-PASS RTCError interface object length
-PASS RTCError interface object name
-PASS RTCError interface: existence and properties of interface prototype object
-PASS RTCError interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCError interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCError interface: attribute errorDetail
-PASS RTCError interface: attribute sdpLineNumber
-PASS RTCError interface: attribute httpRequestStatusCode
-PASS RTCError interface: attribute sctpCauseCode
-PASS RTCError interface: attribute receivedAlert
-PASS RTCError interface: attribute sentAlert
-PASS RTCErrorEvent interface: existence and properties of interface object
-PASS RTCErrorEvent interface object length
-PASS RTCErrorEvent interface object name
-PASS RTCErrorEvent interface: existence and properties of interface prototype object
-PASS RTCErrorEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS RTCErrorEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS RTCErrorEvent interface: attribute error
-FAIL RTCErrorEvent must be primary interface of new RTCErrorEvent('error') assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'RTCErrorEvent': 2 arguments required, but only 1 present."
-FAIL Stringification of new RTCErrorEvent('error') assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'RTCErrorEvent': 2 arguments required, but only 1 present."
-FAIL RTCErrorEvent interface: new RTCErrorEvent('error') must inherit property "error" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'RTCErrorEvent': 2 arguments required, but only 1 present."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/svg/zoom/page/zoom-background-image-tiled-expected.png b/third_party/blink/web_tests/svg/zoom/page/zoom-background-image-tiled-expected.png
index 0ab39c1..ce75d49 100644
--- a/third_party/blink/web_tests/svg/zoom/page/zoom-background-image-tiled-expected.png
+++ b/third_party/blink/web_tests/svg/zoom/page/zoom-background-image-tiled-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png b/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png
index c2345bb..dd50c337 100644
--- a/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png
+++ b/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-background-with-relative-size-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-relative-image-expected.png b/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-relative-image-expected.png
index 77c2b3a..e9d61f0 100644
--- a/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-relative-image-expected.png
+++ b/third_party/blink/web_tests/svg/zoom/page/zoom-svg-as-relative-image-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
deleted file mode 100644
index 901136d..0000000
--- a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/date/date-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
deleted file mode 100644
index 40ebbdaf..0000000
--- a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/datetimelocal/datetimelocal-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
deleted file mode 100644
index f9b1497..0000000
--- a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/month/month-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
deleted file mode 100644
index d4e580c..0000000
--- a/third_party/blink/web_tests/virtual/controls-refresh-hc/virtual/controls-refresh/color-scheme/week/week-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png
index 8eaff5ba..9b715cf 100644
--- a/third_party/blink/web_tests/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png
+++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/color-profile-mask-image-svg-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/forced-high-contrast-cascade/README.md b/third_party/blink/web_tests/virtual/forced-high-contrast-cascade/README.md
new file mode 100644
index 0000000..83e853c
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/forced-high-contrast-cascade/README.md
@@ -0,0 +1,6 @@
+This is a virtual test suite for the Cascade Project. It tests that
+forced-colors works when CSSCascade is enabled.
+
+Flags: CSSCascade,ForcedColors
+
+https://crbug.com/947004
diff --git a/third_party/blink/web_tests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/blink/web_tests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png
index 22ff6a2a..65352f6 100644
--- a/third_party/blink/web_tests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png
+++ b/third_party/blink/web_tests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/off-main-thread-css-paint/http/tests/csspaint/border-color-expected.png b/third_party/blink/web_tests/virtual/off-main-thread-css-paint/http/tests/csspaint/border-color-expected.png
new file mode 100644
index 0000000..427774c
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/off-main-thread-css-paint/http/tests/csspaint/border-color-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/events/event-listener-on-attribute-inside-shadow-dom-expected.txt b/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/events/event-listener-on-attribute-inside-shadow-dom-expected.txt
deleted file mode 100644
index f5fd7d6..0000000
--- a/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/events/event-listener-on-attribute-inside-shadow-dom-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CONSOLE ERROR: line 12: Uncaught TypeError: div2.createShadowRoot is not a function
-This tests ensures that an event listener on an attribute node inside a shadow DOM is properly unregistered when parent element of the attribute is moved to a new document.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-FAIL successfullyParsed should be true. Was false.
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/forms/datalist/datalist-inside-shadow-dom-expected.txt b/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/forms/datalist/datalist-inside-shadow-dom-expected.txt
deleted file mode 100644
index 666c52b..0000000
--- a/third_party/blink/web_tests/virtual/web-components-v0-disabled/fast/forms/datalist/datalist-inside-shadow-dom-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-CONSOLE ERROR: line 16: Uncaught TypeError: host.createShadowRoot is not a function
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
index d61a767..65ff51c 100644
--- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 497 tests; 401 PASS, 96 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 497 tests; 400 PASS, 97 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Test driver for asyncInitCertificate
@@ -471,7 +471,7 @@
 PASS RTCDTMFSender interface: attribute canInsertDTMF
 PASS RTCDTMFSender interface: attribute toneBuffer
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface object
-PASS RTCDTMFToneChangeEvent interface object length
+FAIL RTCDTMFToneChangeEvent interface object length assert_equals: wrong value for RTCDTMFToneChangeEvent.length expected 1 but got 2
 PASS RTCDTMFToneChangeEvent interface object name
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object
 PASS RTCDTMFToneChangeEvent interface: existence and properties of interface prototype object's "constructor" property
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index b29ecc6..2fd9054c 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: unknown
-Revision: a126f524fa825ac694f23fe459202fb26918d542
+Revision: 4dd9124e2fa42c53e137cf831e5d9193f189b543
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
index 2adcefc..98c3d09 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
@@ -16,6 +16,7 @@
 
 #include <fcntl.h>
 #include <stdlib.h>
+#include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
@@ -290,9 +291,17 @@
       }
       pid = creds.pid;
     }
-    if (pid > 0 && client.SetPtracer(pid) != 0) {
-      LOG(ERROR) << "failed to set ptracer";
-      return false;
+    if (pid > 0 && prctl(PR_SET_PTRACER, pid, 0, 0, 0) != 0) {
+      PLOG(WARNING) << "prctl";
+      // TODO(jperaza): If this call to set the ptracer failed, it might be
+      // possible to try again just before a dump request, in case the
+      // environment has changed. Revisit ExceptionHandlerClient::SetPtracer()
+      // and consider saving the result of this call in ExceptionHandlerClient
+      // or as a member in this signal handler. ExceptionHandlerClient hasn't
+      // been responsible for maintaining state and a new ExceptionHandlerClient
+      // has been constructed as a local whenever a client needs to communicate
+      // with the handler. ExceptionHandlerClient lifetimes and ownership will
+      // need to be reconsidered if it becomes responsible for state.
     }
     sock_to_handler_.reset(sock.release());
     handler_pid_ = pid;
diff --git a/third_party/crashpad/crashpad/util/linux/memory_map_test.cc b/third_party/crashpad/crashpad/util/linux/memory_map_test.cc
index 20e5f22..0ee90800 100644
--- a/third_party/crashpad/crashpad/util/linux/memory_map_test.cc
+++ b/third_party/crashpad/crashpad/util/linux/memory_map_test.cc
@@ -101,7 +101,10 @@
   ASSERT_TRUE(mapping);
   EXPECT_GE(code_address, mapping->range.Base());
   EXPECT_LT(code_address, mapping->range.End());
+#if !defined(OS_ANDROID)
+  // Android Q+ supports execute only memory.
   EXPECT_TRUE(mapping->readable);
+#endif
   EXPECT_FALSE(mapping->writable);
   EXPECT_TRUE(mapping->executable);
 
@@ -167,7 +170,10 @@
     ASSERT_TRUE(mapping);
     EXPECT_GE(code_address, mapping->range.Base());
     EXPECT_LT(code_address, mapping->range.End());
+#if !defined(OS_ANDROID)
+    // Android Q+ supports execute only memory.
     EXPECT_TRUE(mapping->readable);
+#endif
     EXPECT_TRUE(mapping->executable);
     EXPECT_FALSE(mapping->writable);
 
diff --git a/third_party/fuchsia-sdk/gen_build_defs.py b/third_party/fuchsia-sdk/gen_build_defs.py
index ccb21870..8a902f3 100755
--- a/third_party/fuchsia-sdk/gen_build_defs.py
+++ b/third_party/fuchsia-sdk/gen_build_defs.py
@@ -183,34 +183,5 @@
 
       buildfile.write(FormatGNTarget(converted) + '\n\n')
 
-      # TODO(fxb/42135): Remove this hack once dependencies have been updated.
-      # Create dummy targets using the old short names, which depend on the
-      # new fully-qualified names, to allow old dependencies to work.
-      if part['type'] == 'fidl_library':
-        target_name = ReformatTargetName(parsed['name'])
-
-        # Generate an old-style FIDL library target name, by stripping the
-        # "fuchsia-" prefix and replacing hyphens with underscores.
-        short_target_name = target_name[8:].replace('-', '_')
-
-        # fuchsia.inspect's short name clashes with the inspect source library.
-        if short_target_name == 'inspect':
-          continue
-
-        fields = {
-            'target_name' : short_target_name,
-            'type': 'group',
-            'public_deps': [ ':' + target_name]
-        }
-        buildfile.write(FormatGNTarget(fields) + '\n\n')
-      elif '-' in parsed['name']:
-        target_name = ReformatTargetName(parsed['name'])
-        fields = {
-            'target_name' : target_name.replace('-', '_'),
-            'type': 'group',
-            'public_deps': [ ':' + target_name]
-        }
-        buildfile.write(FormatGNTarget(fields) + '\n\n')
-
 if __name__ == '__main__':
   sys.exit(ConvertSdkManifests())
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn
index 26553bc..bc4805cc 100644
--- a/third_party/harfbuzz-ng/BUILD.gn
+++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -6,6 +6,7 @@
 import("//build/config/features.gni")
 import("//build/config/freetype/freetype.gni")
 import("//build/config/ui.gni")
+import("//components/paint_preview/buildflags/buildflags.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//third_party/harfbuzz-ng/harfbuzz.gni")
 
@@ -261,6 +262,13 @@
       "U_DISABLE_VERSION_SUFFIX=0",
     ]
 
+    if (enable_paint_preview) {
+      # Paint Previews make use of CFF subsetting. However, enabling this is
+      # expensive for binary size so only compile it when Paint Previews are
+      # compiled.
+      defines -= [ "HB_NO_SUBSET_CFF" ]
+    }
+
     if (is_component_build) {
       if (is_win) {
         defines += [ "HB_EXTERN=__declspec (dllexport) extern" ]
diff --git a/third_party/minigbm/BUILD.gn b/third_party/minigbm/BUILD.gn
index ad58294..a5bc98e 100644
--- a/third_party/minigbm/BUILD.gn
+++ b/third_party/minigbm/BUILD.gn
@@ -7,11 +7,10 @@
 assert(is_linux)
 
 declare_args() {
-  # Controls whether the build should use the version of minigbm library
-  # shipped with the system. In release builds of Chrome OS we use the
-  # system version, but when building on dev workstations or the Chrome
-  # waterfall we bundle it because Ubuntu doesn't ship a usable version.
-  use_system_minigbm = false
+  # Controls whether the build should use the version of minigbm library shipped
+  # with the system. In release builds of desktop Linux and Chrome OS we use the
+  # system version.
+  use_system_minigbm = is_desktop_linux
 
   use_amdgpu_minigbm = false
   use_exynos_minigbm = false
diff --git a/third_party/robolectric/BUILD.gn b/third_party/robolectric/BUILD.gn
index 96ac0d8..bfb8c9a 100644
--- a/third_party/robolectric/BUILD.gn
+++ b/third_party/robolectric/BUILD.gn
@@ -70,7 +70,6 @@
     "//third_party/android_deps:androidx_test_monitor_java",
     "//third_party/android_deps:com_google_guava_guava_java",
     "//third_party/bouncycastle:bouncycastle_java",
-    "//third_party/jsr-305:jsr_305_javalib",
     "//third_party/junit:junit",
     "//third_party/xstream:xstream_java",
   ]
@@ -139,8 +138,6 @@
   deps = [
     ":android-all-9-robolectric-4913185-2_java",
     ":robolectric_shadowapi_java",
-    "//third_party/intellij:intellij_annotations_java",
-    "//third_party/jsr-305:jsr_305_javalib",
   ]
   java_files = [
     "robolectric/annotations/src/main/java/org/robolectric/annotation/AccessibilityChecks.java",
@@ -164,8 +161,6 @@
     "//build/android:sun_tools_java",
     "//third_party/android_deps:com_google_guava_guava_java",
     "//third_party/gson:gson_java",
-    "//third_party/intellij:intellij_annotations_java",
-    "//third_party/jsr-305:jsr_305_javalib",
     "//third_party/ow2_asm:asm_commons_java",
     "//third_party/ow2_asm:asm_java",
     "//third_party/ow2_asm:asm_tree_java",
@@ -230,7 +225,6 @@
     ":robolectric_annotations_java",
     ":robolectric_utils_java",
     "//third_party/android_deps:com_google_guava_guava_java",
-    "//third_party/jsr-305:jsr_305_javalib",
   ]
   java_files = [
     "robolectric/resources/src/main/java/org/robolectric/RoboSettings.java",
@@ -374,7 +368,6 @@
     ":robolectric_shadowapi_java",
     ":robolectric_utils_java",
     "//third_party/android_deps:com_google_guava_guava_java",
-    "//third_party/jsr-305:jsr_305_javalib",
     "//third_party/ow2_asm:asm_commons_java",
     "//third_party/ow2_asm:asm_java",
     "//third_party/ow2_asm:asm_tree_java",
@@ -429,7 +422,6 @@
     ":robolectric_annotations_java",
     ":robolectric_sandbox_java",
     ":robolectric_shadowapi_java",
-    "//third_party/jsr-305:jsr_305_javalib",
     "//third_party/junit:junit",
   ]
 
@@ -868,7 +860,6 @@
     ":robolectric_shadowapi_java",
     ":robolectric_utils_java",
     "//third_party/accessibility_test_framework:accessibility_test_framework_java",
-    "//third_party/jsr-305:jsr_305_javalib",
 
     # Note that gson is not a direct dependency for this library, but must be
     # in the classpath when the Robolectric annotation processor runs.
@@ -876,7 +867,6 @@
     "//third_party/gson:gson_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/icu4j:icu4j_java",
-    "//third_party/intellij:intellij_annotations_java",
     "//third_party/sqlite4java:sqlite4java_java",
   ]
 
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index 4c6ecd98..9bc9bdc9 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -125,7 +125,7 @@
     </module>
     <module name="RegexpSinglelineJava">
       <property name="id" value="UseSharedPreferencesManagerFromChromeCheck"/>
-      <property name="severity" value="error"/>
+      <property name="severity" value="warning"/>
       <property name="format" value="(getAppSharedPreferences|getDefaultSharedPreferences)"/>
       <property name="ignoreComments" value="true"/>
       <property name="message" value="Use SharedPreferencesManager instead to access app-wide SharedPreferences from //src/chrome."/>
diff --git a/tools/android/checkstyle/suppressions.xml b/tools/android/checkstyle/suppressions.xml
index 61fe39f..488679b 100644
--- a/tools/android/checkstyle/suppressions.xml
+++ b/tools/android/checkstyle/suppressions.xml
@@ -6,12 +6,9 @@
   <suppress id="UseSharedPreferencesManagerFromChromeCheck"
             files="src/(android_webview|base|chromecast|components|content|device|media|net|remoting|services|testing|third_party|tools|ui|weblayer)/"/>
   <suppress id="UseSharedPreferencesManagerFromChromeCheck"
-            files="SharedPreferencesManager.java"/>
-  <suppress id="UseSharedPreferencesManagerFromChromeCheck"
             files="Test.java"/>
   <!-- All other usages of the app SharedPreference should go through
        ContextUtils. -->
-  <suppress id="DefaultSharedPreferencesCheck" files="ContextUtils.java"/>
   <suppress id="DefaultSharedPreferencesCheck" files="src/chrome/"/>
   <!-- Only chrome/ and remoting/ can depend on the support library. Ref:
        crbug.com/640248 -->
diff --git a/tools/binary_size/libsupersize/.gitignore b/tools/binary_size/libsupersize/.gitignore
new file mode 100644
index 0000000..60c7ab4
--- /dev/null
+++ b/tools/binary_size/libsupersize/.gitignore
@@ -0,0 +1 @@
+static/caspian_web*
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py
index 7a33c58..c0cf3943 100644
--- a/tools/binary_size/libsupersize/archive.py
+++ b/tools/binary_size/libsupersize/archive.py
@@ -1011,23 +1011,7 @@
   @staticmethod
   def _ParseResInfoFile(res_info_path):
     with open(res_info_path, 'r') as info_file:
-      res_info = {}
-      renames = {}
-      for line in info_file.readlines():
-        dest, source = line.strip().split(',')
-        # Allow indirection due to renames.
-        if dest.startswith('Rename:'):
-          dest = dest.split(':', 1)[1]
-          renames[dest] = source
-        else:
-          res_info[dest] = source
-      for dest, renamed_dest in renames.iteritems():
-        # Allow one more level of indirection due to renaming renamed files
-        renamed_dest = renames.get(renamed_dest, renamed_dest)
-        actual_source = res_info.get(renamed_dest)
-        if actual_source:
-          res_info[dest] = actual_source
-    return res_info
+      return dict(l.rstrip().split('\t') for l in info_file)
 
   def _LoadResInfo(self, size_info_prefix):
     apk_res_info_path = size_info_prefix + '.res.info'
diff --git a/tools/binary_size/libsupersize/caspian/README.md b/tools/binary_size/libsupersize/caspian/README.md
new file mode 100644
index 0000000..8b09c8fb
--- /dev/null
+++ b/tools/binary_size/libsupersize/caspian/README.md
@@ -0,0 +1,27 @@
+# Caspian
+
+## What is it?
+
+Caspian is the name for the WebAssembly portion of the SuperSize Tiger Viewer.
+
+## How do I build it?
+
+Install emscripten from:
+https://emscripten.org/docs/getting_started/downloads.html
+
+```sh
+git apply tools/binary_size/libsupersize/caspian/wasmbuild.patch
+gn gen out/caspian --args='is_official_build=true treat_warnings_as_errors=false fatal_linker_warnings=false'
+autoninja -C out/caspian tools/binary_size:caspian_web
+cp out/caspian/wasm/caspian_web.* tools/binary_size/libsupersize/static/
+```
+
+Then run locally via:
+```sh
+tools/binary_size/supersize start_server out.size
+```
+
+or upload to hosted site via:
+```sh
+tools/binary_size/libsupersize/upload_html_viewer.py --sync
+```
diff --git a/tools/binary_size/libsupersize/caspian/caspian.md b/tools/binary_size/libsupersize/caspian/caspian.md
deleted file mode 100644
index 0a6a8a5..0000000
--- a/tools/binary_size/libsupersize/caspian/caspian.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Caspian
-
-## What is it?
-
-Caspian is the name for the WebAssembly portion of the SuperSize Tiger Viewer.
-
-## How do I build it?
-
-1. Apply the patch file at `tools/binary_size/libsupersize/caspian/wasmbuild.patch`
-
-2. From `src/`, run
-`gn gen out/caspian &&
-third_party/depot_tools/autoninja -C out/caspian tools/binary_size:caspian_web -v &&
-cp out/caspian/wasm/caspian_web.* tools/binary_size/libsupersize/static/`
-
-  * If doing a release build, you should change your gn args: set is\_debug=false
-
-3. You can then launch a local instance using `tools/binary_size/supersize start_server out.size`
-
diff --git a/tools/binary_size/libsupersize/caspian/model.cc b/tools/binary_size/libsupersize/caspian/model.cc
index 2af5154..1377db1 100644
--- a/tools/binary_size/libsupersize/caspian/model.cc
+++ b/tools/binary_size/libsupersize/caspian/model.cc
@@ -328,15 +328,12 @@
     bool is_sparse,
     Json::Value* out) {
   if (symbol) {
+    (*out)["helpme"] = std::string(symbol->Name());
+    (*out)["idPath"] = std::string(symbol->TemplateName());
+    (*out)["fullName"] = std::string(symbol->FullName());
     if (symbol->NumAliases() > 1) {
       (*out)["numAliases"] = symbol->NumAliases();
     }
-    if (symbol->IsDex()) {
-      (*out)["idPath"] = std::string(symbol->FullName());
-    } else {
-      (*out)["idPath"] = std::string(symbol->TemplateName());
-      (*out)["fullName"] = std::string(symbol->FullName());
-    }
     if (symbol->SourcePath()) {
       (*out)["srcPath"] = symbol->SourcePath();
     }
diff --git a/tools/binary_size/libsupersize/caspian/tree_builder.cc b/tools/binary_size/libsupersize/caspian/tree_builder.cc
index 2d86e90..81ade41 100644
--- a/tools/binary_size/libsupersize/caspian/tree_builder.cc
+++ b/tools/binary_size/libsupersize/caspian/tree_builder.cc
@@ -159,7 +159,8 @@
     }
     TreeNode* symbol_node = new TreeNode();
     symbol_node->container_type = ContainerType::kSymbol;
-    symbol_node->id_path = GroupedPath{"", sym->FullName()};
+    symbol_node->id_path =
+        GroupedPath{"", sym->IsDex() ? sym->TemplateName() : sym->FullName()};
     symbol_node->size = sym->Pss();
     symbol_node->node_stats = NodeStats(*sym);
     symbol_node->symbol = sym;
diff --git a/tools/binary_size/libsupersize/static/infocard-ui.js b/tools/binary_size/libsupersize/static/infocard-ui.js
index a8b8c09..2b508fc0 100644
--- a/tools/binary_size/libsupersize/static/infocard-ui.js
+++ b/tools/binary_size/libsupersize/static/infocard-ui.js
@@ -88,6 +88,10 @@
             document.createElement('br'),
             dom.textElement('span', 'Component: ', 'symbol-name-info'),
             document.createTextNode(node.component || '(No component)'),
+            document.createElement('br'),
+            dom.textElement('span', 'Full Name: ', 'symbol-name-info'),
+            document.createTextNode(node.fullName || ''),
+            document.createElement('br'),
         ]);
       } else {
         const path = node.idPath.slice(0, node.shortNameIndex);
diff --git a/tools/binary_size/libsupersize/static/main.css b/tools/binary_size/libsupersize/static/main.css
index ce949d2a..61e2ee25 100644
--- a/tools/binary_size/libsupersize/static/main.css
+++ b/tools/binary_size/libsupersize/static/main.css
@@ -143,6 +143,9 @@
 }
 
 /** Tree nodes */
+[role="treeitem"] {
+  position: relative;
+}
 .node {
   display: flex;
   padding-right: 8px;
@@ -151,7 +154,6 @@
   text-decoration: none;
   color: inherit;
   border-radius: 4px;
-  position: relative;
 }
 .node:hover {
   background: #f1f3f4;
diff --git a/tools/binary_size/libsupersize/static/tree-ui.js b/tools/binary_size/libsupersize/static/tree-ui.js
index a79e09e..6b28860 100644
--- a/tools/binary_size/libsupersize/static/tree-ui.js
+++ b/tools/binary_size/libsupersize/static/tree-ui.js
@@ -310,10 +310,10 @@
     const isLeaf = data.children && data.children.length === 0;
     const template = isLeaf ? _leafTemplate : _treeTemplate;
     const element = document.importNode(template.content, true);
+    const listItemEl = element.firstElementChild;
+    const link = listItemEl.firstElementChild;
 
     // Associate clickable node & tree data
-    /** @type {HTMLAnchorElement | HTMLSpanElement} */
-    const link = element.querySelector('.node');
     _uiNodeData.set(link, Object.freeze(data));
 
     // Icons are predefined in the HTML through hidden SVG elements
@@ -327,7 +327,7 @@
     // Insert an SVG icon at the start of the link to represent adds/removals.
     const diffStatusIcon = getDiffStatusTemplate(data);
     if (diffStatusIcon) {
-      link.insertBefore(diffStatusIcon, link.firstElementChild);
+      listItemEl.insertBefore(diffStatusIcon, listItemEl.firstElementChild);
     }
 
     // Insert an SVG icon at the start of the link to represent type
diff --git a/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/Bundle.aab.res.info b/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/Bundle.aab.res.info
index ea057fd4..dede811 100644
--- a/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/Bundle.aab.res.info
+++ b/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/Bundle.aab.res.info
@@ -1 +1 @@
-drawable/test.xml,../../chrome/android/res/drawable/test.xml
+drawable/test.xml	../../chrome/android/res/drawable/test.xml
diff --git a/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/test.apk.res.info b/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/test.apk.res.info
index ea057fd4..dede811 100644
--- a/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/test.apk.res.info
+++ b/tools/binary_size/libsupersize/testdata/mock_source_directory/out/Release/size-info/test.apk.res.info
@@ -1 +1 @@
-drawable/test.xml,../../chrome/android/res/drawable/test.xml
+drawable/test.xml	../../chrome/android/res/drawable/test.xml
diff --git a/tools/clang/pylib/clang/compile_db.py b/tools/clang/pylib/clang/compile_db.py
index 3e8e12b..46220af 100755
--- a/tools/clang/pylib/clang/compile_db.py
+++ b/tools/clang/pylib/clang/compile_db.py
@@ -28,17 +28,33 @@
   Instead, we just use a regex, with the simplifying assumption that the path to
   clang-cl.exe contains no spaces.
   """
+  # If the driver mode is not already set then define it. Driver mode is
+  # automatically included in the compile db by clang starting with release
+  # 9.0.0.
+  if "--driver_mode" in command:
+    driver_mode = ""
+  # Only specify for Windows. Other platforms do fine without it.
+  elif sys.platform == 'win32':
+    driver_mode = '--driver-mode=cl'
+
   match = _CMD_LINE_RE.search(command)
   if match:
     match_dict = match.groupdict()
     command = ' '.join(
-        [match_dict['clang'], '--driver-mode=cl', match_dict['args']])
+        [match_dict['clang'], driver_mode, match_dict['args']])
   elif _debugging:
     print('Compile command didn\'t match expected regex!')
     print('Command:', command)
     print('Regex:', _CMD_LINE_RE.pattern)
 
-  return command
+  # Remove some blocklisted arguments. These are VisualStudio specific arguments
+  # not recognized or used by clangd. They only suppress or activate graphical
+  # output anyway.
+  blocklisted_arguments = ['/nologo', '/showIncludes']
+  command_parts = filter(lambda arg: arg not in blocklisted_arguments,
+    command.split())
+
+  return " ".join(command_parts)
 
 
 def _ProcessEntry(entry):
diff --git a/tools/clang/scripts/clang_tidy_tool.py b/tools/clang/scripts/clang_tidy_tool.py
index a1993a5c..57e54f70 100755
--- a/tools/clang/scripts/clang_tidy_tool.py
+++ b/tools/clang/scripts/clang_tidy_tool.py
@@ -29,6 +29,7 @@
 import os
 import subprocess
 import sys
+import update
 
 import build_clang_tools_extra
 
@@ -143,7 +144,10 @@
   parser = argparse.ArgumentParser(
       formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__)
   parser.add_argument(
-      '--fetch', action='store_true', help='Fetch and build clang sources')
+      '--fetch',
+      nargs='?',
+      const=update.CLANG_REVISION,
+      help='Fetch and build clang sources')
   parser.add_argument(
       '--build',
       action='store_true',
@@ -180,10 +184,10 @@
     sys.exit('clang-tidy binary doesn\'t exist at ' +
              GetBinaryPath(args.clang_build_dir, 'clang-tidy'))
 
-
   if args.fetch:
     steps.append(('Fetching LLVM sources', lambda:
-                  build_clang_tools_extra.FetchLLVM(args.clang_src_dir)))
+                  build_clang_tools_extra.FetchLLVM(args.clang_src_dir,
+                                                    args.fetch)))
 
   if args.build:
     steps.append(('Building clang-tidy',
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
index 1699b619..7658bd7 100644
--- a/tools/gritsettings/resource_ids
+++ b/tools/gritsettings/resource_ids
@@ -294,6 +294,9 @@
   "chromeos/components/media_app_ui/resources/mock/media_app_bundle_mock_resources.grd": {
     "includes": [12590],
   },
+  "chromeos/components/sample_system_web_app_ui/resources/sample_system_web_app_resources.grd": {
+    "includes": [12700],
+  },
   "chromeos/resources/chromeos_resources.grd": {
     "META": {"join": 2},
     "includes": [12710],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 39e99d1..815bf4e6 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -676,6 +676,7 @@
       'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_resource_whitelisting_fastbuild_java_coverage',
       'android-marshmallow-x86-fyi-rel': 'android_release_trybot_x86_resource_whitelisting',
       'android-oreo-arm64-cts-networkservice-dbg': 'android_debug_trybot_arm64',
+      'android-pie-arm64-coverage-rel': 'android_release_trybot_arm64_webview_google_native_coverage',
       'android-pie-arm64-rel': 'android_release_trybot_arm64_webview_google',
       'android-webview-pie-arm64-fyi-rel': 'android_release_trybot_arm64_webview_google',
       'android-pie-x86-fyi-rel': 'android_release_trybot_x86',
@@ -1190,6 +1191,12 @@
       'webview_google',
     ],
 
+    'android_release_trybot_arm64_webview_google_native_coverage': [
+      'android', 'release_trybot', 'arm64', 'strip_debug_info',
+      'webview_google',
+      'use_clang_coverage', 'partial_code_coverage_instrumentation',
+    ],
+
     'android_release_trybot_fastbuild': [
       'android', 'release_trybot', 'strip_debug_info', 'android_fastbuild',
       'android_no_proguard',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 8a161ff..71631584 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -4932,6 +4932,14 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="CookieControls.Bubble.CookiesInUse">
+  <owner>dullweber@chromium.org</owner>
+  <owner>huanzhong@chromium.org</owner>
+  <description>
+    &quot;Cookies in use&quot; dialog was opened from the cookie controls UI.
+  </description>
+</action>
+
 <action name="CookieControls.Bubble.NotWorking">
   <owner>dullweber@chromium.org</owner>
   <owner>huanzhong@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 95e651a..6f1dc9b7 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4917,6 +4917,7 @@
   <int value="-1442160010" label="Serial"/>
   <int value="-1314032804" label="MediaSessionImpl::OnServiceCreated"/>
   <int value="-1303768664" label="PopupBlockerTabHelper"/>
+  <int value="-1192330754" label="autofill::ContentAutofillDriver"/>
   <int value="-866479064" label="content::protocol::SecurityHandler"/>
   <int value="-684843031" label="SafeBrowsingTriggeredPopupBlocker"/>
   <int value="-438850149" label="PermissionRequestManager"/>
@@ -4931,6 +4932,8 @@
   <int value="2013040510" label="RenderFrameDevToolsAgentHost"/>
   <int value="2024383223"
       label="ChromePasswordManagerClient::BindCredentialManager"/>
+  <int value="2129248270"
+      label="password_manager::ContentPasswordManagerDriver"/>
 </enum>
 
 <enum name="BackForwardCacheEvictedAfterDocumentRestoredReason">
@@ -11618,14 +11621,41 @@
   <int value="536870904" label="Out of Memory"/>
   <int value="1066598273" label="FACILITY_VISUALCPP/ERROR_PROC_NOT_FOUND"/>
   <int value="1066598274" label="FACILITY_VISUALCPP/ERROR_MOD_NOT_FOUND"/>
+  <int value="1072103400" label="STATUS_CURRENT_TRANSACTION_NOT_VALID"/>
+  <int value="1072365548" label="STATUS_SXS_CORRUPT_ACTIVATION_STACK"/>
+  <int value="1072365552" label="STATUS_SXS_INVALID_DEACTIVATION"/>
+  <int value="1072365566" label="STATUS_SXS_CANT_GEN_ACTCTX"/>
+  <int value="1073739514" label="STATUS_VIRUS_INFECTED"/>
+  <int value="1073740004" label="STATUS_INVALID_THREAD"/>
+  <int value="1073740016" label="STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING"/>
+  <int value="1073740022" label="STATUS_THREADPOOL_HANDLE_EXCEPTION"/>
   <int value="1073740760" label="STATUS_INVALID_IMAGE_HASH"/>
+  <int value="1073740767" label="STATUS_VERIFIER_STOP"/>
+  <int value="1073740768" label="STATUS_ASSERTION_FAILURE"/>
+  <int value="1073740771" label="STATUS_FATAL_USER_CALLBACK_EXCEPTION"/>
+  <int value="1073740777" label="STATUS_INVALID_CRUNTIME_PARAMETER"/>
+  <int value="1073740782" label="STATUS_DELAY_LOAD_FAILED"/>
   <int value="1073740791" label="STATUS_STACK_BUFFER_OVERRUN"/>
   <int value="1073740940" label="STATUS_HEAP_CORRUPTION"/>
+  <int value="1073740959" label="STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT"/>
+  <int value="1073741131" label="STATUS_FLOAT_MULTIPLE_TRAPS"/>
+  <int value="1073741132" label="STATUS_FLOAT_MULTIPLE_FAULTS"/>
+  <int value="1073741205" label="STATUS_DLL_INIT_FAILED_LOGOFF"/>
+  <int value="1073741212" label="STATUS_RESOURCE_NOT_OWNED"/>
+  <int value="1073741431" label="STATUS_TOO_LATE"/>
   <int value="1073741502" label="STATUS_DLL_INIT_FAILED"/>
   <int value="1073741510" label="STATUS_CONTROL_C_EXIT"/>
+  <int value="1073741511" label="STATUS_ENTRYPOINT_NOT_FOUND"/>
   <int value="1073741515" label="STATUS_DLL_NOT_FOUND"/>
+  <int value="1073741523" label="STATUS_COMMITMENT_LIMIT"/>
+  <int value="1073741558" label="STATUS_PROCESS_IS_TERMINATING"/>
+  <int value="1073741569" label="STATUS_BAD_FUNCTION_TABLE"/>
   <int value="1073741571" label="STATUS_STACK_OVERFLOW"/>
+  <int value="1073741581" label="STATUS_INVALID_PARAMETER_5"/>
+  <int value="1073741595" label="STATUS_INTERNAL_ERROR"/>
   <int value="1073741659" label="STATUS_BAD_IMPERSONATION_LEVEL"/>
+  <int value="1073741662" label="STATUS_MEDIA_WRITE_PROTECTED"/>
+  <int value="1073741670" label="STATUS_INSUFFICIENT_RESOURCES"/>
   <int value="1073741674" label="STATUS_PRIVILEGED_INSTRUCTION"/>
   <int value="1073741675" label="STATUS_INTEGER_OVERFLOW"/>
   <int value="1073741676" label="STATUS_INTEGER_DIVIDE_BY_ZERO"/>
@@ -11637,18 +11667,33 @@
   <int value="1073741682" label="STATUS_FLOAT_DIVIDE_BY_ZERO"/>
   <int value="1073741683" label="STATUS_FLOAT_DENORMAL_OPERAND"/>
   <int value="1073741684" label="STATUS_ARRAY_BOUNDS_EXCEEDED"/>
+  <int value="1073741701" label="STATUS_INVALID_IMAGE_FORMAT"/>
+  <int value="1073741738" label="STATUS_DELETE_PENDING"/>
+  <int value="1073741744" label="STATUS_EA_TOO_LARGE"/>
+  <int value="1073741749" label="STATUS_THREAD_IS_TERMINATING"/>
+  <int value="1073741756" label="STATUS_QUOTA_EXCEEDED"/>
+  <int value="1073741757" label="STATUS_SHARING_VIOLATION"/>
+  <int value="1073741766" label="STATUS_OBJECT_PATH_NOT_FOUND"/>
+  <int value="1073741772" label="STATUS_OBJECT_NAME_NOT_FOUND"/>
   <int value="1073741783" label="STATUS_INVALID_UNWIND_TARGET"/>
+  <int value="1073741784" label="STATUS_BAD_STACK"/>
+  <int value="1073741785" label="STATUS_UNWIND"/>
   <int value="1073741786" label="STATUS_INVALID_DISPOSITION"/>
   <int value="1073741787" label="STATUS_NONCONTINUABLE_EXCEPTION"/>
+  <int value="1073741788" label="STATUS_OBJECT_TYPE_MISMATCH"/>
   <int value="1073741790" label="STATUS_ACCESS_DENIED"/>
   <int value="1073741794" label="STATUS_INVALID_LOCK_SEQUENCE"/>
   <int value="1073741795" label="STATUS_ILLEGAL_INSTRUCTION"/>
+  <int value="1073741796" label="STATUS_INVALID_SYSTEM_SERVICE"/>
   <int value="1073741800" label="STATUS_CONFLICTING_ADDRESSES"/>
   <int value="1073741801" label="STATUS_NO_MEMORY"/>
   <int value="1073741811" label="STATUS_INVALID_PARAMETER"/>
   <int value="1073741816" label="STATUS_INVALID_HANDLE"/>
   <int value="1073741818" label="STATUS_IN_PAGE_ERROR"/>
   <int value="1073741819" label="STATUS_ACCESS_VIOLATION"/>
+  <int value="1073741820" label="STATUS_INFO_LENGTH_MISMATCH"/>
+  <int value="1073741822" label="STATUS_NOT_IMPLEMENTED"/>
+  <int value="1073741823" label="STATUS_UNSUCCESSFUL"/>
   <int value="1073741829" label="STATUS_SEGMENT_NOTIFICATION"/>
   <int value="1073741845" label="STATUS_FATAL_APP_EXIT"/>
   <int value="2147483644" label="STATUS_SINGLE_STEP"/>
@@ -18933,6 +18978,7 @@
   <int value="654" label="DNSInterceptionChecksEnabled"/>
   <int value="655" label="PrimaryMouseButtonSwitch"/>
   <int value="656" label="ReportDeviceCpuInfo"/>
+  <int value="657" label="DeviceLoginScreenPrimaryMouseButtonSwitch"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -25621,7 +25667,7 @@
   <int value="3028" label="CreateObjectBlob"/>
   <int value="3029" label="QuotaRead"/>
   <int value="3030" label="DelegateFocus"/>
-  <int value="3031" label="DelegateFocusNotFirstInFlatTree"/>
+  <int value="3031" label="OBSOLETE_DelegateFocusNotFirstInFlatTree"/>
   <int value="3032" label="ThirdPartySharedWorker"/>
   <int value="3033" label="ThirdPartyBroadcastChannel"/>
   <int value="3034"
@@ -25715,6 +25761,11 @@
   <int value="3118" label="LongTaskBufferFull"/>
   <int value="3119" label="HTMLMetaElementMonetization"/>
   <int value="3120" label="HTMLLinkElementMonetization"/>
+  <int value="3121" label="InputTypeCheckboxRenderedNonSquare"/>
+  <int value="3122" label="InputTypeRadioRenderedNonSquare"/>
+  <int value="3123" label="WebkitBoxPackJustifyDoesSomething"/>
+  <int value="3124" label="WebkitBoxPackCenterDoesSomething"/>
+  <int value="3125" label="WebkitBoxPackEndDoesSomething"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -38410,6 +38461,7 @@
   <int value="892899792" label="MaterialDesignIncognitoNTP:disabled"/>
   <int value="898311758" label="ReaderMode:disabled"/>
   <int value="900614020" label="ContentSuggestionsShowSummary:disabled"/>
+  <int value="902209599" label="ShelfHotseat:enabled"/>
   <int value="902839593" label="WebContentsForceDark:disabled"/>
   <int value="903267263" label="disable-offline-pages"/>
   <int value="908302031"
@@ -38517,6 +38569,7 @@
       label="AllowDownloadResumptionWithoutStrongValidators:enabled"/>
   <int value="1046878091" label="PasswordForceSaving:enabled"/>
   <int value="1046981538" label="OfflinePagesShowAlternateDinoPage:disabled"/>
+  <int value="1047110483" label="ShelfHotseat:disabled"/>
   <int value="1049885154" label="OfflinePagesPrefetching:disabled"/>
   <int value="1050048304" label="enable-font-cache-scaling"/>
   <int value="1050321458" label="new-profile-management"/>
@@ -48245,6 +48298,13 @@
   <int value="3" label="Clicked Ok"/>
 </enum>
 
+<enum name="PasswordLeakDetectionError">
+  <int value="0" label="Not signed in"/>
+  <int value="1" label="Token request error"/>
+  <int value="2" label="Hashing/encryption error"/>
+  <int value="3" label="Invalid server response"/>
+</enum>
+
 <enum name="PasswordLeakLookupResponseResult">
   <int value="0" label="Success"/>
   <int value="1" label="Network/server error"/>
@@ -50842,7 +50902,7 @@
   <int value="21" label="RENDERER_CRASHED"/>
   <int value="22" label="UNSUPPORTED_SCHEME"/>
   <int value="23" label="INVALID_HTTP_METHOD"/>
-  <int value="24" label="WINDOW_PRINT"/>
+  <int value="24" label="WINDOW_PRINT (Obsolete)"/>
   <int value="25" label="RECENTLY_VISITED"/>
   <int value="26" label="WINDOW_OPENER"/>
   <int value="27" label="PAGE_ID_CONFLICT"/>
@@ -55192,6 +55252,9 @@
 </enum>
 
 <enum name="SafeBrowsingUserConsentVsUrlCheckRaceResult">
+  <obsolete>
+    The relevant code was deleted in December 2019.
+  </obsolete>
   <int value="0" label="URL check finished first, URL is safe"/>
   <int value="1" label="URL check finished first, URL is malicious"/>
   <int value="2" label="User opted in, URL is safe"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c051f7d..b7688dd 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -5199,7 +5199,7 @@
 
 <histogram
     name="Apps.AppList.DriveQuickAccessProvider.GetQuickAccessItemsLatency"
-    units="ms" expires_after="2020-04-12">
+    units="ms" expires_after="2020-06-14">
   <owner>wrong@chromium.org</owner>
   <owner>tby@chromium.org</owner>
   <owner>jiameng@chromium.org</owner>
@@ -7035,7 +7035,7 @@
 </histogram>
 
 <histogram name="Arc.IntentHelper.OpenType" enum="ArcIntentHelperOpenType"
-    expires_after="2020-04-05">
+    expires_after="2020-06-14">
   <owner>hashimoto@google.com</owner>
   <owner>shihuis@google.com</owner>
   <summary>
@@ -7110,7 +7110,7 @@
 </histogram>
 
 <histogram name="Arc.OptInAction" enum="ArcOptInAction"
-    expires_after="2020-04-12">
+    expires_after="2020-06-14">
   <owner>elijahtaylor@google.com</owner>
   <owner>shihuis@google.com</owner>
   <summary>Arc OptIn action taken by user.</summary>
@@ -7131,7 +7131,7 @@
 </histogram>
 
 <histogram name="Arc.OptInSilentAuthCode" enum="ArcOptInSilentAuthCode"
-    expires_after="2020-04-05">
+    expires_after="2020-06-14">
   <owner>elijahtaylor@google.com</owner>
   <summary>
     Arc Silent Auth Code status. This status is set during the ARC OptIn flow.
@@ -8657,7 +8657,7 @@
 </histogram>
 
 <histogram name="Ash.SwipeDownDrag.Tab.PresentationTime.TabletMode" units="ms"
-    expires_after="2020-03-29">
+    expires_after="2020-06-14">
   <owner>omrilio@chromium.org</owner>
   <summary>Presentation time while dragging a tab in tablet mode.</summary>
 </histogram>
@@ -16732,7 +16732,7 @@
 
 <histogram
     name="Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred"
-    enum="NQEEffectiveConnectionType" expires_after="2020-04-05">
+    enum="NQEEffectiveConnectionType" expires_after="2020-06-14">
   <owner>sclittle@chromium.org</owner>
   <summary>
     Records the effective connection type whenever a lazily-loaded iframe that
@@ -19553,7 +19553,7 @@
 </histogram>
 
 <histogram name="BookmarkManager.CommandMenuOpened"
-    enum="BookmarkManagerMenuSource" expires_after="2020-04-12">
+    enum="BookmarkManagerMenuSource" expires_after="2020-06-14">
   <owner>calamity@chromium.org</owner>
   <summary>
     Logs where the menu was opened from when a user action opens the command
@@ -19793,7 +19793,7 @@
   <summary>Time from power on to login panel ready (Chrome OS).</summary>
 </histogram>
 
-<histogram name="BootTime.Total2" units="ms" expires_after="2020-03-01">
+<histogram name="BootTime.Total2" units="ms" expires_after="2020-06-14">
   <owner>bccheng@chromium.org</owner>
   <owner>semenzato@chromium.org</owner>
   <summary>Time from power on to login panel ready (Chrome OS).</summary>
@@ -25370,7 +25370,7 @@
 </histogram>
 
 <histogram name="ContentSettings.Popups" enum="ContentSettingPopupAction"
-    expires_after="2020-02-16">
+    expires_after="2020-06-14">
   <owner>charleszhao@chromium.org</owner>
   <summary>
     Tracks whether the popup content blocked puzzle piece was shown in the
@@ -28534,8 +28534,8 @@
   <summary>Time taken for successful backup.</summary>
 </histogram>
 
-<histogram base="true" name="Crostini.ContainerOsVersion"
-    enum="CrostiniContainerOsVersion" expires_after="2020-11-01">
+<histogram name="Crostini.ContainerOsVersion" enum="CrostiniContainerOsVersion"
+    expires_after="2020-11-01">
   <owner>davidmunro@chromium.org</owner>
   <owner>nverne@chromium.org</owner>
   <owner>benwells@chromium.org</owner>
@@ -51796,7 +51796,7 @@
 </histogram>
 
 <histogram name="FCMInvalidations.TokenStateOnRegistrationRequest"
-    enum="TokenStateOnRegistrationRequest" expires_after="M80">
+    enum="TokenStateOnRegistrationRequest" expires_after="2020-06-14">
   <obsolete>
     Replaced in 2019-12 by FCMInvalidations.TokenStateOnRegistrationRequest2.
     This first version did not record the &quot;Token was cleared&quot; bucket.
@@ -53987,7 +53987,7 @@
 </histogram>
 
 <histogram name="GCM.SendWebPushMessageForbiddenBody"
-    enum="ForbiddenResponseBody" expires_after="M80">
+    enum="ForbiddenResponseBody" expires_after="2020-06-14">
   <owner>alexchau@chromium.org</owner>
   <owner>peter@chromium.org</owner>
   <summary>
@@ -54098,7 +54098,7 @@
   <summary>Number of retries before a GCM unregistration succeeds.</summary>
 </histogram>
 
-<histogram name="GCM.UserSignedIn" enum="Boolean" expires_after="2020-02-16">
+<histogram name="GCM.UserSignedIn" enum="Boolean" expires_after="2020-06-14">
   <owner>jianli@chromium.org</owner>
   <summary>
     Indicates whether the user was signed in when GCM started up.
@@ -61868,7 +61868,7 @@
 </histogram>
 
 <histogram name="IOS.Cookies.GetCookiesForURLCallResult"
-    enum="IOSGetCookiesForURLCallResult" expires_after="2020-02-16">
+    enum="IOSGetCookiesForURLCallResult" expires_after="2020-06-14">
   <owner>mrefaat@chromium.org</owner>
   <summary>
     Recorded to indicate whether the GetCookiesForURL call found cookies or not
@@ -61893,7 +61893,7 @@
 </histogram>
 
 <histogram name="IOS.CRWWKNavigationStatesRemoveOldPending" enum="Boolean"
-    expires_after="2020-04-05">
+    expires_after="2020-06-14">
   <owner>justincohen@chromium.org</owner>
   <owner>gambard@chromium.org</owner>
   <summary>
@@ -97839,19 +97839,19 @@
 </histogram>
 
 <histogram name="OAuth2Login.SessionRestore" enum="GaiaSessionRestoreOutcome"
-    expires_after="M78">
+    expires_after="2020-12-17">
   <owner>tbarzic@chromium.org</owner>
   <summary>Outcome of Chrome OS GAIA cookie session restore process.</summary>
 </histogram>
 
 <histogram name="OAuth2Login.SessionRestoreTimeToFailure" units="ms"
-    expires_after="M78">
+    expires_after="2020-12-17">
   <owner>tbarzic@chromium.org</owner>
   <summary>How long it takes for the session restore to fail.</summary>
 </histogram>
 
 <histogram name="OAuth2Login.SessionRestoreTimeToSuccess" units="ms"
-    expires_after="2020-02-16">
+    expires_after="2020-12-17">
   <owner>tbarzic@chromium.org</owner>
   <summary>
     How long it takes for the session restore to finish succeessfully.
@@ -108464,7 +108464,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.AccessTokenFetchStatus"
-    enum="GoogleServiceAuthError" expires_after="2020-05-24">
+    enum="GoogleServiceAuthError" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108474,7 +108474,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.AccessTokenNetErrorCode"
-    enum="NetErrorCodes" expires_after="2020-01-31">
+    enum="NetErrorCodes" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108484,22 +108484,21 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.AnalyzeSingleLeakResponseResult"
-    enum="PasswordAnalyzeLeakResponseResult" expires_after="2020-05-24">
+    enum="PasswordAnalyzeLeakResponseResult" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>Result of analyzing a single leak response.</summary>
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime"
-    units="ms" expires_after="2020-05-24">
+    units="ms" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>The time it took to analyze a single leak lookup response.</summary>
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.DialogDismissalReason"
-    enum="PasswordLeakDetectionDialogDismissalReason"
-    expires_after="2020-05-24">
+    enum="PasswordLeakDetectionDialogDismissalReason" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108509,7 +108508,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.Enabled" enum="BooleanEnabled"
-    expires_after="2020-01-31">
+    expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108518,8 +108517,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.LeakDetection.Error"
+    enum="PasswordLeakDetectionError" expires_after="M84">
+  <owner>jdoerrie@chromium.org</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Shows the error that happened in password leak detection on sign-in.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.LeakDetection.HttpResponseCode"
-    enum="HttpResponseCode" expires_after="2020-05-24">
+    enum="HttpResponseCode" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108529,7 +108537,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.LookupSingleLeakResponseResult"
-    enum="PasswordLeakLookupResponseResult" expires_after="2020-05-24">
+    enum="PasswordLeakLookupResponseResult" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108539,7 +108547,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.NetErrorCode"
-    enum="NetErrorCodes" expires_after="2020-01-31">
+    enum="NetErrorCodes" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108549,7 +108557,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.NotifyIsLeakedTime" units="ms"
-    expires_after="2020-05-24">
+    expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108559,7 +108567,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.ObtainAccessTokenTime"
-    units="ms" expires_after="2020-01-31">
+    units="ms" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108569,7 +108577,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.PrepareSingleLeakRequestTime"
-    units="ms" expires_after="2020-01-31">
+    units="ms" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108578,7 +108586,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime"
-    units="ms" expires_after="2020-01-31">
+    units="ms" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108588,7 +108596,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.SingleLeakResponsePrefixes"
-    units="prefixes" expires_after="2020-05-24">
+    units="prefixes" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -108598,7 +108606,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.SingleLeakResponseSize"
-    units="bytes" expires_after="2020-05-24">
+    units="bytes" expires_after="M84">
   <owner>jdoerrie@chromium.org</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -121811,7 +121819,7 @@
   </summary>
 </histogram>
 
-<histogram name="Quota.AgeOfDataInDays" units="days" expires_after="2020-03-29">
+<histogram name="Quota.AgeOfDataInDays" units="days" expires_after="2020-06-14">
   <owner>jarrydg@chromium.org</owner>
   <summary>
     How many kilobytes are how old. Similar to |AgeOfOrigin| except a sample is
@@ -121839,7 +121847,7 @@
 </histogram>
 
 <histogram name="Quota.DaysBetweenRepeatedOriginEvictions" units="units"
-    expires_after="2020-04-05">
+    expires_after="2020-06-14">
   <owner>jarrydg@chromium.org</owner>
   <summary>
     The number of days since an origin was last chosen to be evicted from the
@@ -128909,7 +128917,10 @@
 </histogram>
 
 <histogram name="SafeBrowsing.WebView.UserConsentVsUrlCheckRace"
-    enum="SafeBrowsingUserConsentVsUrlCheckRaceResult">
+    enum="SafeBrowsingUserConsentVsUrlCheckRaceResult" expires_after="M81">
+  <obsolete>
+    Removed in December 2019 because logic was simplified to remove this race.
+  </obsolete>
   <owner>ntfschr@chromium.org</owner>
   <summary>
     WebView can simultaneously check for user opt-in and Safe-Browsing-check the
@@ -146391,7 +146402,7 @@
 </histogram>
 
 <histogram name="Stability.Android.OomKillReverseRank" units="rank"
-    expires_after="2020-04-10">
+    expires_after="2020-06-14">
   <owner>boliu@chromium.org</owner>
   <owner>ssid@chromium.org</owner>
   <summary>
@@ -149084,7 +149095,7 @@
 </histogram>
 
 <histogram name="SubresourceFilter.DocumentLoad.ActivationState"
-    enum="SubresourceFilterActivationState" expires_after="2020-03-08">
+    enum="SubresourceFilterActivationState" expires_after="2020-06-14">
   <owner>engedy@chromium.org</owner>
   <summary>
     Whenever a document load is committed in a main frame or subframe, records
@@ -151368,6 +151379,27 @@
   </summary>
 </histogram>
 
+<histogram name="Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailed"
+    enum="Boolean" expires_after="M81">
+  <owner>mmoskvitin@google.com</owner>
+  <owner>mastiz@chromium.org</owner>
+  <summary>
+    Recorded when Nigori-only configuration failed. Indicates whether there was
+    a valid access token when failure happened.
+  </summary>
+</histogram>
+
+<histogram
+    name="Sync.HasAccessTokenWhenNigoriOnlyConfigurationFailedWith5SecBackoff"
+    enum="Boolean" expires_after="M81">
+  <owner>mmoskvitin@google.com</owner>
+  <owner>mastiz@chromium.org</owner>
+  <summary>
+    Recorded when Nigori-only configuration failed with 5 seconds backoff.
+    Indicates whether there was a valid access token when failure happened.
+  </summary>
+</histogram>
+
 <histogram name="Sync.InitialState" enum="SyncInitialState"
     expires_after="2020-05-24">
   <owner>treib@chromium.org</owner>
@@ -159474,7 +159506,7 @@
 </histogram>
 
 <histogram name="UMA.TruncatedEvents.UserAction" units="events"
-    expires_after="2020-06-07">
+    expires_after="2020-06-14">
   <owner>rkaplow@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -162540,7 +162572,7 @@
 </histogram>
 
 <histogram name="V8.WasmModuleSizeBytes" units="bytes"
-    expires_after="2020-03-31">
+    expires_after="2020-06-14">
   <owner>titzer@chromium.org</owner>
   <owner>adamk@chromium.org</owner>
   <owner>ahaas@chromium.org</owner>
@@ -165039,7 +165071,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContextOptions.sampleRate" units="Hz"
-    expires_after="2020-03-08">
+    expires_after="2020-06-14">
   <owner>rtoy@chromium.org</owner>
   <owner>hongchan@chromium.org</owner>
   <summary>
@@ -165050,7 +165082,7 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContextOptions.sampleRateRatio" units="units"
-    expires_after="2020-03-08">
+    expires_after="2020-06-14">
   <owner>rtoy@chromium.org</owner>
   <owner>hongchan@chromium.org</owner>
   <summary>
@@ -189029,11 +189061,11 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="WebAppSystemProfileCategory" separator=".">
-  <suffix base="true" name="Ephemeral" label="Guest or incognito"/>
-  <suffix base="true" name="Kiosk" label="Kioso app"/>
-  <suffix base="true" name="Other" label="Other"/>
-  <suffix base="true" name="Primary" label="Regular user"/>
-  <suffix base="true" name="SigninOrLockScreen" label="Sign in or lockscreen"/>
+  <suffix name="Ephemeral" label="Guest or incognito"/>
+  <suffix name="Kiosk" label="Kioso app"/>
+  <suffix name="Other" label="Other"/>
+  <suffix name="Primary" label="Regular user"/>
+  <suffix name="SigninOrLockScreen" label="Sign in or lockscreen"/>
   <affected-histogram name="Webapp.InstallResult.System.Profiles"/>
   <affected-histogram
       name="Webapp.InstallResultExtensionDisabledReason.System.Profiles"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 89d61588..357fdb84 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -6576,10 +6576,20 @@
     </summary>
   </metric>
   <metric name="ThirdPartyCookieBlockingEnabledForSite">
+    <owner>dullweber@chromium.org</owner>
+    <owner>huanzhong@chromium.org</owner>
     <summary>
       Records whether third party cookie blocking was enabled for a site. Only
       recorded for users who enabled the cookie controls ui.
     </summary>
+    <aggregation>
+      <history>
+        <index fields="profile.country"/>
+        <statistics>
+          <enumeration/>
+        </statistics>
+      </history>
+    </aggregation>
   </metric>
   <metric name="WasCached">
     <summary>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv
index d3686b0..cbe58186 100644
--- a/tools/perf/benchmark.csv
+++ b/tools/perf/benchmark.csv
@@ -57,8 +57,8 @@
 startup.mobile,"pasko@chromium.org, chrome-android-perf-status@chromium.org",Speed>Metrics>SystemHealthRegressions,,
 system_health.common_desktop,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,2019,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
 system_health.common_mobile,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
-system_health.memory_desktop,perezju@chromium.org,,https://bit.ly/system-health-benchmarks,"2016,2018,2019,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
-system_health.memory_mobile,perezju@chromium.org,,https://bit.ly/system-health-benchmarks,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
+system_health.memory_desktop,"pasko@chromium.org, crouleau@chromium.org, chrome-android-perf-status@chromium.org",,https://bit.ly/system-health-benchmarks,"2016,2018,2019,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,webgl"
+system_health.memory_mobile,"pasko@chromium.org, crouleau@chromium.org, chrome-android-perf-status@chromium.org",,https://bit.ly/system-health-benchmarks,"2016,2018,2019,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy"
 system_health.webview_startup,"oksamyt@chromium.org, torne@chromium.org, changwan@chromium.org",Mobile>WebView>Perf,,"2016,health_check"
 tab_switching.typical_25,vovoy@chromium.org,OS>Performance,,"2016,tabs_switching"
 tracing.tracing_with_background_memory_infra,ssid@chromium.org,,,
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py
index cf1b14a0..d344cc7 100644
--- a/tools/perf/benchmarks/system_health.py
+++ b/tools/perf/benchmarks/system_health.py
@@ -117,7 +117,8 @@
                                           take_memory_measurement=True)
 
 
-@benchmark.Info(emails=['perezju@chromium.org'],
+@benchmark.Info(emails=['pasko@chromium.org', 'crouleau@chromium.org',
+                        'chrome-android-perf-status@chromium.org'],
                 documentation_url='https://bit.ly/system-health-benchmarks')
 class DesktopMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Desktop Chrome Memory System Health Benchmark."""
@@ -129,7 +130,8 @@
     return 'system_health.memory_desktop'
 
 
-@benchmark.Info(emails=['perezju@chromium.org'],
+@benchmark.Info(emails=['pasko@chromium.org', 'crouleau@chromium.org',
+                        'chrome-android-perf-status@chromium.org'],
                 documentation_url='https://bit.ly/system-health-benchmarks')
 class MobileMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Mobile Chrome Memory System Health Benchmark."""
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py
index 5430ddc..4cf1e2f 100644
--- a/tools/perf/benchmarks/system_health_smoke_test.py
+++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -41,6 +41,9 @@
 
   # crbug.com/878390 - These stories are already covered by their 2018 or
   # 2019 versions and will later be removed.
+  'system_health.memory_mobile/background:social:facebook',
+  'system_health.memory_mobile/background:media:imgur',
+  'system_health.memory_mobile/browse:chrome:omnibox',
   'system_health.memory_mobile/browse:tech:discourse_infinite_scroll',
   'system_health.memory_mobile/browse:shopping:amazon',
   'system_health.memory_mobile/browse:social:facebook_infinite_scroll',
@@ -58,6 +61,8 @@
   'system_health.memory_mobile/load:news:qq',
   'system_health.memory_mobile/load:news:reddit',
   'system_health.memory_mobile/load:news:washingtonpost',
+  'system_health.memory_mobile/load:search:amazon',
+  'system_health.memory_mobile/load:search:taobao',
   'system_health.memory_mobile/load:tools:stackoverflow',
   'system_health.memory_desktop/load_accessibility:shopping:amazon',
   'system_health.memory_desktop/browse_accessibility:tech:codesearch',
diff --git a/tools/perf/cli_tools/update_wpr/update_wpr.py b/tools/perf/cli_tools/update_wpr/update_wpr.py
index 9d6e381b..a6cf876 100644
--- a/tools/perf/cli_tools/update_wpr/update_wpr.py
+++ b/tools/perf/cli_tools/update_wpr/update_wpr.py
@@ -347,8 +347,7 @@
     """Creates, starts a Pinpoint job and returns its URL."""
     try:
       resp = pinpoint_service.NewJob(
-          start_git_hash='HEAD',
-          end_git_hash='HEAD',
+          base_git_hash='HEAD',
           target='performance_test_suite',
           patch=self._GetBranchIssueUrl(),
           bug_id=self.bug_id or '',
@@ -453,7 +452,7 @@
       if self._IsDesktop():
         configs = ['linux-perf', 'win-10-perf', 'mac-10_12_laptop_low_end-perf']
       else:
-        configs = ['android-nexus5x-perf']
+        configs = ['android-pixel2-perf']
     for config in configs:
       job_url = self._StartPinpointJob(config)
       if not job_url:
diff --git a/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py b/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
index 1290ea9..ff16af3 100644
--- a/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
+++ b/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
@@ -368,8 +368,7 @@
         self.wpr_updater.StartPinpointJobs(),
         (['<url>', '<url>', '<url>'], []))
     new_job.assert_called_with(
-        start_git_hash='HEAD',
-        end_git_hash='HEAD',
+        base_git_hash='HEAD',
         target='performance_test_suite',
         patch='<issue-url>',
         bug_id='',
@@ -390,8 +389,7 @@
     self.assertEqual(
         self.wpr_updater.StartPinpointJobs(['<config>']), ([], ['<config>']))
     new_job.assert_called_once_with(
-        start_git_hash='HEAD',
-        end_git_hash='HEAD',
+        base_git_hash='HEAD',
         target='performance_test_suite',
         patch='<issue-url>',
         bug_id='',
diff --git a/tools/perf/contrib/cluster_telemetry/OWNERS b/tools/perf/contrib/cluster_telemetry/OWNERS
index 0f070b1..e355ad1 100644
--- a/tools/perf/contrib/cluster_telemetry/OWNERS
+++ b/tools/perf/contrib/cluster_telemetry/OWNERS
@@ -1,5 +1,8 @@
 rmistry@chromium.org
 
+# Uncomment when alexmt@ becomes a committer.
+# per-file ad_tagging_ct.py=alexmt@chromium.org
+per-file ad_tagging_ct.py=johnidel@chromium.org
 per-file loading_ct.py=tdresser@chromium.org
 per-file loading_ct.py=maxlg@chromium.org
 per-file loading_ct.py=dproy@chromium.org
diff --git a/tools/perf/contrib/cluster_telemetry/ad_tagging_ct.py b/tools/perf/contrib/cluster_telemetry/ad_tagging_ct.py
new file mode 100644
index 0000000..7590a363c
--- /dev/null
+++ b/tools/perf/contrib/cluster_telemetry/ad_tagging_ct.py
@@ -0,0 +1,80 @@
+# 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.
+
+from contrib.cluster_telemetry import ct_benchmarks_util, page_set
+from core import perf_benchmark
+import py_utils
+from telemetry import benchmark
+from telemetry.page import cache_temperature
+from telemetry.timeline import chrome_trace_category_filter
+from telemetry.web_perf import timeline_based_measurement
+
+_NAVIGATION_TIMEOUT = 180
+_QUIESCENCE_TIMEOUT = 30
+
+# Benchmark to measure various UMA histograms relevant to AdTagging as well as
+# CPU usage on page loads. These measurements will help to determine the
+# accuracy of AdTagging.
+@benchmark.Info(emails=['alexmt@chromium.org','johnidel@chromium.org'],
+                component='UI>Browser>AdFilter')
+class AdTaggingClusterTelemetry(perf_benchmark.PerfBenchmark):
+
+  @classmethod
+  def AddBenchmarkCommandLineArgs(cls, parser):
+    ct_benchmarks_util.AddBenchmarkCommandLineArgs(parser)
+
+  @classmethod
+  def ProcessCommandLineArgs(cls, parser, args):
+    ct_benchmarks_util.ValidateCommandLineArgs(parser, args)
+
+  def GetExtraOutDirectories(self):
+    # The indexed filter list does not end up in a build directory on cluster
+    # telemetry; so we add its location here.
+    return ['/b/s/w/ir/out/telemetry_isolates']
+
+  def CreateCoreTimelineBasedMeasurementOptions(self):
+    category_filter = chrome_trace_category_filter.CreateLowOverheadFilter()
+    tbm_options = timeline_based_measurement.Options(category_filter)
+    uma_histograms = [
+        'Ads.ResourceUsage.Size.Network.Mainframe.AdResource',
+        'Ads.ResourceUsage.Size.Network.Mainframe.VanillaResource',
+        'Ads.ResourceUsage.Size.Network.Subframe.AdResource',
+        'Ads.ResourceUsage.Size.Network.Subframe.VanillaResource',
+        'PageLoad.Clients.Ads.Cpu.AdFrames.Aggregate.TotalUsage',
+        'PageLoad.Clients.Ads.Cpu.FullPage.TotalUsage',
+        'PageLoad.Clients.Ads.Resources.Bytes.Ads2',
+        'PageLoad.Experimental.Bytes.NetworkIncludingHeaders',
+    ]
+    for histogram in uma_histograms:
+      tbm_options.config.chrome_trace_config.EnableUMAHistograms(histogram)
+
+    tbm_options.SetTimelineBasedMetrics(['umaMetric', 'cpuTimeMetric'])
+    return tbm_options
+
+  def CreateStorySet(self, options):
+    def NavigateToPageAndLeavePage(self, action_runner):
+      url = self.file_path_url_with_scheme if self.is_file else self.url
+      action_runner.Navigate(url,
+                             self.script_to_evaluate_on_commit,
+                             timeout_in_seconds=_NAVIGATION_TIMEOUT)
+      try:
+        py_utils.WaitFor(action_runner.tab.HasReachedQuiescence,
+                         timeout=_QUIESCENCE_TIMEOUT)
+      except py_utils.TimeoutException:
+        pass
+
+      # Navigate away to an untracked page to trigger recording of page load
+      # metrics
+      action_runner.Navigate('about:blank',
+                             self.script_to_evaluate_on_commit,
+                             timeout_in_seconds=_NAVIGATION_TIMEOUT)
+
+    return page_set.CTPageSet(
+        options.urls_list, options.user_agent, options.archive_data_file,
+        run_navigate_steps_callback=NavigateToPageAndLeavePage,
+        cache_temperature=cache_temperature.COLD)
+
+  @classmethod
+  def Name(cls):
+    return 'ad_tagging.cluster_telemetry'
diff --git a/tools/perf/core/perf_benchmark.py b/tools/perf/core/perf_benchmark.py
index 76cafe9..52cba20 100644
--- a/tools/perf/core/perf_benchmark.py
+++ b/tools/perf/core/perf_benchmark.py
@@ -1,6 +1,8 @@
 # Copyright 2015 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 itertools
 import json
 import os
 import sys
@@ -119,6 +121,12 @@
 
     self.SetExtraBrowserOptions(browser_options)
 
+  def GetExtraOutDirectories(self):
+    # Subclasses of PerfBenchmark should override this method instead of
+    # _GetPossibleBuildDirectories to consider more directories in
+    # _GetOutDirectoryEstimate.
+    return []
+
   @staticmethod
   def FixupTargetOS(target_os):
     if target_os == 'darwin':
@@ -169,8 +177,12 @@
     if finder_options.chromium_output_dir is not None:
       return finder_options.chromium_output_dir
 
-    possible_directories = self._GetPossibleBuildDirectories(
-        finder_options.chrome_root, finder_options.browser_options.browser_type)
+    possible_directories = itertools.chain(
+        self._GetPossibleBuildDirectories(
+          finder_options.chrome_root,
+          finder_options.browser_options.browser_type),
+        self.GetExtraOutDirectories())
+
     return next((p for p in possible_directories if os.path.exists(p)), None)
 
   @staticmethod
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py
index 25200ed..4806250 100644
--- a/tools/perf/core/results_processor/processor.py
+++ b/tools/perf/core/results_processor/processor.py
@@ -287,7 +287,9 @@
     # specify which artifacts deserve uploading.
     if name in [DIAGNOSTICS_NAME, MEASUREMENTS_NAME]:
       continue
-    remote_name = '/'.join([run_identifier, test_result['testPath'], name])
+    retry_identifier = 'retry_%s' % test_result.get('resultId', '0')
+    remote_name = '/'.join(
+        [run_identifier, test_result['testPath'], retry_identifier, name])
     urlsafe_remote_name = re.sub(r'[^A-Za-z0-9/.-]+', '_', remote_name)
     cloud_filepath = cloud_storage.Upload(
         upload_bucket, urlsafe_remote_name, artifact['filePath'])
diff --git a/tools/perf/core/results_processor/processor_unittest.py b/tools/perf/core/results_processor/processor_unittest.py
index 3e4021b9..49b3604 100644
--- a/tools/perf/core/results_processor/processor_unittest.py
+++ b/tools/perf/core/results_processor/processor_unittest.py
@@ -72,9 +72,10 @@
           'bucket', 'path')
       processor.UploadArtifacts(test_result, 'bucket', 'run1')
       cloud_patch.assert_has_calls([
-          mock.call('bucket', 'run1/benchmark/story/logs', '/log.log'),
-          mock.call('bucket', 'run1/benchmark/story/trace.html', '/trace.html'),
-          mock.call('bucket', 'run1/benchmark/story/screenshot',
+          mock.call('bucket', 'run1/benchmark/story/retry_0/logs', '/log.log'),
+          mock.call('bucket', 'run1/benchmark/story/retry_0/trace.html',
+                    '/trace.html'),
+          mock.call('bucket', 'run1/benchmark/story/retry_0/screenshot',
                     '/screenshot.png'),
         ],
         any_order=True,
diff --git a/tools/perf/page_sets/data/system_health_mobile.json b/tools/perf/page_sets/data/system_health_mobile.json
index 3afa9416..2250e97 100644
--- a/tools/perf/page_sets/data/system_health_mobile.json
+++ b/tools/perf/page_sets/data/system_health_mobile.json
@@ -3,6 +3,9 @@
         "background:media:imgur": {
             "DEFAULT": "system_health_mobile_047.wprgo"
         },
+        "background:media:imgur:2019": {
+            "DEFAULT": "system_health_mobile_1e1539cbc7.wprgo"
+        },
         "background:news:nytimes": {
             "DEFAULT": "system_health_mobile_052.wprgo"
         },
@@ -12,6 +15,9 @@
         "background:social:facebook": {
             "DEFAULT": "system_health_mobile_045.wprgo"
         },
+        "background:social:facebook:2019": {
+            "DEFAULT": "system_health_mobile_6a3429e9e4.wprgo"
+        },
         "background:tools:gmail": {
             "DEFAULT": "system_health_mobile_043.wprgo"
         },
@@ -21,6 +27,9 @@
         "browse:chrome:omnibox": {
             "DEFAULT": "system_health_mobile_056.wprgo"
         },
+        "browse:chrome:omnibox:2019": {
+            "DEFAULT": "system_health_mobile_8de13d6bda.wprgo"
+        },
         "browse:media:facebook_photos": {
             "DEFAULT": "system_health_mobile_040.wprgo"
         },
@@ -261,6 +270,9 @@
         "load:search:amazon": {
             "DEFAULT": "system_health_mobile_000.wprgo"
         },
+        "load:search:amazon:2019": {
+            "DEFAULT": "system_health_mobile_c1802fd8f4.wprgo"
+        },
         "load:search:baidu": {
             "DEFAULT": "system_health_mobile_000.wprgo"
         },
@@ -282,6 +294,9 @@
         "load:search:taobao": {
             "DEFAULT": "system_health_mobile_000.wprgo"
         },
+        "load:search:taobao:2019": {
+            "DEFAULT": "system_health_mobile_193439b464.wprgo"
+        },
         "load:search:yahoo": {
             "DEFAULT": "system_health_mobile_000.wprgo"
         },
diff --git a/tools/perf/page_sets/data/system_health_mobile_193439b464.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_193439b464.wprgo.sha1
new file mode 100644
index 0000000..dcd23f5e
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_193439b464.wprgo.sha1
@@ -0,0 +1 @@
+193439b46469c141d841b2734c58f7e554ca296d
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_1e1539cbc7.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_1e1539cbc7.wprgo.sha1
new file mode 100644
index 0000000..b6df5a3f
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_1e1539cbc7.wprgo.sha1
@@ -0,0 +1 @@
+1e1539cbc79d433742d3af4c1309fd84711fe809
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_6a3429e9e4.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_6a3429e9e4.wprgo.sha1
new file mode 100644
index 0000000..6fb8239b
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_6a3429e9e4.wprgo.sha1
@@ -0,0 +1 @@
+6a3429e9e4a5dd28df5e066df178b46b20d1a5a2
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_8de13d6bda.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_8de13d6bda.wprgo.sha1
new file mode 100644
index 0000000..ac2b1e38
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_8de13d6bda.wprgo.sha1
@@ -0,0 +1 @@
+8de13d6bda9b81051ba42be7f4330cb1badb5aa8
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_c1802fd8f4.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_c1802fd8f4.wprgo.sha1
new file mode 100644
index 0000000..7905c20
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_mobile_c1802fd8f4.wprgo.sha1
@@ -0,0 +1 @@
+c1802fd8f41023c1f042bb0eac91654c5f377be9
\ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/background_stories.py b/tools/perf/page_sets/system_health/background_stories.py
index 64bd7cb2..c8b5a3a 100644
--- a/tools/perf/page_sets/system_health/background_stories.py
+++ b/tools/perf/page_sets/system_health/background_stories.py
@@ -45,6 +45,11 @@
   SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
   TAGS = [story_tags.YEAR_2016]
 
+class BackgroundFacebookMobileStory2019(_BackgroundStory):
+  NAME = 'background:social:facebook:2019'
+  URL = 'https://www.facebook.com/rihanna'
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+  TAGS = [story_tags.YEAR_2019]
 
 class BackgroundNytimesMobileStory(_BackgroundStory):
   NAME = 'background:news:nytimes'
@@ -84,6 +89,13 @@
   TAGS = [story_tags.HEALTH_CHECK, story_tags.YEAR_2016]
 
 
+class BackgroundImgurMobileStory2019(_BackgroundStory):
+  NAME = 'background:media:imgur:2019'
+  URL = 'http://imgur.com/gallery/hUita'
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+  TAGS = [story_tags.HEALTH_CHECK, story_tags.YEAR_2019]
+
+
 class BackgroundGmailMobileStory(LoadGmailMobileStory):
   NAME = 'background:tools:gmail'
   SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
diff --git a/tools/perf/page_sets/system_health/chrome_stories.py b/tools/perf/page_sets/system_health/chrome_stories.py
index 3e3b8c6..3f453f6e 100644
--- a/tools/perf/page_sets/system_health/chrome_stories.py
+++ b/tools/perf/page_sets/system_health/chrome_stories.py
@@ -56,6 +56,34 @@
     action_runner.WaitForNavigate()
     action_runner.ScrollPage(use_touch=True, distance=500)
 
+class SearchOmniboxStory2019(system_health_story.SystemHealthStory):
+  """Story that peforms search by using omnibox search provider
+
+  Loads a website and enters a search query on omnibox and navigates to default
+  search provider (google).
+  """
+  NAME = 'browse:chrome:omnibox:2019'
+  URL = 'https://www.google.co.in'
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+  TAGS = [story_tags.EMERGING_MARKET, story_tags.YEAR_2019]
+  # WebView has no omnibox, so not supported.
+  WEBVIEW_NOT_SUPPORTED = True
+
+  def _DidLoadDocument(self, action_runner):
+    app_ui = action_runner.tab.browser.GetAppUi()
+    platform = action_runner.tab.browser.platform
+    app_ui.WaitForUiNode(resource_id='url_bar')
+    url_bar = app_ui.GetUiNode(resource_id='url_bar')
+    url_bar.Tap()
+    action_runner.Wait(1) # user wait before typing
+    platform.android_action_runner.InputText('drake')
+    action_runner.Wait(0.5) # user wait after typing
+    platform.android_action_runner.InputKeyEvent(keyevent.KEYCODE_ENTER)
+
+    action_runner.WaitForNavigate()
+    action_runner.ScrollPage(use_touch=True, distance=500)
+
+
 
 class MobileNewTabPageStory(system_health_story.SystemHealthStory):
   """Story that loads new tab page and performs searches.
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py
index 6b5b4452..e33046b5 100644
--- a/tools/perf/page_sets/system_health/loading_stories.py
+++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -54,6 +54,13 @@
   SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
 
 
+class LoadAmazonMobileStory2019(_LoadingStory):
+  NAME = 'load:search:amazon:2019'
+  URL = 'https://www.amazon.com/s/?field-keywords=pixel'
+  TAGS = [story_tags.YEAR_2019]
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+
+
 class LoadTaobaoDesktopStory2018(_LoadingStory):
   NAME = 'load:search:taobao:2018'
   URL = 'https://world.taobao.com/'
@@ -77,6 +84,14 @@
           story_tags.YEAR_2016]
 
 
+class LoadTaobaoMobileStory2019(_LoadingStory):
+  NAME = 'load:search:taobao:2019'
+  URL = 'http://m.intl.taobao.com/'
+  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
+  TAGS = [story_tags.INTERNATIONAL, story_tags.HEALTH_CHECK,
+          story_tags.YEAR_2019]
+
+
 class LoadYandexStory2018(_LoadingStory):
   NAME = 'load:search:yandex:2018'
   URL = 'https://yandex.ru/touchsearch?text=science'
diff --git a/tools/perf/system_health_stories.csv b/tools/perf/system_health_stories.csv
index a8e9ec8..efdb8b16 100644
--- a/tools/perf/system_health_stories.csv
+++ b/tools/perf/system_health_stories.csv
@@ -2,12 +2,15 @@
 See //tools/perf/core/perf_data_generator.py to make changes
 Story,Description,Platforms,Tags
 background:media:imgur,,mobile,"2016,health_check"
+background:media:imgur:2019,,mobile,"2019,health_check"
 background:news:nytimes,,mobile,"2016,javascript_heavy"
 background:search:google,,mobile,"2016,health_check"
 background:social:facebook,,mobile,2016
+background:social:facebook:2019,,mobile,2019
 background:tools:gmail,,mobile,"2016,health_check"
 browse:chrome:newtab,Story that loads new tab page and performs searches.,mobile,"2016,emerging_market"
 browse:chrome:omnibox,Story that peforms search by using omnibox search provider,mobile,"2016,emerging_market"
+browse:chrome:omnibox:2019,Story that peforms search by using omnibox search provider,mobile,"2019,emerging_market"
 browse:media:facebook_photos,Load a photo page from Rihanna's facebook page then navigate a few next,mobile,"2016,emerging_market"
 browse:media:flickr_infinite_scroll,,"desktop,mobile","2016,infinite_scroll"
 browse:media:googleplaystore:2018,"Navigate to the movies page of Google Play Store, scroll to the bottom,",desktop,"2018,images"
@@ -98,12 +101,14 @@
 load:news:washingtonpost:2019,,mobile,"2019,health_check"
 load:news:wikipedia:2018,,"desktop,mobile","2018,emerging_market"
 load:search:amazon:2018,,desktop,2018
+load:search:amazon:2019,,mobile,2019
 load:search:baidu:2018,,"desktop,mobile","2018,health_check,international"
 load:search:ebay:2018,,"desktop,mobile","2018,health_check"
 load:search:flipkart:2018,,desktop,"2018,international"
 load:search:google:2018,,"desktop,mobile",2018
 load:search:taobao,,mobile,"2016,health_check,international"
 load:search:taobao:2018,,desktop,"2018,international"
+load:search:taobao:2019,,mobile,"2019,health_check,international"
 load:search:yahoo:2018,,"desktop,mobile",2018
 load:search:yandex:2018,,"desktop,mobile","2018,international"
 load:social:instagram:2018,,desktop,2018
diff --git a/tools/perf/validate_wpr_archives b/tools/perf/validate_wpr_archives
index 2415424..8d57372 100755
--- a/tools/perf/validate_wpr_archives
+++ b/tools/perf/validate_wpr_archives
@@ -36,7 +36,9 @@
       'cros_tab_switching.typical_24',
       'multipage_skpicture_printer',
       'leak_detection.cluster_telemetry',
-      'generic_trace_ct']
+      'generic_trace_ct',
+      'ad_tagging.cluster_telemetry',
+  ]
 
   for benchmark in benchmark_finders.GetAllBenchmarks():
     if benchmark.Name() in benchmarks_to_skip:
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 0d0f40ad..14eea120 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -238,7 +238,7 @@
  <item id="safe_browsing_cache_collector" hash_code="115907811" type="0" content_hash_code="36392362" os_list="linux,windows" file_path="components/safe_browsing/browser/threat_details_cache.cc"/>
  <item id="safe_browsing_certificate_error_reporting" hash_code="66590631" type="0" content_hash_code="50197576" os_list="linux,windows" file_path="chrome/browser/ssl/certificate_error_reporter.cc"/>
  <item id="safe_browsing_chunk_backup_request" hash_code="79957943" type="0" deprecated="2018-08-14" content_hash_code="133850277" file_path=""/>
- <item id="safe_browsing_client_side_malware_detector" hash_code="102935425" type="0" content_hash_code="79591279" os_list="linux,windows" file_path="chrome/browser/safe_browsing/client_side_detection_service.cc"/>
+ <item id="safe_browsing_client_side_malware_detector" hash_code="102935425" type="0" deprecated="2019-12-07" content_hash_code="79591279" file_path=""/>
  <item id="safe_browsing_client_side_phishing_detector" hash_code="1313982" type="0" content_hash_code="50199143" os_list="linux,windows" file_path="chrome/browser/safe_browsing/client_side_detection_service.cc"/>
  <item id="safe_browsing_extended_reporting" hash_code="42848942" type="0" content_hash_code="50089173" os_list="linux,windows" file_path="components/safe_browsing/ping_manager.cc"/>
  <item id="safe_browsing_feedback" hash_code="44583821" type="0" content_hash_code="114076664" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/download_feedback.cc"/>
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc
index 1acb610..69fa4d7 100644
--- a/ui/accessibility/ax_enum_util.cc
+++ b/ui/accessibility/ax_enum_util.cc
@@ -1835,6 +1835,8 @@
       return "isLineBreakingObject";
     case ax::mojom::BoolAttribute::kIsPageBreakingObject:
       return "isPageBreakingObject";
+    case ax::mojom::BoolAttribute::kHasAriaAttribute:
+      return "hasAriaAttribute";
   }
 
   return "";
@@ -1875,6 +1877,8 @@
     return ax::mojom::BoolAttribute::kIsLineBreakingObject;
   if (0 == strcmp(bool_attribute, "isPageBreakingObject"))
     return ax::mojom::BoolAttribute::kIsPageBreakingObject;
+  if (0 == strcmp(bool_attribute, "hasAriaAttribute"))
+    return ax::mojom::BoolAttribute::kHasAriaAttribute;
   return ax::mojom::BoolAttribute::kNone;
 }
 
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom
index 0ba3a708..6defc0d 100644
--- a/ui/accessibility/ax_enums.mojom
+++ b/ui/accessibility/ax_enums.mojom
@@ -730,6 +730,9 @@
 
   // Indicates whether this node causes a page break
   kIsPageBreakingObject,
+
+  // True if the node has any ARIA attributes set.
+  kHasAriaAttribute,
 };
 
 enum IntListAttribute {
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
index e4ad10f..a3e4fd17 100644
--- a/ui/accessibility/ax_node_data.cc
+++ b/ui/accessibility/ax_node_data.cc
@@ -1499,6 +1499,9 @@
       case ax::mojom::BoolAttribute::kIsPageBreakingObject:
         result += " is_page_breaking_object=" + value;
         break;
+      case ax::mojom::BoolAttribute::kHasAriaAttribute:
+        result += " has_aria_attribute=" + value;
+        break;
       case ax::mojom::BoolAttribute::kNone:
         break;
     }
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index c7e87186..9ac6b3e 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -6593,12 +6593,12 @@
       // text to be effectively repeated.
       auto* parent = FromNativeViewAccessible(GetDelegate()->GetParent());
       while (parent) {
-        const ui::AXNodeData& data = parent->GetData();
+        const AXNodeData& data = parent->GetData();
+        if (IsCellOrTableHeader(data.role))
+          return false;
         switch (data.role) {
           case ax::mojom::Role::kButton:
-          case ax::mojom::Role::kCell:
           case ax::mojom::Role::kCheckBox:
-          case ax::mojom::Role::kColumnHeader:
           case ax::mojom::Role::kGroup:
           case ax::mojom::Role::kHeading:
           case ax::mojom::Role::kLineBreak:
@@ -6612,7 +6612,6 @@
           case ax::mojom::Role::kRadioButton:
           case ax::mojom::Role::kRow:
           case ax::mojom::Role::kRowGroup:
-          case ax::mojom::Role::kRowHeader:
           case ax::mojom::Role::kStaticText:
           case ax::mojom::Role::kSwitch:
           case ax::mojom::Role::kTab:
@@ -6625,6 +6624,57 @@
         parent = FromNativeViewAccessible(parent->GetParent());
       }
     }
+    const AXNodeData& data = GetData();
+    // https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-treeoverview#control-view
+    // The control view also includes noninteractive UI items that contribute
+    // to the logical structure of the UI.
+    if (IsControl(data.role) || ComputeUIALandmarkType() ||
+        IsTableLike(data.role) || IsList(data.role)) {
+      return true;
+    }
+    if (IsImage(data.role)) {
+      // If the author provides an explicitly empty alt text attribute then
+      // the image is decorational and should not be considered as a control.
+      if (data.role == ax::mojom::Role::kImage &&
+          data.GetNameFrom() ==
+              ax::mojom::NameFrom::kAttributeExplicitlyEmpty) {
+        return false;
+      }
+      return true;
+    }
+    switch (data.role) {
+      case ax::mojom::Role::kArticle:
+      case ax::mojom::Role::kBlockquote:
+      case ax::mojom::Role::kDetails:
+      case ax::mojom::Role::kFigure:
+      case ax::mojom::Role::kFooter:
+      case ax::mojom::Role::kFooterAsNonLandmark:
+      case ax::mojom::Role::kHeader:
+      case ax::mojom::Role::kHeaderAsNonLandmark:
+      case ax::mojom::Role::kLabelText:
+      case ax::mojom::Role::kListBoxOption:
+      case ax::mojom::Role::kListItem:
+      case ax::mojom::Role::kMeter:
+      case ax::mojom::Role::kProgressIndicator:
+      case ax::mojom::Role::kSection:
+      case ax::mojom::Role::kSplitter:
+      case ax::mojom::Role::kTime:
+        return true;
+      default:
+        break;
+    }
+    // Classify generic containers that are not clickable or focusable and have
+    // no name, description, landmark type, and is not the root of editable
+    // content as not controls.
+    // Doing so helps Narrator find all the content of live regions.
+    if (!data.GetBoolAttribute(ax::mojom::BoolAttribute::kHasAriaAttribute) &&
+        !data.GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot) &&
+        data.GetStringAttribute(ax::mojom::StringAttribute::kName).empty() &&
+        data.GetStringAttribute(ax::mojom::StringAttribute::kDescription)
+            .empty() &&
+        !data.HasState(ax::mojom::State::kFocusable) && !data.IsClickable()) {
+      return false;
+    }
     return true;
   }
   // non web-content case
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index 31ebeaa..872aa76 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -227,6 +227,7 @@
   ax_fragment_root_.reset(nullptr);
   tree_.reset(nullptr);
   AXNodePosition::SetTree(nullptr);
+  TestAXNodeWrapper::SetGlobalIsWebContent(false);
   ASSERT_EQ(0U, AXPlatformNodeBase::GetInstanceCountForTesting());
 }
 
@@ -283,6 +284,14 @@
       GetRootNode()->children()[size_t{child_index}]);
 }
 
+Microsoft::WRL::ComPtr<IRawElementProviderSimple>
+AXPlatformNodeWinTest::GetIRawElementProviderSimpleFromTree(
+    const ui::AXTreeID tree_id,
+    const int32_t node_id) {
+  return QueryInterfaceFromNode<IRawElementProviderSimple>(
+      GetNodeFromTree(tree_id, node_id));
+}
+
 ComPtr<IRawElementProviderFragment>
 AXPlatformNodeWinTest::GetRootIRawElementProviderFragment() {
   return QueryInterfaceFromNode<IRawElementProviderFragment>(GetRootNode());
@@ -4221,6 +4230,94 @@
                      UIA_LocalizedControlTypePropertyId, L"search box");
 }
 
+TEST_F(AXPlatformNodeWinTest, TestGetPropertyValue_IsControlElement) {
+  AXTreeUpdate update;
+  ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
+  update.tree_data.tree_id = tree_id;
+  update.has_tree_data = true;
+  update.root_id = 1;
+  update.nodes.resize(16);
+  update.nodes[0].id = 1;
+  update.nodes[0].role = ax::mojom::Role::kRootWebArea;
+  update.nodes[0].child_ids = {2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  update.nodes[1].id = 2;
+  update.nodes[1].role = ax::mojom::Role::kButton;
+  update.nodes[1].child_ids = {3};
+  update.nodes[2].id = 3;
+  update.nodes[2].role = ax::mojom::Role::kStaticText;
+  update.nodes[2].SetName("some text");
+  update.nodes[3].id = 4;
+  update.nodes[3].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[3].child_ids = {5};
+  update.nodes[4].id = 5;
+  update.nodes[4].role = ax::mojom::Role::kStaticText;
+  update.nodes[4].SetName("more text");
+  update.nodes[5].id = 6;
+  update.nodes[5].role = ax::mojom::Role::kTable;
+  update.nodes[6].id = 7;
+  update.nodes[6].role = ax::mojom::Role::kList;
+  update.nodes[7].id = 8;
+  update.nodes[7].role = ax::mojom::Role::kForm;
+  update.nodes[8].id = 9;
+  update.nodes[8].role = ax::mojom::Role::kImage;
+  update.nodes[9].id = 10;
+  update.nodes[9].role = ax::mojom::Role::kImage;
+  update.nodes[9].SetNameExplicitlyEmpty();
+  update.nodes[10].id = 11;
+  update.nodes[10].role = ax::mojom::Role::kArticle;
+  update.nodes[11].id = 12;
+  update.nodes[11].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[11].AddBoolAttribute(ax::mojom::BoolAttribute::kHasAriaAttribute,
+                                    true);
+  update.nodes[12].id = 13;
+  update.nodes[12].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[12].AddBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot,
+                                    true);
+  update.nodes[13].id = 14;
+  update.nodes[13].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[13].SetName("name");
+  update.nodes[14].id = 15;
+  update.nodes[14].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[14].SetDescription("description");
+  update.nodes[15].id = 16;
+  update.nodes[15].role = ax::mojom::Role::kGenericContainer;
+  update.nodes[15].AddState(ax::mojom::State::kFocusable);
+
+  Init(update);
+  TestAXNodeWrapper::SetGlobalIsWebContent(true);
+
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 2),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 3),
+                     UIA_IsControlElementPropertyId, false);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 4),
+                     UIA_IsControlElementPropertyId, false);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 5),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 6),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 7),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 8),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 9),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 10),
+                     UIA_IsControlElementPropertyId, false);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 11),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 12),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 13),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 14),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 15),
+                     UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(GetIRawElementProviderSimpleFromTree(tree_id, 16),
+                     UIA_IsControlElementPropertyId, true);
+}
+
 TEST_F(AXPlatformNodeWinTest, TestUIAGetProviderOptions) {
   AXNodeData root_data;
   Init(root_data);
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.h b/ui/accessibility/platform/ax_platform_node_win_unittest.h
index 136bd095..fced930 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.h
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.h
@@ -64,6 +64,9 @@
   GetRootIRawElementProviderSimple();
   Microsoft::WRL::ComPtr<IRawElementProviderSimple>
   GetIRawElementProviderSimpleFromChildIndex(int child_index);
+  Microsoft::WRL::ComPtr<IRawElementProviderSimple>
+  GetIRawElementProviderSimpleFromTree(const ui::AXTreeID tree_id,
+                                       const int32_t node_id);
   Microsoft::WRL::ComPtr<IRawElementProviderFragment>
   GetRootIRawElementProviderFragment();
   Microsoft::WRL::ComPtr<IRawElementProviderFragment>
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index 2e5cac7..70dc3d1 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -43,6 +43,9 @@
 // default action was called from.
 AXNode* g_node_from_last_default_action;
 
+// A global indicating that AXPlatformNodeDelegate objects are web content.
+bool g_is_web_content = false;
+
 // A simple implementation of AXTreeObserver to catch when AXNodes are
 // deleted so we can delete their wrappers.
 class TestAXTreeObserver : public AXTreeObserver {
@@ -97,6 +100,10 @@
   return std::make_unique<base::AutoReset<float>>(&g_scale_factor, value);
 }
 
+void TestAXNodeWrapper::SetGlobalIsWebContent(bool is_web_content) {
+  g_is_web_content = is_web_content;
+}
+
 TestAXNodeWrapper::~TestAXNodeWrapper() {
   platform_node_->Destroy();
 }
@@ -274,6 +281,10 @@
   return minimized_;
 }
 
+bool TestAXNodeWrapper::IsWebContent() const {
+  return g_is_web_content;
+}
+
 // Walk the AXTree and ensure that all wrappers are created
 void TestAXNodeWrapper::BuildAllWrappers(AXTree* tree, AXNode* node) {
   for (auto* child : node->children()) {
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h
index 0066534..30eddca 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -44,6 +44,9 @@
   // Set a global scale factor for testing.
   static std::unique_ptr<base::AutoReset<float>> SetScaleFactor(float value);
 
+  // Set a global indicating that AXPlatformNodeDelegates are for web content.
+  static void SetGlobalIsWebContent(bool is_web_content);
+
   ~TestAXNodeWrapper() override;
 
   AXPlatformNode* ax_platform_node() const { return platform_node_; }
@@ -81,6 +84,7 @@
   gfx::NativeViewAccessible HitTestSync(int x, int y) override;
   gfx::NativeViewAccessible GetFocus() override;
   bool IsMinimized() const override;
+  bool IsWebContent() const override;
   AXPlatformNode* GetFromNodeID(int32_t id) override;
   AXPlatformNode* GetFromTreeIDAndNodeID(const ui::AXTreeID& ax_tree_id,
                                          int32_t id) override;
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index d34e615..6a47021 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -362,6 +362,8 @@
     "javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java",
     "javatests/src/org/chromium/ui/test/util/DummyUiActivity.java",
     "javatests/src/org/chromium/ui/test/util/DummyUiActivityTestCase.java",
+    "javatests/src/org/chromium/ui/test/util/NightModeTestUtils.java",
+    "javatests/src/org/chromium/ui/test/util/RenderTestRule.java",
     "javatests/src/org/chromium/ui/test/util/UiDisableIf.java",
     "javatests/src/org/chromium/ui/test/util/UiDisableIfSkipCheck.java",
     "javatests/src/org/chromium/ui/test/util/UiRestriction.java",
diff --git a/ui/android/java/res/values/semantic_colors.xml b/ui/android/java/res/values/semantic_colors.xml
index 7602067..db1cc3d 100644
--- a/ui/android/java/res/values/semantic_colors.xml
+++ b/ui/android/java/res/values/semantic_colors.xml
@@ -49,4 +49,7 @@
     </color>
     <color name="divider_bg_color_dark">@color/modern_grey_300</color>
     <color name="divider_bg_color_light">@color/white_alpha_12</color>
-</resources>
\ No newline at end of file
+
+    <!-- Illustration only -->
+    <color name="ntp_incognito_icon_color" tools:ignore="UnusedResources">@color/modern_grey_300</color>
+</resources>
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/NightModeTestUtils.java b/ui/android/javatests/src/org/chromium/ui/test/util/NightModeTestUtils.java
new file mode 100644
index 0000000..d5683de
--- /dev/null
+++ b/ui/android/javatests/src/org/chromium/ui/test/util/NightModeTestUtils.java
@@ -0,0 +1,48 @@
+// 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.
+
+package org.chromium.ui.test.util;
+
+import android.support.v7.app.AppCompatDelegate;
+
+import org.chromium.base.test.params.ParameterProvider;
+import org.chromium.base.test.params.ParameterSet;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Helper methods to be used in tests to specify night mode state.
+ */
+public class NightModeTestUtils {
+    /**
+     * {@link ParameterProvider} used for parameterized test that provides the night mode state.
+     */
+    public static class NightModeParams implements ParameterProvider {
+        private static List<ParameterSet> sNightModeParams =
+                Arrays.asList(new ParameterSet().value(false).name("NightModeDisabled"),
+                        new ParameterSet().value(true).name("NightModeEnabled"));
+
+        @Override
+        public List<ParameterSet> getParameters() {
+            return sNightModeParams;
+        }
+    }
+
+    /**
+     * Sets up the night mode state for {@link DummyUiActivity}.
+     * @param nightModeEnabled Whether night mode should be enabled.
+     */
+    public static void setUpNightModeForDummyUiActivity(boolean nightModeEnabled) {
+        AppCompatDelegate.setDefaultNightMode(nightModeEnabled ? AppCompatDelegate.MODE_NIGHT_YES
+                                                               : AppCompatDelegate.MODE_NIGHT_NO);
+    }
+
+    /**
+     * Resets the night mode state for {@link DummyUiActivity}.
+     */
+    public static void tearDownNightModeForDummyUiActivity() {
+        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
+    }
+}
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/OWNERS b/ui/android/javatests/src/org/chromium/ui/test/util/OWNERS
index 43ab5bd..942bdcb 100644
--- a/ui/android/javatests/src/org/chromium/ui/test/util/OWNERS
+++ b/ui/android/javatests/src/org/chromium/ui/test/util/OWNERS
@@ -1,2 +1,4 @@
 per-file DisableAnimationsTestRule.java=yliuyliu@google.com
 per-file *DummyUiActivity*.java=yliuyliu@google.com
+per-file RenderTestRule.java=peconn@chromium.org
+per-file RENDER_TESTS.md=peconn@chromium.org
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RENDER_TESTS.md b/ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md
similarity index 92%
rename from chrome/test/android/javatests/src/org/chromium/chrome/test/util/RENDER_TESTS.md
rename to ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md
index 5add6c6a..684601e 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RENDER_TESTS.md
+++ b/ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md
@@ -62,7 +62,8 @@
 ### Writing the test
 
 To write a new test, start with the example in the javadoc for
-[RenderTestRule](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java).
+[RenderTestRule](https://cs.chromium.org/chromium/src/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java)
+or [ChromeRenderTestRule](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeRenderTestRule.java).
 
 ### Running the tests locally
 
@@ -123,7 +124,7 @@
 
 Certain features lead to flaky tests, for example any sort of animation we don't
 take into account while writing the tests. To help deal with this, you can use
-`RenderTestRule.sanitize` to modify the View hierarchy and remove some of the
+`ChromeRenderTestRule.sanitize` to modify the View hierarchy and remove some of the
 more troublesome attributes (for example, it disables the blinking cursor in
 `EditText`s).
 
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java b/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java
similarity index 89%
rename from chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java
rename to ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java
index 9b1c7fa..3be034b 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java
+++ b/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.test.util;
+package org.chromium.ui.test.util;
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -11,8 +11,6 @@
 import android.text.TextUtils;
 import android.util.Pair;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
 
 import org.junit.Assert;
 import org.junit.rules.TestWatcher;
@@ -23,7 +21,6 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.UiUtils;
 
 import java.io.File;
@@ -41,13 +38,12 @@
  * <pre>
  * {@code
  *
- * @RunWith(ChromeJUnit4ClassRunner.class)
- * @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
- * public class MyTest {
+ * @RunWith(BaseJUnit4ClassRunner.class)
+ * public class MyTest extends DummyUiActivityTestCase {
  *     // Provide RenderTestRule with the path from src/ to the golden directory.
  *     @Rule
  *     public RenderTestRule mRenderTestRule =
- *             new RenderTestRule("chrome/test/data/android/render_tests");
+ *             new RenderTestRule("components/myfeature/test/data/android/render_tests");
  *
  *     @Test
  *     // The test must have the feature "RenderTest" for the bots to display renders.
@@ -109,13 +105,6 @@
         }
     }
 
-    /**
-     * Constructor using {@code "chrome/test/data/android/render_tests"} as default golden folder.
-     */
-    public RenderTestRule() {
-        this("chrome/test/data/android/render_tests");
-    }
-
     public RenderTestRule(String goldenFolder) {
         // |goldenFolder| is relative to the src directory in the repository. |mGoldenFolder| will
         // be the folder on the test device.
@@ -148,20 +137,19 @@
     public void render(final View view, String id) throws IOException {
         Assert.assertTrue("Render Tests must have the RenderTest feature.", mHasRenderTestFeature);
 
-        Bitmap testBitmap =
-                ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Bitmap>() {
-                    @Override
-                    public Bitmap call() {
-                        int height = view.getMeasuredHeight();
-                        int width = view.getMeasuredWidth();
-                        if (height <= 0 || width <= 0) {
-                            throw new IllegalStateException(
-                                    "Invalid view dimensions: " + width + "x" + height);
-                        }
+        Bitmap testBitmap = ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Bitmap>() {
+            @Override
+            public Bitmap call() {
+                int height = view.getMeasuredHeight();
+                int width = view.getMeasuredWidth();
+                if (height <= 0 || width <= 0) {
+                    throw new IllegalStateException(
+                            "Invalid view dimensions: " + width + "x" + height);
+                }
 
-                        return UiUtils.generateScaledScreenshot(view, 0, Bitmap.Config.ARGB_8888);
-                    }
-                });
+                return UiUtils.generateScaledScreenshot(view, 0, Bitmap.Config.ARGB_8888);
+            }
+        });
 
         compareForResult(testBitmap, id);
     }
@@ -209,25 +197,6 @@
         }
     }
 
-    /**
-     * Searches the View hierarchy and modifies the Views to provide better stability in tests. For
-     * example it will disable the blinking cursor in EditTexts.
-     */
-    public static void sanitize(View view) {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            // Add more sanitizations as we discover more flaky attributes.
-            if (view instanceof ViewGroup) {
-                ViewGroup viewGroup = (ViewGroup) view;
-                for (int i = 0; i < viewGroup.getChildCount(); i++) {
-                    sanitize(viewGroup.getChildAt(i));
-                }
-            } else if (view instanceof EditText) {
-                EditText editText = (EditText) view;
-                editText.setCursorVisible(false);
-            }
-        });
-    }
-
     @Override
     protected void finished(Description desc) {
         if (!onRenderTestDevice() && !mGoldenMissingIds.isEmpty()) {
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc
index 920ed3d9..653dbda 100644
--- a/ui/aura/native_window_occlusion_tracker_win.cc
+++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -263,8 +263,7 @@
 void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
     EnableOcclusionTrackingForWindow(HWND hwnd) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  NativeWindowOcclusionState default_state;
-  root_window_hwnds_occlusion_state_[hwnd] = default_state;
+  root_window_hwnds_occlusion_state_[hwnd] = Window::OcclusionState::UNKNOWN;
   if (global_event_hooks_.empty())
     RegisterEventHooks();
 
@@ -355,38 +354,26 @@
       SkIRect::MakeLTRB(screen_left, screen_top,
                         screen_left + GetSystemMetrics(SM_CXVIRTUALSCREEN),
                         screen_top + GetSystemMetrics(SM_CYVIRTUALSCREEN)));
+  num_root_windows_with_unknown_occlusion_state_ = 0;
 
   for (auto& root_window_pair : root_window_hwnds_occlusion_state_) {
-    root_window_pair.second.unoccluded_region.setEmpty();
     HWND hwnd = root_window_pair.first;
 
     // IsIconic() checks for a minimized window. Immediately set the state of
     // minimized windows to HIDDEN.
     if (IsIconic(hwnd)) {
-      root_window_pair.second.occlusion_state = Window::OcclusionState::HIDDEN;
+      root_window_pair.second = Window::OcclusionState::HIDDEN;
     } else if (IsWindowOnCurrentVirtualDesktop(hwnd) == false) {
       // If window is not on the current virtual desktop, immediately
       // set the state of the window to OCCLUDED.
-      root_window_pair.second.occlusion_state =
-          Window::OcclusionState::OCCLUDED;
+      root_window_pair.second = Window::OcclusionState::OCCLUDED;
       // Don't unregister event hooks when not on current desktop. There's no
       // notification when that changes, so we can't reregister event hooks.
       should_unregister_event_hooks = false;
     } else {
-      root_window_pair.second.occlusion_state = Window::OcclusionState::UNKNOWN;
-      RECT window_rect;
-      if (GetWindowRect(hwnd, &window_rect) != 0) {
-        root_window_pair.second.unoccluded_region =
-            SkRegion(SkIRect::MakeLTRB(window_rect.left, window_rect.top,
-                                       window_rect.right, window_rect.bottom));
-        // Clip the unoccluded region by the screen dimensions, to handle the
-        // case of the app window being partly off screen.
-        root_window_pair.second.unoccluded_region.op(screen_region,
-                                                     SkRegion::kIntersect_Op);
-      }
-      // If call to GetWindowRect fails, window will be treated as occluded,
-      // because unoccluded_region will be empty.
+      root_window_pair.second = Window::OcclusionState::UNKNOWN;
       should_unregister_event_hooks = false;
+      num_root_windows_with_unknown_occlusion_state_++;
     }
   }
   // Unregister event hooks if all native windows are minimized.
@@ -394,6 +381,7 @@
     UnregisterEventHooks();
   } else {
     base::flat_set<DWORD> current_pids_with_visible_windows;
+    unoccluded_desktop_region_ = screen_region;
     // Calculate unoccluded region if there is a non-minimized native window.
     // Also compute |current_pids_with_visible_windows| as we enumerate
     // the windows.
@@ -427,25 +415,15 @@
   }
   // Determine new occlusion status and post a task to the browser ui
   // thread to update the window occlusion state on the root windows.
-  base::flat_map<HWND, Window::OcclusionState> window_occlusion_states;
-
   for (auto& root_window_pair : root_window_hwnds_occlusion_state_) {
-    Window::OcclusionState new_state;
-    if (root_window_pair.second.occlusion_state !=
-        Window::OcclusionState::UNKNOWN) {
-      new_state = root_window_pair.second.occlusion_state;
-    } else {
-      new_state = root_window_pair.second.unoccluded_region.isEmpty()
-                      ? Window::OcclusionState::OCCLUDED
-                      : Window::OcclusionState::VISIBLE;
-    }
-    window_occlusion_states[root_window_pair.first] = new_state;
-    root_window_pair.second.occlusion_state = new_state;
+    if (root_window_pair.second == Window::OcclusionState::UNKNOWN)
+      DCHECK(FALSE) << "A root window did not get its occlusion state set";
   }
   ui_thread_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&NativeWindowOcclusionTrackerWin::UpdateOcclusionState,
-                     base::Unretained(g_tracker), window_occlusion_states));
+                     base::Unretained(g_tracker),
+                     root_window_hwnds_occlusion_state_));
 }
 
 void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
@@ -524,46 +502,56 @@
         base::flat_set<DWORD>* current_pids_with_visible_windows) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  SkRegion curr_unoccluded_destkop = unoccluded_desktop_region_;
   gfx::Rect window_rect;
-  // Check if |hwnd| is a root_window; if so, we're done figuring out
-  // if it's occluded because we've seen all the windows "over" it.
-  // TODO(davidbienvenu): Explore checking if occlusion state has been
-  // computed for all |root_window_hwnds_occlusion_state_|, and if so, skipping
-  // further oclcusion calculations. However, we still want to keep computing
-  // |current_pids_with_visible_windows_|, so this function always returns true.
-  auto it = root_window_hwnds_occlusion_state_.find(hwnd);
-  if (it != root_window_hwnds_occlusion_state_.end() &&
-      it->second.occlusion_state != Window::OcclusionState::HIDDEN) {
-    it->second.occlusion_state = it->second.unoccluded_region.isEmpty()
-                                     ? Window::OcclusionState::OCCLUDED
-                                     : Window::OcclusionState::VISIBLE;
+  bool window_is_occluding =
+      WindowCanOccludeOtherWindowsOnCurrentVirtualDesktop(hwnd, &window_rect);
+  if (window_is_occluding) {
+    // Hook this window's process with EVENT_OBJECT_LOCATION_CHANGE, if we are
+    // not already doing so.
+    DWORD pid;
+    GetWindowThreadProcessId(hwnd, &pid);
+    current_pids_with_visible_windows->insert(pid);
+    if (!base::Contains(process_event_hooks_, pid))
+      RegisterEventHookForProcess(pid);
+
+    // If no more root windows to consider, return true so we can continue
+    // looking for windows we haven't hooked.
+    if (num_root_windows_with_unknown_occlusion_state_ == 0)
+      return true;
+
+    SkRegion window_region(SkIRect::MakeLTRB(window_rect.x(), window_rect.y(),
+                                             window_rect.right(),
+                                             window_rect.bottom()));
+    unoccluded_desktop_region_.op(window_region, SkRegion::kDifference_Op);
+  } else if (num_root_windows_with_unknown_occlusion_state_ == 0) {
+    // This window can't occlude other windows, but we've determined the
+    // occlusion state of all root windows, so we can return.
+    return true;
   }
 
-  if (!WindowCanOccludeOtherWindowsOnCurrentVirtualDesktop(hwnd, &window_rect))
+  // Check if |hwnd| is a root window; if so, we're done figuring out
+  // if it's occluded because we've seen all the windows "over" it.
+  auto it = root_window_hwnds_occlusion_state_.find(hwnd);
+  if (it == root_window_hwnds_occlusion_state_.end() ||
+      it->second != Window::OcclusionState::UNKNOWN) {
     return true;
-  // We are interested in this window, but are not currently hooking it with
-  // EVENT_OBJECT_LOCATION_CHANGE, so we need to hook it. We check
-  // this by seeing if its PID is in |process_event_hooks_|.
-  DWORD pid;
-  GetWindowThreadProcessId(hwnd, &pid);
-  current_pids_with_visible_windows->insert(pid);
-  if (!base::Contains(process_event_hooks_, pid))
-    RegisterEventHookForProcess(pid);
+  }
+  // On Win7, default theme makes root windows have complex regions by
+  // default. But we can still check if their bounding rect is occluded.
+  if (!window_is_occluding) {
+    RECT rect;
+    if (::GetWindowRect(hwnd, &rect) != 0) {
+      SkRegion window_region(
+          SkIRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom));
 
-  SkRegion window_region(SkIRect::MakeLTRB(window_rect.x(), window_rect.y(),
-                                           window_rect.right(),
-                                           window_rect.bottom()));
-
-  for (auto& root_window_pair : root_window_hwnds_occlusion_state_) {
-    if (root_window_pair.second.occlusion_state !=
-        Window::OcclusionState::UNKNOWN)
-      continue;
-    if (!root_window_pair.second.unoccluded_region.op(
-            window_region, SkRegion::kDifference_Op)) {
-      root_window_pair.second.occlusion_state =
-          Window::OcclusionState::OCCLUDED;
+      curr_unoccluded_destkop.op(window_region, SkRegion::kDifference_Op);
     }
   }
+  it->second = (unoccluded_desktop_region_ == curr_unoccluded_destkop)
+                   ? Window::OcclusionState::OCCLUDED
+                   : Window::OcclusionState::VISIBLE;
+  num_root_windows_with_unknown_occlusion_state_--;
   return true;
 }
 
diff --git a/ui/aura/native_window_occlusion_tracker_win.h b/ui/aura/native_window_occlusion_tracker_win.h
index 0b433367..7746998 100644
--- a/ui/aura/native_window_occlusion_tracker_win.h
+++ b/ui/aura/native_window_occlusion_tracker_win.h
@@ -78,17 +78,6 @@
     friend class NativeWindowOcclusionTrackerTest;
     friend class test::AuraTestHelper;
 
-    struct NativeWindowOcclusionState {
-      // The region of the native window that is not occluded by other windows.
-      SkRegion unoccluded_region;
-
-      // The current occlusion state of the native window. Default to UNKNOWN
-      // because we do not know the state starting out. More information on
-      // these states can be found in aura::Window.
-      aura::Window::OcclusionState occlusion_state =
-          aura::Window::OcclusionState::UNKNOWN;
-    };
-
     // Registers event hooks, if not registered.
     void MaybeRegisterEventHooks();
 
@@ -184,7 +173,7 @@
 
     // Map of root app window hwnds and their occlusion state. This contains
     // both visible and hidden windows.
-    base::flat_map<HWND, NativeWindowOcclusionState>
+    base::flat_map<HWND, Window::OcclusionState>
         root_window_hwnds_occlusion_state_;
 
     // Values returned by SetWinEventHook are stored so that hooks can be
@@ -207,6 +196,19 @@
     // calculating window occlusion.
     bool window_is_moving_ = false;
 
+    // Used to determine if a root window is occluded. As we iterate through the
+    // hwnds in z-order, we subtract each opaque window's rect from
+    // |unoccluded_desktop_region_|. When we get to a root window, we subtract
+    // it from |unoccluded_desktop_region_|, and if |unoccluded_desktop_region_|
+    // doesn't change, the root window was already occluded.
+    SkRegion unoccluded_desktop_region_;
+
+    // Keeps track of how many root windows we need to compute the occlusion
+    // state of in a call to ComputeNativeWindowOcclusionStatus. Once we've
+    // determined the state of all root windows, we can stop subtracting
+    // windows from |unoccluded_desktop_region_|.
+    int num_root_windows_with_unknown_occlusion_state_;
+
     // Only used on Win10+.
     Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_;
 
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc
index 6be2086..669f086 100644
--- a/ui/base/clipboard/clipboard_win.cc
+++ b/ui/base/clipboard/clipboard_win.cc
@@ -88,14 +88,13 @@
     // shouldn't be contention.
 
     for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) {
-      // If we didn't manage to open the clipboard, sleep a bit and be hopeful.
-      if (attempts != 0)
-        ::Sleep(5);
-
       if (::OpenClipboard(owner)) {
         opened_ = true;
         return true;
       }
+
+      // If we didn't manage to open the clipboard, sleep a bit and be hopeful.
+      ::Sleep(5);
     }
 
     // We failed to acquire the clipboard.
@@ -469,7 +468,7 @@
   // Since Windows uses premultiplied alpha, we scan for instances where
   // (R, G, B) > A. If there are any invalid premultiplied colors in the image,
   // we assume the alpha channel contains garbage and force the bitmap to be
-  // opaque as well. Note that this  heuristic will fail on a transparent bitmap
+  // opaque as well. Note that this heuristic will fail on a transparent bitmap
   // containing only black pixels...
   SkPixmap device_pixels(SkImageInfo::MakeN32Premul(bitmap->bmiHeader.biWidth,
                                                     bitmap->bmiHeader.biHeight),
diff --git a/ui/base/ime/dummy_text_input_client.cc b/ui/base/ime/dummy_text_input_client.cc
index 0cd06f6..eb4c7d4 100644
--- a/ui/base/ime/dummy_text_input_client.cc
+++ b/ui/base/ime/dummy_text_input_client.cc
@@ -153,6 +153,12 @@
 #endif
 
 #if defined(OS_WIN)
+bool DummyTextInputClient::GetEditContextLayoutBounds(
+    gfx::Rect* control_bounds,
+    gfx::Rect* selection_bounds) {
+  return false;
+}
+
 void DummyTextInputClient::SetActiveCompositionForAccessibility(
     const gfx::Range& range,
     const base::string16& active_composition_text,
diff --git a/ui/base/ime/dummy_text_input_client.h b/ui/base/ime/dummy_text_input_client.h
index b4bbc8be..ef78fe7a 100644
--- a/ui/base/ime/dummy_text_input_client.h
+++ b/ui/base/ime/dummy_text_input_client.h
@@ -63,6 +63,8 @@
 #endif
 
 #if defined(OS_WIN)
+  bool GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                  gfx::Rect* selection_bounds) override;
   void SetActiveCompositionForAccessibility(
       const gfx::Range& range,
       const base::string16& active_composition_text,
diff --git a/ui/base/ime/text_input_client.h b/ui/base/ime/text_input_client.h
index ae47101..b5429ce 100644
--- a/ui/base/ime/text_input_client.h
+++ b/ui/base/ime/text_input_client.h
@@ -217,6 +217,10 @@
 #endif
 
 #if defined(OS_WIN)
+  // Returns false if the EditContext bounds are not available, else it returns
+  // true with the control and selection bounds for the active EditContext.
+  virtual bool GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                          gfx::Rect* selection_bounds) = 0;
   // Notifies accessibility about active composition. This API is currently
   // only defined for TSF which is available only on Windows
   // https://docs.microsoft.com/en-us/windows/desktop/api/UIAutomationCore/
diff --git a/ui/base/ime/win/tsf_input_policy_unittest.cc b/ui/base/ime/win/tsf_input_policy_unittest.cc
index 5749448..9987461 100644
--- a/ui/base/ime/win/tsf_input_policy_unittest.cc
+++ b/ui/base/ime/win/tsf_input_policy_unittest.cc
@@ -72,6 +72,8 @@
                bool(const gfx::Range&, const std::vector<ui::ImeTextSpan>&));
   MOCK_METHOD3(SetActiveCompositionForAccessibility,
                void(const gfx::Range&, const base::string16&, bool));
+  MOCK_METHOD2(GetEditContextLayoutBounds,
+               bool(gfx::Rect* control_bounds, gfx::Rect* selection_bounds));
 };
 
 class MockInputMethodDelegate : public internal::InputMethodDelegate {
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc
index 4c8552a..72bd089 100644
--- a/ui/base/ime/win/tsf_text_store.cc
+++ b/ui/base/ime/win/tsf_text_store.cc
@@ -25,6 +25,25 @@
 // We support only one view.
 const TsViewCookie kViewCookie = 1;
 
+// Fetches the client rectangle, top left and bottom right points using the
+// window handle in screen coordinates.
+bool GetWindowClientRect(HWND window_handle,
+                         POINT* left_top,
+                         POINT* right_bottom) {
+  RECT client_rect = {};
+  if (!IsWindow(window_handle))
+    return false;
+  if (!GetClientRect(window_handle, &client_rect))
+    return false;
+  *left_top = {client_rect.left, client_rect.top};
+  *right_bottom = {client_rect.right, client_rect.bottom};
+  if (!ClientToScreen(window_handle, left_top))
+    return false;
+  if (!ClientToScreen(window_handle, right_bottom))
+    return false;
+  return true;
+}
+
 }  // namespace
 
 TSFTextStore::TSFTextStore() {
@@ -167,27 +186,32 @@
   // {0, 0, 0, 0} means that the document rect is not currently displayed.
   SetRect(rect, 0, 0, 0, 0);
 
-  if (!IsWindow(window_handle_))
-    return E_FAIL;
-
   // Currently ui::TextInputClient does not expose the document rect. So use
   // the Win32 client rectangle instead.
   // TODO(yukawa): Upgrade TextInputClient so that the client can retrieve the
   // document rectangle.
-  RECT client_rect = {};
-  if (!GetClientRect(window_handle_, &client_rect))
-    return E_FAIL;
-  POINT left_top = {client_rect.left, client_rect.top};
-  POINT right_bottom = {client_rect.right, client_rect.bottom};
-  if (!ClientToScreen(window_handle_, &left_top))
-    return E_FAIL;
-  if (!ClientToScreen(window_handle_, &right_bottom))
+  POINT left_top;
+  POINT right_bottom;
+  if (!GetWindowClientRect(window_handle_, &left_top, &right_bottom))
     return E_FAIL;
 
   rect->left = left_top.x;
   rect->top = left_top.y;
   rect->right = right_bottom.x;
   rect->bottom = right_bottom.y;
+  // If the EditContext is active, then fetch the layout bounds from
+  // the active EditContext.
+  gfx::Rect result_rect;
+  gfx::Rect tmp_rect;
+  // TODO(snianu): Use this route to fetch the focused content editable
+  // element's layout bounds instead of reporting the client rectangle.
+  if (text_input_client_->GetEditContextLayoutBounds(&result_rect, &tmp_rect)) {
+    *rect =
+        display::win::ScreenWin::DIPToScreenRect(window_handle_, result_rect)
+            .ToRECT();
+    rect->left += left_top.x;
+    rect->top += left_top.y;
+  }
   return S_OK;
 }
 
@@ -306,6 +330,21 @@
   const uint32_t start_pos = acp_start - composition_start_;
   const uint32_t end_pos = acp_end - composition_start_;
 
+  // If there is an active EditContext, then fetch the layout bounds from it.
+  if (text_input_client_->GetEditContextLayoutBounds(&tmp_rect, &result_rect)) {
+    POINT left_top;
+    POINT right_bottom;
+    if (!GetWindowClientRect(window_handle_, &left_top, &right_bottom))
+      return E_FAIL;
+    *rect =
+        display::win::ScreenWin::DIPToScreenRect(window_handle_, result_rect)
+            .ToRECT();
+    rect->left += left_top.x;
+    rect->top += left_top.y;
+    *clipped = FALSE;
+    return S_OK;
+  }
+
   if (start_pos == end_pos) {
     if (text_input_client_->HasCompositionText()) {
       // According to MSDN document, if |acp_start| and |acp_end| are equal it
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc
index 7909ade..68d83142 100644
--- a/ui/base/ime/win/tsf_text_store_unittest.cc
+++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -70,6 +70,8 @@
                bool(const gfx::Range&, const std::vector<ui::ImeTextSpan>&));
   MOCK_METHOD3(SetActiveCompositionForAccessibility,
                void(const gfx::Range&, const base::string16&, bool));
+  MOCK_METHOD2(GetEditContextLayoutBounds,
+               bool(gfx::Rect* control_bounds, gfx::Rect* selection_bounds));
 };
 
 class MockInputMethodDelegate : public internal::InputMethodDelegate {
diff --git a/ui/events/blink/blink_event_util.cc b/ui/events/blink/blink_event_util.cc
index 993351a..61ad07c 100644
--- a/ui/events/blink/blink_event_util.cc
+++ b/ui/events/blink/blink_event_util.cc
@@ -443,10 +443,10 @@
   // not be exactly equal, so we only require approximate equality.
   constexpr float kAnchorTolerance = 1.f;
   if (event.GetType() == WebInputEvent::kGesturePinchUpdate &&
-      (std::abs(event.PositionInWidget().x -
-                event_to_coalesce.PositionInWidget().x) < kAnchorTolerance) &&
-      (std::abs(event.PositionInWidget().y -
-                event_to_coalesce.PositionInWidget().y) < kAnchorTolerance)) {
+      (std::abs(event.PositionInWidget().x() -
+                event_to_coalesce.PositionInWidget().x()) < kAnchorTolerance) &&
+      (std::abs(event.PositionInWidget().y() -
+                event_to_coalesce.PositionInWidget().y()) < kAnchorTolerance)) {
     return true;
   }
 
@@ -480,11 +480,11 @@
                                 gesture_event.data.scroll_update.delta_y);
   } else if (gesture_event.GetType() == WebInputEvent::kGesturePinchUpdate) {
     float scale = gesture_event.data.pinch_update.scale;
-    gesture_transform.Translate(-gesture_event.PositionInWidget().x,
-                                -gesture_event.PositionInWidget().y);
+    gesture_transform.Translate(-gesture_event.PositionInWidget().x(),
+                                -gesture_event.PositionInWidget().y());
     gesture_transform.Scale(scale, scale);
-    gesture_transform.Translate(gesture_event.PositionInWidget().x,
-                                gesture_event.PositionInWidget().y);
+    gesture_transform.Translate(gesture_event.PositionInWidget().x(),
+                                gesture_event.PositionInWidget().y());
   } else {
     NOTREACHED() << "Invalid event type for transform retrieval: "
                  << WebInputEvent::GetName(gesture_event.GetType());
@@ -619,13 +619,13 @@
   float combined_scroll_pinch_y =
       SkMScalarToFloat(combined_scroll_pinch.matrix().get(1, 3));
   scroll_event.data.scroll_update.delta_x =
-      (combined_scroll_pinch_x + pinch_event.PositionInWidget().x) /
+      (combined_scroll_pinch_x + pinch_event.PositionInWidget().x()) /
           combined_scale -
-      pinch_event.PositionInWidget().x;
+      pinch_event.PositionInWidget().x();
   scroll_event.data.scroll_update.delta_y =
-      (combined_scroll_pinch_y + pinch_event.PositionInWidget().y) /
+      (combined_scroll_pinch_y + pinch_event.PositionInWidget().y()) /
           combined_scale -
-      pinch_event.PositionInWidget().y;
+      pinch_event.PositionInWidget().y();
   pinch_event.data.pinch_update.scale = combined_scale;
 
   return std::make_pair(scroll_event, pinch_event);
@@ -866,8 +866,8 @@
     blink::WebMouseWheelEvent* wheel_event = new blink::WebMouseWheelEvent;
     scaled_event.reset(wheel_event);
     *wheel_event = static_cast<const blink::WebMouseWheelEvent&>(event);
-    float x = (wheel_event->PositionInWidget().x + delta.x()) * scale;
-    float y = (wheel_event->PositionInWidget().y + delta.y()) * scale;
+    float x = (wheel_event->PositionInWidget().x() + delta.x()) * scale;
+    float y = (wheel_event->PositionInWidget().y() + delta.y()) * scale;
     wheel_event->SetPositionInWidget(x, y);
     if (wheel_event->delta_units !=
         ui::input_types::ScrollGranularity::kScrollByPage) {
@@ -880,8 +880,8 @@
     blink::WebMouseEvent* mouse_event = new blink::WebMouseEvent;
     scaled_event.reset(mouse_event);
     *mouse_event = static_cast<const blink::WebMouseEvent&>(event);
-    float x = (mouse_event->PositionInWidget().x + delta.x()) * scale;
-    float y = (mouse_event->PositionInWidget().y + delta.y()) * scale;
+    float x = (mouse_event->PositionInWidget().x() + delta.x()) * scale;
+    float y = (mouse_event->PositionInWidget().y() + delta.y()) * scale;
     mouse_event->SetPositionInWidget(x, y);
     // Do not scale movement of raw movement events.
     if (!mouse_event->is_raw_movement_event) {
@@ -894,8 +894,8 @@
     *touch_event = static_cast<const blink::WebTouchEvent&>(event);
     for (unsigned i = 0; i < touch_event->touches_length; i++) {
       touch_event->touches[i].SetPositionInWidget(
-          (touch_event->touches[i].PositionInWidget().x + delta.x()) * scale,
-          (touch_event->touches[i].PositionInWidget().y + delta.y()) * scale);
+          (touch_event->touches[i].PositionInWidget().x() + delta.x()) * scale,
+          (touch_event->touches[i].PositionInWidget().y() + delta.y()) * scale);
       touch_event->touches[i].radius_x *= scale;
       touch_event->touches[i].radius_y *= scale;
     }
@@ -903,9 +903,9 @@
     blink::WebGestureEvent* gesture_event = new blink::WebGestureEvent;
     scaled_event.reset(gesture_event);
     *gesture_event = static_cast<const blink::WebGestureEvent&>(event);
-    gesture_event->SetPositionInWidget(blink::WebFloatPoint(
-        (gesture_event->PositionInWidget().x + delta.x()) * scale,
-        (gesture_event->PositionInWidget().y + delta.y()) * scale));
+    gesture_event->SetPositionInWidget(gfx::PointF(
+        (gesture_event->PositionInWidget().x() + delta.x()) * scale,
+        (gesture_event->PositionInWidget().y() + delta.y()) * scale));
     switch (gesture_event->GetType()) {
       case blink::WebInputEvent::kGestureScrollUpdate:
         if (gesture_event->data.scroll_update.delta_units ==
@@ -1244,7 +1244,7 @@
     WebInputEvent::Type type,
     base::TimeTicks timestamp,
     blink::WebGestureDevice device,
-    blink::WebFloatPoint position_in_widget,
+    gfx::PointF position_in_widget,
     gfx::Vector2dF scroll_delta,
     input_types::ScrollGranularity granularity) {
   DCHECK(IsGestureScroll(type));
@@ -1273,14 +1273,13 @@
   return generated_gesture_event;
 }
 
-blink::WebFloatPoint PositionInWidgetFromInputEvent(
-    const blink::WebInputEvent& event) {
+gfx::PointF PositionInWidgetFromInputEvent(const blink::WebInputEvent& event) {
   if (WebInputEvent::IsMouseEventType(event.GetType())) {
     return static_cast<const WebMouseEvent&>(event).PositionInWidget();
   } else if (WebInputEvent::IsGestureEventType(event.GetType())) {
     return static_cast<const WebGestureEvent&>(event).PositionInWidget();
   } else {
-    return blink::WebFloatPoint(0, 0);
+    return gfx::PointF(0, 0);
   }
 }
 
diff --git a/ui/events/blink/blink_event_util.h b/ui/events/blink/blink_event_util.h
index fc2c81c..ec2319e0 100644
--- a/ui/events/blink/blink_event_util.h
+++ b/ui/events/blink/blink_event_util.h
@@ -121,13 +121,12 @@
     blink::WebInputEvent::Type type,
     base::TimeTicks timestamp,
     blink::WebGestureDevice device,
-    blink::WebFloatPoint position_in_widget,
+    gfx::PointF position_in_widget,
     gfx::Vector2dF scroll_delta,
     input_types::ScrollGranularity granularity);
 
 // Returns the position in the widget if it exists for the passed in event type
-blink::WebFloatPoint PositionInWidgetFromInputEvent(
-    const blink::WebInputEvent& event);
+gfx::PointF PositionInWidgetFromInputEvent(const blink::WebInputEvent& event);
 
 #if defined(OS_ANDROID)
 // Convenience method that converts an instance to blink event.
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index 766e54a..ffc3743 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -52,8 +52,8 @@
   cc::ScrollStateData scroll_state_data;
   switch (event.GetType()) {
     case WebInputEvent::kGestureScrollBegin:
-      scroll_state_data.position_x = event.PositionInWidget().x;
-      scroll_state_data.position_y = event.PositionInWidget().y;
+      scroll_state_data.position_x = event.PositionInWidget().x();
+      scroll_state_data.position_y = event.PositionInWidget().y();
       scroll_state_data.delta_x_hint = -event.data.scroll_begin.delta_x_hint;
       scroll_state_data.delta_y_hint = -event.data.scroll_begin.delta_y_hint;
       scroll_state_data.is_beginning = true;
@@ -395,7 +395,7 @@
 // scrollbar. (See InputHandlerProxy::HandleInputEvent)
 void InputHandlerProxy::InjectScrollbarGestureScroll(
     const WebInputEvent::Type type,
-    const blink::WebFloatPoint& position_in_widget,
+    const gfx::PointF& position_in_widget,
     const cc::InputHandlerPointerResult& pointer_result,
     const LatencyInfo& latency_info,
     const base::TimeTicks original_timestamp) {
@@ -615,8 +615,8 @@
       CHECK(input_handler_);
       cc::InputHandlerPointerResult pointer_result =
           input_handler_->MouseMoveAt(
-              gfx::Point(mouse_event.PositionInWidget().x,
-                         mouse_event.PositionInWidget().y));
+              gfx::Point(mouse_event.PositionInWidget().x(),
+                         mouse_event.PositionInWidget().y()));
       if (pointer_result.type == cc::PointerResultType::kScrollbarScroll) {
         // Generate a GSU event and add it to the CompositorThreadEventQueue.
         InjectScrollbarGestureScroll(WebInputEvent::Type::kGestureScrollUpdate,
@@ -783,9 +783,9 @@
       return result;
   }
 
-  blink::WebFloatPoint position_in_widget = wheel_event.PositionInWidget();
+  gfx::PointF position_in_widget = wheel_event.PositionInWidget();
   if (input_handler_->HasBlockingWheelEventHandlerAt(
-          gfx::Point(position_in_widget.x, position_in_widget.y))) {
+          gfx::Point(position_in_widget.x(), position_in_widget.y()))) {
     result = DID_NOT_HANDLE;
   } else {
     cc::EventListenerProperties properties =
@@ -1011,8 +1011,8 @@
     cc::TouchAction touch_action = cc::TouchAction::kAuto;
     cc::InputHandler::TouchStartOrMoveEventListenerType event_listener_type =
         input_handler_->EventListenerTypeForTouchStartOrMoveAt(
-            gfx::Point(touch_event.touches[i].PositionInWidget().x,
-                       touch_event.touches[i].PositionInWidget().y),
+            gfx::Point(touch_event.touches[i].PositionInWidget().x(),
+                       touch_event.touches[i].PositionInWidget().y()),
             &touch_action);
     if (white_listed_touch_action)
       *white_listed_touch_action &= touch_action;
diff --git a/ui/events/blink/input_handler_proxy.h b/ui/events/blink/input_handler_proxy.h
index faafa5656..f538ac6 100644
--- a/ui/events/blink/input_handler_proxy.h
+++ b/ui/events/blink/input_handler_proxy.h
@@ -85,7 +85,7 @@
                                        EventDispositionCallback callback);
   void InjectScrollbarGestureScroll(
       const blink::WebInputEvent::Type type,
-      const blink::WebFloatPoint& position_in_widget,
+      const gfx::PointF& position_in_widget,
       const cc::InputHandlerPointerResult& pointer_result,
       const LatencyInfo& latency_info,
       const base::TimeTicks now);
diff --git a/ui/events/blink/web_input_event_builders_win.cc b/ui/events/blink/web_input_event_builders_win.cc
index a9bbe80..7523507 100644
--- a/ui/events/blink/web_input_event_builders_win.cc
+++ b/ui/events/blink/web_input_event_builders_win.cc
@@ -133,8 +133,8 @@
   // set position fields:
   result.SetPositionInWidget(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
 
-  POINT global_point = {result.PositionInWidget().x,
-                        result.PositionInWidget().y};
+  POINT global_point = {result.PositionInWidget().x(),
+                        result.PositionInWidget().y()};
   ClientToScreen(hwnd, &global_point);
 
   // We need to convert the global point back to DIP before using it.
@@ -153,9 +153,9 @@
 
   base::TimeTicks current_time = result.TimeStamp();
   bool cancel_previous_click =
-      (abs(last_click_position_x - result.PositionInWidget().x) >
+      (abs(last_click_position_x - result.PositionInWidget().x()) >
        (::GetSystemMetrics(SM_CXDOUBLECLK) / 2)) ||
-      (abs(last_click_position_y - result.PositionInWidget().y) >
+      (abs(last_click_position_y - result.PositionInWidget().y()) >
        (::GetSystemMetrics(SM_CYDOUBLECLK) / 2)) ||
       ((current_time - g_last_click_time).InMilliseconds() >
        ::GetDoubleClickTime());
@@ -165,8 +165,8 @@
       ++g_last_click_count;
     } else {
       g_last_click_count = 1;
-      last_click_position_x = result.PositionInWidget().x;
-      last_click_position_y = result.PositionInWidget().y;
+      last_click_position_x = result.PositionInWidget().x();
+      last_click_position_y = result.PositionInWidget().y();
     }
     g_last_click_time = current_time;
     last_click_button = result.button;
@@ -275,8 +275,8 @@
   result.SetModifiers(modifiers);
 
   // Set coordinates by translating event coordinates from screen to client.
-  POINT client_point = {result.PositionInScreen().x,
-                        result.PositionInScreen().y};
+  POINT client_point = {result.PositionInScreen().x(),
+                        result.PositionInScreen().y()};
   MapWindowPoints(0, hwnd, &client_point, 1);
   result.SetPositionInWidget(client_point.x, client_point.y);
 
diff --git a/ui/events/blink/web_input_event_builders_win_unittest.cc b/ui/events/blink/web_input_event_builders_win_unittest.cc
index c38f874..82f989a 100644
--- a/ui/events/blink/web_input_event_builders_win_unittest.cc
+++ b/ui/events/blink/web_input_event_builders_win_unittest.cc
@@ -35,12 +35,12 @@
   // The WebMouseEvent.position field should be in pixels on return and hence
   // should be the same value as the x and y coordinates passed in to the
   // WebMouseEventBuilder::Build function.
-  EXPECT_EQ(300, mouse_move.PositionInWidget().x);
-  EXPECT_EQ(200, mouse_move.PositionInWidget().y);
+  EXPECT_EQ(300, mouse_move.PositionInWidget().x());
+  EXPECT_EQ(200, mouse_move.PositionInWidget().y());
 
   // WebMouseEvent.positionInScreen is calculated in DIPs.
-  EXPECT_EQ(150, mouse_move.PositionInScreen().x);
-  EXPECT_EQ(100, mouse_move.PositionInScreen().y);
+  EXPECT_EQ(150, mouse_move.PositionInScreen().x());
+  EXPECT_EQ(100, mouse_move.PositionInScreen().y());
 
   EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
             mouse_move.pointer_type);
diff --git a/ui/events/blink/web_input_event_traits.cc b/ui/events/blink/web_input_event_traits.cc
index 646792f..db1cd34 100644
--- a/ui/events/blink/web_input_event_traits.cc
+++ b/ui/events/blink/web_input_event_traits.cc
@@ -39,10 +39,10 @@
   StringAppendF(result,
                 "{\n Button: %d\n Pos: (%f, %f)\n"
                 " GlobalPos: (%f, %f)\n Movement: (%d, %d)\n Clicks: %d\n}",
-                static_cast<int>(event.button), event.PositionInWidget().x,
-                event.PositionInWidget().y, event.PositionInScreen().x,
-                event.PositionInScreen().y, event.movement_x, event.movement_y,
-                event.click_count);
+                static_cast<int>(event.button), event.PositionInWidget().x(),
+                event.PositionInWidget().y(), event.PositionInScreen().x(),
+                event.PositionInScreen().y(), event.movement_x,
+                event.movement_y, event.click_count);
 }
 
 void ApppendEventDetails(const WebMouseWheelEvent& event, std::string* result) {
@@ -59,8 +59,8 @@
   StringAppendF(result,
                 "{\n Pos: (%f, %f)\n GlobalPos: (%f, %f)\n SourceDevice: %d\n"
                 " RawData: (%f, %f, %f, %f)\n}",
-                event.PositionInWidget().x, event.PositionInWidget().y,
-                event.PositionInScreen().x, event.PositionInScreen().y,
+                event.PositionInWidget().x(), event.PositionInWidget().y(),
+                event.PositionInScreen().x(), event.PositionInScreen().y(),
                 event.SourceDevice(), event.data.scroll_update.delta_x,
                 event.data.scroll_update.delta_y,
                 event.data.scroll_update.velocity_x,
@@ -72,9 +72,9 @@
                 "  (ID: %d, State: %d, ScreenPos: (%f, %f), Pos: (%f, %f),"
                 " Radius: (%f, %f), Rot: %f, Force: %f,"
                 " Tilt: (%d, %d), Twist: %d, TangentialPressure: %f),\n",
-                point.id, point.state, point.PositionInScreen().x,
-                point.PositionInScreen().y, point.PositionInWidget().x,
-                point.PositionInWidget().y, point.radius_x, point.radius_y,
+                point.id, point.state, point.PositionInScreen().x(),
+                point.PositionInScreen().y(), point.PositionInWidget().x(),
+                point.PositionInWidget().y(), point.radius_x, point.radius_y,
                 point.rotation_angle, point.force, point.tilt_x, point.tilt_y,
                 point.twist, point.tangential_pressure);
 }
@@ -98,9 +98,9 @@
       " GlobalPos: (%f, %f)\n Movement: (%d, %d)\n width: %f\n height: "
       "%f\n Pressure: %f\n TangentialPressure: %f\n Rotation: %f\n Tilt: "
       "(%d, %d)\n}",
-      event.id, static_cast<int>(event.button), event.PositionInWidget().x,
-      event.PositionInWidget().y, event.PositionInScreen().x,
-      event.PositionInScreen().y, event.movement_x, event.movement_y,
+      event.id, static_cast<int>(event.button), event.PositionInWidget().x(),
+      event.PositionInWidget().y(), event.PositionInScreen().x(),
+      event.PositionInScreen().y(), event.movement_x, event.movement_y,
       event.width, event.height, event.force, event.tangential_pressure,
       event.rotation_angle, event.tilt_x, event.tilt_y);
 }
diff --git a/ui/events/blink/web_input_event_unittest.cc b/ui/events/blink/web_input_event_unittest.cc
index 931dfa9..69f853c 100644
--- a/ui/events/blink/web_input_event_unittest.cc
+++ b/ui/events/blink/web_input_event_unittest.cc
@@ -253,8 +253,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kLeft, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseDown, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Left released.
@@ -269,8 +269,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kLeft, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseUp, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Middle pressed.
@@ -285,8 +285,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kMiddle, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseDown, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Middle released.
@@ -301,8 +301,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kMiddle, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseUp, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Right pressed.
@@ -317,8 +317,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kRight, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseDown, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Right released.
@@ -333,8 +333,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kRight, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseUp, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Moved
@@ -348,8 +348,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kNoButton, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseMove, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Moved with left down
@@ -364,8 +364,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kLeft, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseMove, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Left with shift pressed.
@@ -380,8 +380,8 @@
     EXPECT_EQ(blink::WebMouseEvent::Button::kLeft, webkit_event.button);
     EXPECT_EQ(blink::WebInputEvent::kMouseDown, webkit_event.GetType());
     EXPECT_EQ(ui_event.GetClickCount(), webkit_event.click_count);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Default values for PointerDetails.
@@ -398,8 +398,8 @@
     EXPECT_TRUE(std::isnan(webkit_event.force));
     EXPECT_EQ(0.0f, webkit_event.tangential_pressure);
     EXPECT_EQ(0, webkit_event.twist);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
   {
     // Stylus values for PointerDetails.
@@ -426,8 +426,8 @@
     EXPECT_FLOAT_EQ(0.6f, webkit_event.tangential_pressure);
     EXPECT_EQ(269, webkit_event.twist);
     EXPECT_EQ(63, webkit_event.id);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
 }
 
@@ -456,8 +456,8 @@
     EXPECT_TRUE(std::isnan(webkit_event.force));
     EXPECT_EQ(0.0f, webkit_event.tangential_pressure);
     EXPECT_EQ(0, webkit_event.twist);
-    EXPECT_EQ(123, webkit_event.PositionInWidget().x);
-    EXPECT_EQ(321, webkit_event.PositionInWidget().y);
+    EXPECT_EQ(123, webkit_event.PositionInWidget().x());
+    EXPECT_EQ(321, webkit_event.PositionInWidget().y());
   }
 }
 
@@ -531,10 +531,10 @@
     ASSERT_TRUE(blink::WebInputEvent::IsMouseEventType(web_event.GetType()));
     ASSERT_EQ(tests[i].web_type, web_event.GetType());
     ASSERT_EQ(tests[i].web_modifiers, web_event.GetModifiers());
-    ASSERT_EQ(tests[i].location.x(), web_event.PositionInWidget().x);
-    ASSERT_EQ(tests[i].location.y(), web_event.PositionInWidget().y);
-    ASSERT_EQ(tests[i].screen_location.x(), web_event.PositionInScreen().x);
-    ASSERT_EQ(tests[i].screen_location.y(), web_event.PositionInScreen().y);
+    ASSERT_EQ(tests[i].location.x(), web_event.PositionInWidget().x());
+    ASSERT_EQ(tests[i].location.y(), web_event.PositionInWidget().y());
+    ASSERT_EQ(tests[i].screen_location.x(), web_event.PositionInScreen().x());
+    ASSERT_EQ(tests[i].screen_location.y(), web_event.PositionInScreen().y());
   }
 }
 
@@ -549,10 +549,10 @@
 
   // WM_MOUSELEAVE events take coordinates from cursor position instead of
   // LPARAM.
-  ASSERT_EQ(250, web_event.PositionInWidget().x);
-  ASSERT_EQ(350, web_event.PositionInWidget().y);
-  ASSERT_EQ(250, web_event.PositionInScreen().x);
-  ASSERT_EQ(350, web_event.PositionInScreen().y);
+  ASSERT_EQ(250, web_event.PositionInWidget().x());
+  ASSERT_EQ(350, web_event.PositionInWidget().y());
+  ASSERT_EQ(250, web_event.PositionInScreen().x());
+  ASSERT_EQ(350, web_event.PositionInScreen().y());
 }
 #endif
 
diff --git a/ui/events/ipc/BUILD.gn b/ui/events/ipc/BUILD.gn
new file mode 100644
index 0000000..13b5c83
--- /dev/null
+++ b/ui/events/ipc/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/jumbo.gni")
+
+jumbo_component("ipc") {
+  output_name = "ui_events_ipc"
+
+  sources = [
+    "ui_events_param_traits.cc",
+    "ui_events_param_traits_macros.h",
+  ]
+
+  defines = [ "IS_UI_EVENTS_IPC_IMPL" ]
+
+  public_deps = [
+    "//base",
+    "//ipc",
+  ]
+}
diff --git a/ui/events/ipc/OWNERS b/ui/events/ipc/OWNERS
new file mode 100644
index 0000000..146c3c3c
--- /dev/null
+++ b/ui/events/ipc/OWNERS
@@ -0,0 +1,2 @@
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ui/events/ipc/ui_events_param_traits.cc b/ui/events/ipc/ui_events_param_traits.cc
new file mode 100644
index 0000000..d7a7f36
--- /dev/null
+++ b/ui/events/ipc/ui_events_param_traits.cc
@@ -0,0 +1,26 @@
+// 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 "ui/events/ipc/ui_events_param_traits_macros.h"
+
+#include "ipc/param_traits_write_macros.h"
+
+namespace IPC {
+#undef UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
+#include "ui/events/ipc/ui_events_param_traits_macros.h"
+}  // namespace IPC
+
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#undef UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
+#include "ui/events/ipc/ui_events_param_traits_macros.h"
+}  // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#undef UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
+#include "ui/events/ipc/ui_events_param_traits_macros.h"
+}  // namespace IPC
diff --git a/ui/events/ipc/ui_events_param_traits_macros.h b/ui/events/ipc/ui_events_param_traits_macros.h
new file mode 100644
index 0000000..e31ba3d
--- /dev/null
+++ b/ui/events/ipc/ui_events_param_traits_macros.h
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
+#define UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
+
+#include "base/component_export.h"
+#include "ipc/ipc_message_macros.h"
+#include "ui/events/types/scroll_types.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT COMPONENT_EXPORT(UI_EVENTS_IPC)
+
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(
+    ui::input_types::ScrollGranularity,
+    ui::input_types::ScrollGranularity::kFirstScrollGranularity,
+    ui::input_types::ScrollGranularity::kMaxValue)
+
+#endif  // UI_EVENTS_IPC_UI_EVENTS_PARAM_TRAITS_MACROS_H_
diff --git a/ui/events/mojom/BUILD.gn b/ui/events/mojom/BUILD.gn
index eb177e8..c281273 100644
--- a/ui/events/mojom/BUILD.gn
+++ b/ui/events/mojom/BUILD.gn
@@ -5,10 +5,12 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 
 mojom("mojom") {
+  generate_java = true
   sources = [
     "event.mojom",
     "event_constants.mojom",
     "keyboard_codes.mojom",
+    "scroll_granularity.mojom",
   ]
 
   public_deps = [
diff --git a/chrome/browser/policy/e2e_test/infra/__init__.py b/ui/events/mojom/blink_typemaps.gni
similarity index 71%
rename from chrome/browser/policy/e2e_test/infra/__init__.py
rename to ui/events/mojom/blink_typemaps.gni
index 9226ba6..4f4e185 100644
--- a/chrome/browser/policy/e2e_test/infra/__init__.py
+++ b/ui/events/mojom/blink_typemaps.gni
@@ -2,4 +2,4 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from chrome_ent_test_case import ChromeEnterpriseTestCase
\ No newline at end of file
+typemaps = [ "//ui/events/mojom/scroll_granularity.typemap" ]
diff --git a/ui/events/mojom/scroll_granularity.mojom b/ui/events/mojom/scroll_granularity.mojom
new file mode 100644
index 0000000..7bf2ad4
--- /dev/null
+++ b/ui/events/mojom/scroll_granularity.mojom
@@ -0,0 +1,8 @@
+// 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.
+
+module ui.mojom;
+
+[Native]
+enum ScrollGranularity;
diff --git a/ui/events/mojom/scroll_granularity.typemap b/ui/events/mojom/scroll_granularity.typemap
new file mode 100644
index 0000000..02fe65b
--- /dev/null
+++ b/ui/events/mojom/scroll_granularity.typemap
@@ -0,0 +1,12 @@
+# 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.
+
+mojom = "//ui/events/mojom/scroll_granularity.mojom"
+public_headers = [ "//ui/events/types/scroll_types.h" ]
+traits_headers = [ "//ui/events/ipc/ui_events_param_traits_macros.h" ]
+public_deps = [
+  "//ui/events/ipc",
+]
+type_mappings =
+    [ "ui.mojom.ScrollGranularity=::ui::input_types::ScrollGranularity" ]
diff --git a/ui/events/mojom/typemaps.gni b/ui/events/mojom/typemaps.gni
index 74433b7..14cd946 100644
--- a/ui/events/mojom/typemaps.gni
+++ b/ui/events/mojom/typemaps.gni
@@ -2,4 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-typemaps = [ "//ui/events/mojom/event.typemap" ]
+typemaps = [
+  "//ui/events/mojom/event.typemap",
+  "//ui/events/mojom/scroll_granularity.typemap",
+]
diff --git a/ui/file_manager/OWNERS b/ui/file_manager/OWNERS
index 353bd977..85fcdd5 100644
--- a/ui/file_manager/OWNERS
+++ b/ui/file_manager/OWNERS
@@ -1,3 +1,4 @@
+adanilo@chromium.org
 amistry@chromium.org
 austinct@chromium.org
 dats@chromium.org
diff --git a/ui/file_manager/file_manager/foreground/elements/xf_button.js b/ui/file_manager/file_manager/foreground/elements/xf_button.js
index b96ed06..0515956 100644
--- a/ui/file_manager/file_manager/foreground/elements/xf_button.js
+++ b/ui/file_manager/file_manager/foreground/elements/xf_button.js
@@ -60,6 +60,7 @@
               }
 
               :host {
+                flex-shrink: 0;
                 position: relative;
               }
 
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 3e02839f..b699127 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -882,6 +882,15 @@
     this.providersModel_ = new ProvidersModel(this.volumeManager_);
     this.fileFilter_ = new FileFilter(this.metadataModel_);
 
+    // Set the files-ng class for dialog header styling.
+    const dialogHeader = queryRequiredElement('.dialog-header');
+    if (util.isFilesNg()) {
+      dialogHeader.classList.add('files-ng');
+      // Move the dialog header to the side of the splitter above the list view.
+      const dialogMain = queryRequiredElement('.dialog-main');
+      dialogMain.insertBefore(dialogHeader, dialogMain.firstChild);
+    }
+
     // Create the root view of FileManager.
     assert(this.dialogDom_);
     assert(this.launchParams_);
diff --git a/ui/gfx/buffer_format_util.cc b/ui/gfx/buffer_format_util.cc
index dfa3e4cd..81df32b9 100644
--- a/ui/gfx/buffer_format_util.cc
+++ b/ui/gfx/buffer_format_util.cc
@@ -11,15 +11,21 @@
 namespace gfx {
 namespace {
 
-const BufferFormat kBufferFormats[] = {
-    BufferFormat::R_8,              BufferFormat::R_16,
-    BufferFormat::RG_88,            BufferFormat::BGR_565,
-    BufferFormat::RGBA_4444,        BufferFormat::RGBX_8888,
-    BufferFormat::RGBA_8888,        BufferFormat::BGRX_8888,
-    BufferFormat::BGRX_1010102,     BufferFormat::RGBX_1010102,
-    BufferFormat::BGRA_8888,        BufferFormat::RGBA_F16,
-    BufferFormat::YUV_420_BIPLANAR, BufferFormat::YVU_420,
-    BufferFormat::P010};
+const BufferFormat kBufferFormats[] = {BufferFormat::R_8,
+                                       BufferFormat::R_16,
+                                       BufferFormat::RG_88,
+                                       BufferFormat::BGR_565,
+                                       BufferFormat::RGBA_4444,
+                                       BufferFormat::RGBX_8888,
+                                       BufferFormat::RGBA_8888,
+                                       BufferFormat::BGRX_8888,
+                                       BufferFormat::BGRX_1010102,
+                                       BufferFormat::RGBA_1010102,
+                                       BufferFormat::BGRA_8888,
+                                       BufferFormat::RGBA_F16,
+                                       BufferFormat::YUV_420_BIPLANAR,
+                                       BufferFormat::YVU_420,
+                                       BufferFormat::P010};
 
 static_assert(base::size(kBufferFormats) ==
                   (static_cast<int>(BufferFormat::LAST) + 1),
@@ -43,7 +49,7 @@
     case BufferFormat::RGBA_8888:
     case BufferFormat::BGRX_8888:
     case BufferFormat::BGRX_1010102:
-    case BufferFormat::RGBX_1010102:
+    case BufferFormat::RGBA_1010102:
     case BufferFormat::BGRA_8888:
     case BufferFormat::RGBA_F16:
       return 1;
@@ -68,7 +74,7 @@
     case BufferFormat::RGBA_8888:
     case BufferFormat::BGRX_8888:
     case BufferFormat::BGRX_1010102:
-    case BufferFormat::RGBX_1010102:
+    case BufferFormat::RGBA_1010102:
     case BufferFormat::BGRA_8888:
     case BufferFormat::RGBA_F16:
       return 1;
@@ -119,7 +125,7 @@
       return true;
     case BufferFormat::BGRX_8888:
     case BufferFormat::BGRX_1010102:
-    case BufferFormat::RGBX_1010102:
+    case BufferFormat::RGBA_1010102:
     case BufferFormat::RGBX_8888:
     case BufferFormat::RGBA_8888:
     case BufferFormat::BGRA_8888:
@@ -194,7 +200,7 @@
     case BufferFormat::RGBA_8888:
     case BufferFormat::BGRX_8888:
     case BufferFormat::BGRX_1010102:
-    case BufferFormat::RGBX_1010102:
+    case BufferFormat::RGBA_1010102:
     case BufferFormat::BGRA_8888:
     case BufferFormat::RGBA_F16:
       return 0;
@@ -241,8 +247,8 @@
       return "BGRX_8888";
     case BufferFormat::BGRX_1010102:
       return "BGRX_1010102";
-    case BufferFormat::RGBX_1010102:
-      return "RGBX_1010102";
+    case BufferFormat::RGBA_1010102:
+      return "RGBA_1010102";
     case BufferFormat::BGRA_8888:
       return "BGRA_8888";
     case BufferFormat::RGBA_F16:
diff --git a/ui/gfx/buffer_types.h b/ui/gfx/buffer_types.h
index ebc8e01..37ca972 100644
--- a/ui/gfx/buffer_types.h
+++ b/ui/gfx/buffer_types.h
@@ -21,7 +21,7 @@
   RGBA_8888,
   BGRX_8888,
   BGRX_1010102,
-  RGBX_1010102,
+  RGBA_1010102,
   BGRA_8888,
   RGBA_F16,
   YVU_420,
diff --git a/ui/gfx/linux/BUILD.gn b/ui/gfx/linux/BUILD.gn
index 74205a9..b367a14e 100644
--- a/ui/gfx/linux/BUILD.gn
+++ b/ui/gfx/linux/BUILD.gn
@@ -23,6 +23,7 @@
 source_set("gbm") {
   sources = [
     "gbm_buffer.h",
+    "gbm_defines.h",
     "gbm_device.h",
     "gbm_wrapper.cc",
     "gbm_wrapper.h",
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
index a0de4bb..dacee6ec 100644
--- a/ui/gfx/linux/client_native_pixmap_dmabuf.cc
+++ b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -129,7 +129,7 @@
           format == gfx::BufferFormat::R_8 ||
           format == gfx::BufferFormat::RG_88 ||
           format == gfx::BufferFormat::YUV_420_BIPLANAR ||
-          format == gfx::BufferFormat::RGBX_1010102 ||
+          format == gfx::BufferFormat::RGBA_1010102 ||
           format == gfx::BufferFormat::BGRX_1010102 ||
 #endif
 
diff --git a/ui/gfx/linux/drm_util_linux.cc b/ui/gfx/linux/drm_util_linux.cc
index dd4fad1b1fb..5ebca3ac 100644
--- a/ui/gfx/linux/drm_util_linux.cc
+++ b/ui/gfx/linux/drm_util_linux.cc
@@ -41,7 +41,7 @@
       return DRM_FORMAT_XRGB8888;
     case gfx::BufferFormat::BGRX_1010102:
       return DRM_FORMAT_XRGB2101010;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return DRM_FORMAT_XBGR2101010;
     case gfx::BufferFormat::RGBA_F16:
       return DRM_FORMAT_INVALID;
@@ -72,7 +72,7 @@
     case DRM_FORMAT_XRGB2101010:
       return gfx::BufferFormat::BGRX_1010102;
     case DRM_FORMAT_XBGR2101010:
-      return gfx::BufferFormat::RGBX_1010102;
+      return gfx::BufferFormat::RGBA_1010102;
     case DRM_FORMAT_RGB565:
       return gfx::BufferFormat::BGR_565;
     case DRM_FORMAT_NV12:
diff --git a/ui/gfx/linux/gbm_defines.h b/ui/gfx/linux/gbm_defines.h
new file mode 100644
index 0000000..7069dff
--- /dev/null
+++ b/ui/gfx/linux/gbm_defines.h
@@ -0,0 +1,24 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_LINUX_GBM_DEFINES_H_
+#define UI_GFX_LINUX_GBM_DEFINES_H_
+
+#include <gbm.h>
+
+// Minigbm has some defines that are used by ozone/gbm. However, when we build
+// Ozone for Linux and use system libgbm, these defines are not present and
+// compilation fails. Thus, to fix the issue, mask out these defines and let the
+// compilation go through. The values for these are copied from the minigbm's
+// gbm.h file.
+#if !defined(MINIGBM)
+#define GBM_MAX_PLANES 4
+
+#define GBM_BO_USE_TEXTURING 0
+#define GBM_BO_USE_CAMERA_WRITE 0
+#define GBM_BO_USE_HW_VIDEO_DECODER 0
+#define GBM_BO_USE_HW_VIDEO_ENCODER 0
+#endif
+
+#endif  // UI_GFX_LINUX_GBM_DEFINES_H_
diff --git a/ui/gfx/linux/gbm_wrapper.cc b/ui/gfx/linux/gbm_wrapper.cc
index 7301415..8f185ada 100644
--- a/ui/gfx/linux/gbm_wrapper.cc
+++ b/ui/gfx/linux/gbm_wrapper.cc
@@ -16,14 +16,56 @@
 #include "ui/gfx/linux/gbm_device.h"
 
 #if !defined(MINIGBM)
+#include <dlfcn.h>
 #include <fcntl.h>
 #include <xf86drm.h>
+
+#include "base/strings/stringize_macros.h"
 #endif
 
 namespace gbm_wrapper {
 
 namespace {
 
+#if defined(MINIGBM)
+// Minigbm has all needed functions, so dynamic loading is not necessary.
+#define WRAP_GBM_FN(x) \
+  ALLOW_UNUSED_TYPE decltype(x)* get_##x() { return x; }
+#else
+#define WRAP_GBM_FN(x)                                                        \
+  decltype(auto) get_##x() {                                                  \
+    static auto* x##_ =                                                       \
+        reinterpret_cast<decltype(::x)*>(dlsym(RTLD_DEFAULT, STRINGIZE(x)));  \
+    return x##_;                                                              \
+  }                                                                           \
+  /* Functions that call dlsym-loaded functions must not be instrumented with \
+   * CFI_ICALL. */                                                            \
+  template <typename... Args>                                                 \
+  NO_SANITIZE("cfi-icall")                                                    \
+  decltype(auto) x(Args&&... args) {                                          \
+    if (!get_##x()) {                                                         \
+      LOG(FATAL) << STRINGIZE(x) << "() is not available on this platform. "  \
+                 << STRINGIZE(get_##x)                                        \
+                 << "() should be used to determine availability.";           \
+    }                                                                         \
+    return get_##x()(std::forward<Args>(args)...);                            \
+  }
+#endif
+
+// TODO(https://crbug.com/784010): Remove these once support for Ubuntu Trusty
+// is dropped.
+WRAP_GBM_FN(gbm_bo_map)
+WRAP_GBM_FN(gbm_bo_unmap)
+
+// TODO(https://crbug.com/784010): Remove these once support for Ubuntu Trusty
+// and Debian Stretch are dropped.
+WRAP_GBM_FN(gbm_bo_create_with_modifiers)
+WRAP_GBM_FN(gbm_bo_get_handle_for_plane)
+WRAP_GBM_FN(gbm_bo_get_modifier)
+WRAP_GBM_FN(gbm_bo_get_offset)
+WRAP_GBM_FN(gbm_bo_get_plane_count)
+WRAP_GBM_FN(gbm_bo_get_stride_for_plane)
+
 int GetPlaneFdForBo(gbm_bo* bo, size_t plane) {
 #if defined(MINIGBM)
   return gbm_bo_get_plane_fd(bo, plane);
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
index c383d42..2b16916 100644
--- a/ui/gfx/mac/io_surface.cc
+++ b/ui/gfx/mac/io_surface.cc
@@ -59,7 +59,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::P010:
       NOTREACHED();
@@ -89,8 +89,8 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
-    // Technically RGBX_1010102 should be accepted as 'R10k', but then it won't
+    case gfx::BufferFormat::RGBA_1010102:
+    // Technically RGBA_1010102 should be accepted as 'R10k', but then it won't
     // be supported by CGLTexImageIOSurface2D(), so it's best to reject it here.
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::P010:
diff --git a/ui/gfx/mojom/buffer_types.mojom b/ui/gfx/mojom/buffer_types.mojom
index 3cce5e66..483c0bf 100644
--- a/ui/gfx/mojom/buffer_types.mojom
+++ b/ui/gfx/mojom/buffer_types.mojom
@@ -18,7 +18,7 @@
   RGBA_8888,
   BGRX_8888,
   BGRX_1010102,
-  RGBX_1010102,
+  RGBA_1010102,
   BGRA_8888,
   RGBA_F16,
   YVU_420,
diff --git a/ui/gfx/mojom/buffer_types_mojom_traits.h b/ui/gfx/mojom/buffer_types_mojom_traits.h
index 31d0a587..ca6c9584a 100644
--- a/ui/gfx/mojom/buffer_types_mojom_traits.h
+++ b/ui/gfx/mojom/buffer_types_mojom_traits.h
@@ -37,8 +37,8 @@
         return gfx::mojom::BufferFormat::BGRX_8888;
       case gfx::BufferFormat::BGRX_1010102:
         return gfx::mojom::BufferFormat::BGRX_1010102;
-      case gfx::BufferFormat::RGBX_1010102:
-        return gfx::mojom::BufferFormat::RGBX_1010102;
+      case gfx::BufferFormat::RGBA_1010102:
+        return gfx::mojom::BufferFormat::RGBA_1010102;
       case gfx::BufferFormat::BGRA_8888:
         return gfx::mojom::BufferFormat::BGRA_8888;
       case gfx::BufferFormat::RGBA_F16:
@@ -78,8 +78,8 @@
       case gfx::mojom::BufferFormat::BGRX_1010102:
         *out = gfx::BufferFormat::BGRX_1010102;
         return true;
-      case gfx::mojom::BufferFormat::RGBX_1010102:
-        *out = gfx::BufferFormat::RGBX_1010102;
+      case gfx::mojom::BufferFormat::RGBA_1010102:
+        *out = gfx::BufferFormat::RGBA_1010102;
         return true;
       case gfx::mojom::BufferFormat::RGBA_8888:
         *out = gfx::BufferFormat::RGBA_8888;
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 9880b81..54bb9fc 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -772,13 +772,11 @@
 
 void RenderText::SetColor(SkColor value) {
   colors_.SetValue(value);
-  OnTextColorChanged();
   OnLayoutTextAttributeChanged(false);
 }
 
 void RenderText::ApplyColor(SkColor value, const Range& range) {
   colors_.ApplyValue(value, range);
-  OnTextColorChanged();
   OnLayoutTextAttributeChanged(false);
 }
 
@@ -1309,9 +1307,6 @@
   return GetTextIndex(GetGraphemeIteratorAtDisplayTextIndex(index));
 }
 
-void RenderText::OnTextColorChanged() {
-}
-
 void RenderText::OnLayoutTextAttributeChanged(bool text_changed) {
   layout_text_up_to_date_ = false;
 }
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 575c9aa..c9f353d 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -699,9 +699,6 @@
   // Notifies that attributes that affect the display text shape have changed.
   virtual void OnDisplayTextAttributeChanged() = 0;
 
-  // Called when the text color changes.
-  void OnTextColorChanged();
-
   // Ensure the text is laid out, lines are computed, and |lines_| is valid.
   virtual void EnsureLayout() = 0;
 
diff --git a/ui/gfx/render_text_api_fuzzer.cc b/ui/gfx/render_text_api_fuzzer.cc
index 9c3cf07e..0b181d9 100644
--- a/ui/gfx/render_text_api_fuzzer.cc
+++ b/ui/gfx/render_text_api_fuzzer.cc
@@ -69,7 +69,9 @@
   kApplyWeight,
   kSetDirectionalityMode,
   kSetElideBehavior,
-  kMaxValue = kSetElideBehavior
+  kIsGraphemeBoundary,
+  kIndexOfAdjacentGrapheme,
+  kMaxValue = kIndexOfAdjacentGrapheme
 };
 
 gfx::DirectionalityMode ConsumeDirectionalityMode(FuzzedDataProvider* fdp) {
@@ -157,6 +159,16 @@
   }
 }
 
+gfx::LogicalCursorDirection ConsumeLogicalCursorDirection(
+    FuzzedDataProvider* fdp) {
+  switch (fdp->ConsumeIntegralInRange(0, 1)) {
+    case 0:
+      return gfx::CURSOR_BACKWARD;
+    default:
+      return gfx::CURSOR_FORWARD;
+  }
+}
+
 gfx::Font::Weight ConsumeWeight(FuzzedDataProvider* fdp) {
   if (fdp->ConsumeBool())
     return gfx::Font::Weight::BOLD;
@@ -301,6 +313,19 @@
       case RenderTextAPI::kSetElideBehavior:
         render_text->SetElideBehavior(ConsumeElideBehavior(&fdp));
         break;
+
+      case RenderTextAPI::kIsGraphemeBoundary:
+        render_text->IsGraphemeBoundary(fdp.ConsumeIntegralInRange<size_t>(
+            0, render_text->text().length()));
+        break;
+
+      case RenderTextAPI::kIndexOfAdjacentGrapheme: {
+        size_t index = render_text->IndexOfAdjacentGrapheme(
+            fdp.ConsumeIntegralInRange<size_t>(0, render_text->text().length()),
+            ConsumeLogicalCursorDirection(&fdp));
+        bool is_grapheme = render_text->IsGraphemeBoundary(index);
+        DCHECK(is_grapheme);
+      } break;
     }
   }
 
diff --git a/ui/gfx/render_text_harfbuzz.h b/ui/gfx/render_text_harfbuzz.h
index 6d7ff06..acee9fc 100644
--- a/ui/gfx/render_text_harfbuzz.h
+++ b/ui/gfx/render_text_harfbuzz.h
@@ -39,10 +39,6 @@
   explicit TextRunHarfBuzz(const Font& template_font);
   ~TextRunHarfBuzz();
 
-  // Returns the index of the first glyph that corresponds to the character at
-  // |pos|.
-  size_t CharToGlyph(size_t pos) const;
-
   // Returns the corresponding glyph range of the given character range.
   // |range| is in text-space (0 corresponds to |GetDisplayText()[0]|). Returned
   // value is in run-space (0 corresponds to the first glyph in the run).
@@ -131,7 +127,6 @@
     ShapeOutput& operator=(ShapeOutput&& other);
 
     float width = 0.0;
-    float preceding_run_widths = 0.0;
     std::vector<uint16_t> glyphs;
     std::vector<SkPoint> positions;
     // Note that in the context of TextRunHarfBuzz, |glyph_to_char| is indexed
diff --git a/ui/gl/buffer_format_utils.cc b/ui/gl/buffer_format_utils.cc
index ba2e7bc0..92980b2 100644
--- a/ui/gl/buffer_format_utils.cc
+++ b/ui/gl/buffer_format_utils.cc
@@ -28,7 +28,7 @@
       return GL_RGB;
     case gfx::BufferFormat::BGRX_1010102:
       return GL_RGB10_A2_EXT;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return GL_RGB10_A2_EXT;
     case gfx::BufferFormat::BGRA_8888:
       return GL_BGRA_EXT;
@@ -61,7 +61,7 @@
       return GL_UNSIGNED_SHORT_5_6_5;
     case gfx::BufferFormat::RGBA_4444:
       return GL_UNSIGNED_SHORT_4_4_4_4;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::BGRX_1010102:
       return GL_UNSIGNED_INT_2_10_10_10_REV;
     case gfx::BufferFormat::RGBA_F16:
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm
index f5fd7c3..06b5910a 100644
--- a/ui/gl/gl_image_io_surface.mm
+++ b/ui/gl/gl_image_io_surface.mm
@@ -80,7 +80,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::P010:
       NOTREACHED() << gfx::BufferFormatToString(format);
@@ -109,7 +109,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::YUV_420_BIPLANAR:
     case gfx::BufferFormat::P010:
@@ -139,7 +139,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::YUV_420_BIPLANAR:
     case gfx::BufferFormat::P010:
@@ -506,7 +506,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::P010:
       return false;
diff --git a/ui/gl/gl_image_io_surface_egl.mm b/ui/gl/gl_image_io_surface_egl.mm
index fdbcc4a9..5f7bbdf 100644
--- a/ui/gl/gl_image_io_surface_egl.mm
+++ b/ui/gl/gl_image_io_surface_egl.mm
@@ -58,7 +58,7 @@
     case gfx::BufferFormat::BGR_565:
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::YVU_420:
     case gfx::BufferFormat::P010:
       NOTREACHED();
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 85860598..308c32b 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -39,7 +39,7 @@
     case gfx::BufferFormat::RGBA_8888:
     case gfx::BufferFormat::BGRX_8888:
     case gfx::BufferFormat::BGRX_1010102:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::BGRA_8888:
       return base::checked_cast<GLint>(stride) / 4;
     case gfx::BufferFormat::RGBA_F16:
@@ -152,7 +152,7 @@
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBA_8888:
     case gfx::BufferFormat::BGRX_1010102:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::BGRA_8888:
     case gfx::BufferFormat::RGBA_F16:
     case gfx::BufferFormat::R_8:
@@ -286,7 +286,7 @@
 unsigned GLImageMemory::GetDataFormat() {
   switch (format_) {
     case gfx::BufferFormat::RGBX_8888:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return GL_RGBA;
     case gfx::BufferFormat::BGRX_8888:
     case gfx::BufferFormat::BGRX_1010102:
@@ -451,7 +451,7 @@
     case gfx::BufferFormat::RGBA_8888:
     case gfx::BufferFormat::BGRX_8888:
     case gfx::BufferFormat::BGRX_1010102:
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
     case gfx::BufferFormat::BGRA_8888:
     case gfx::BufferFormat::RGBA_F16:
       return true;
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc
index 93e1cdd..20fecf6a 100644
--- a/ui/gl/gl_image_native_pixmap.cc
+++ b/ui/gl/gl_image_native_pixmap.cc
@@ -69,7 +69,7 @@
       return DRM_FORMAT_ARGB8888;
     case gfx::BufferFormat::BGRX_8888:
       return DRM_FORMAT_XRGB8888;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return DRM_FORMAT_XBGR2101010;
     case gfx::BufferFormat::BGRX_1010102:
       return DRM_FORMAT_XRGB2101010;
@@ -103,7 +103,7 @@
     case DRM_FORMAT_XRGB8888:
       return gfx::BufferFormat::BGRX_8888;
     case DRM_FORMAT_XBGR2101010:
-      return gfx::BufferFormat::RGBX_1010102;
+      return gfx::BufferFormat::RGBA_1010102;
     case DRM_FORMAT_RGB565:
       return gfx::BufferFormat::BGR_565;
     case DRM_FORMAT_NV12:
diff --git a/ui/gl/gl_image_native_pixmap_unittest.cc b/ui/gl/gl_image_native_pixmap_unittest.cc
index 8927c385..3c4acdfb 100644
--- a/ui/gl/gl_image_native_pixmap_unittest.cc
+++ b/ui/gl/gl_image_native_pixmap_unittest.cc
@@ -119,7 +119,7 @@
     GLImageNativePixmapTestDelegate<gfx::BufferFormat::RGBA_8888>,
     GLImageNativePixmapTestDelegate<gfx::BufferFormat::BGRX_8888>,
     GLImageNativePixmapTestDelegate<gfx::BufferFormat::BGRA_8888>,
-    GLImageNativePixmapTestDelegate<gfx::BufferFormat::RGBX_1010102>,
+    GLImageNativePixmapTestDelegate<gfx::BufferFormat::RGBA_1010102>,
     GLImageNativePixmapTestDelegate<gfx::BufferFormat::BGRX_1010102>>;
 
 #if !defined(MEMORY_SANITIZER)
diff --git a/ui/gl/gl_image_shared_memory_unittest.cc b/ui/gl/gl_image_shared_memory_unittest.cc
index 4c5681ed..4153c6ba 100644
--- a/ui/gl/gl_image_shared_memory_unittest.cc
+++ b/ui/gl/gl_image_shared_memory_unittest.cc
@@ -56,7 +56,7 @@
     // back the color used to clear the buffer).
     // TODO(mcasas): enable those paltforms https://crbug.com/803451.
     GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRX_1010102>,
-    GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBX_1010102>,
+    GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBA_1010102>,
 #endif
     GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRA_8888>>;
 
diff --git a/ui/gl/test/gl_image_test_support.cc b/ui/gl/test/gl_image_test_support.cc
index 1433af24..3e78492 100644
--- a/ui/gl/test/gl_image_test_support.cc
+++ b/ui/gl/test/gl_image_test_support.cc
@@ -151,7 +151,7 @@
       }
       return;
 
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       DCHECK_EQ(0, plane);
       for (int y = 0; y < height; ++y) {
         for (int x = 0; x < width; ++x) {
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn
index bd18c57..1d7f3aa 100644
--- a/ui/ozone/BUILD.gn
+++ b/ui/ozone/BUILD.gn
@@ -220,7 +220,6 @@
     "//testing/gtest",
     "//ui/gfx:test_support",
     "//ui/gfx/geometry",
-    "//ui/ozone/public/mojom:mojom_trait_unit_test",
     "//ui/platform_window:platform_window",
   ]
 
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/ui/ozone/common/gpu/ozone_gpu_message_params.cc
index 72d40a99..48aaeefd 100644
--- a/ui/ozone/common/gpu/ozone_gpu_message_params.cc
+++ b/ui/ozone/common/gpu/ozone_gpu_message_params.cc
@@ -7,7 +7,6 @@
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/ipc/gfx_param_traits.h"
 #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
 
 namespace ui {
 
@@ -22,22 +21,4 @@
 
 DisplaySnapshot_Params::~DisplaySnapshot_Params() {}
 
-OverlayCheck_Params::OverlayCheck_Params() {}
-
-OverlayCheck_Params::OverlayCheck_Params(
-    const ui::OverlaySurfaceCandidate& candidate)
-    : buffer_size(candidate.buffer_size),
-      transform(candidate.transform),
-      format(candidate.format),
-      display_rect(gfx::ToNearestRect(candidate.display_rect)),
-      crop_rect(candidate.crop_rect),
-      is_opaque(candidate.is_opaque),
-      plane_z_order(candidate.plane_z_order),
-      is_overlay_candidate(candidate.overlay_handled) {}
-
-OverlayCheck_Params::OverlayCheck_Params(const OverlayCheck_Params& other) =
-    default;
-
-OverlayCheck_Params::~OverlayCheck_Params() {}
-
 }  // namespace ui
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.h b/ui/ozone/common/gpu/ozone_gpu_message_params.h
index efd3ceb..5ac2bac 100644
--- a/ui/ozone/common/gpu/ozone_gpu_message_params.h
+++ b/ui/ozone/common/gpu/ozone_gpu_message_params.h
@@ -16,12 +16,8 @@
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/overlay_transform.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
 
 namespace ui {
-class OverlaySurfaceCandidate;
 
 struct DisplayMode_Params {
   DisplayMode_Params();
@@ -62,31 +58,6 @@
   gfx::Size maximum_cursor_size;
 };
 
-struct OverlayCheck_Params {
-  OverlayCheck_Params();
-  OverlayCheck_Params(const OverlaySurfaceCandidate& candidate);
-  OverlayCheck_Params(const OverlayCheck_Params& other);
-  ~OverlayCheck_Params();
-
-  gfx::Size buffer_size;
-  gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE;
-  gfx::BufferFormat format = gfx::BufferFormat::BGRA_8888;
-  gfx::Rect display_rect;
-  gfx::RectF crop_rect;
-  bool is_opaque = false;
-  int plane_z_order = 0;
-  // By default we mark this configuration valid for promoting it to an overlay.
-  bool is_overlay_candidate = true;
-};
-
-struct OverlayCheckReturn_Params {
-  OverlayCheckReturn_Params() = default;
-  OverlayCheckReturn_Params(const OverlayCheckReturn_Params& other) = default;
-  ~OverlayCheckReturn_Params() = default;
-
-  OverlayStatus status = OVERLAY_STATUS_PENDING;
-};
-
 }  // namespace ui
 
 #endif  // UI_OZONE_COMMON_GPU_OZONE_GPU_MESSAGE_PARAMS_H_
diff --git a/ui/ozone/common/gpu/ozone_gpu_messages.h b/ui/ozone/common/gpu/ozone_gpu_messages.h
index fd9813f..ed4053c 100644
--- a/ui/ozone/common/gpu/ozone_gpu_messages.h
+++ b/ui/ozone/common/gpu/ozone_gpu_messages.h
@@ -5,6 +5,7 @@
 // Multiply-included message file, hence no include guard here, but see below
 // for a much smaller-than-usual include guard section.
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 #include <stdint.h>
 
@@ -38,10 +39,6 @@
 IPC_ENUM_TRAITS_MAX_VALUE(display::PanelOrientation,
                           display::PanelOrientation::kLast)
 
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::OverlayTransform, gfx::OVERLAY_TRANSFORM_LAST)
-
-IPC_ENUM_TRAITS_MAX_VALUE(ui::OverlayStatus, ui::OVERLAY_STATUS_LAST)
-
 // clang-format off
 IPC_STRUCT_TRAITS_BEGIN(ui::DisplayMode_Params)
   IPC_STRUCT_TRAITS_MEMBER(size)
@@ -79,22 +76,6 @@
   IPC_STRUCT_TRAITS_MEMBER(g)
   IPC_STRUCT_TRAITS_MEMBER(b)
 IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::OverlayCheck_Params)
-  IPC_STRUCT_TRAITS_MEMBER(buffer_size)
-  IPC_STRUCT_TRAITS_MEMBER(transform)
-  IPC_STRUCT_TRAITS_MEMBER(format)
-  IPC_STRUCT_TRAITS_MEMBER(display_rect)
-  IPC_STRUCT_TRAITS_MEMBER(crop_rect)
-  IPC_STRUCT_TRAITS_MEMBER(is_opaque)
-  IPC_STRUCT_TRAITS_MEMBER(plane_z_order)
-  IPC_STRUCT_TRAITS_MEMBER(is_overlay_candidate)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::OverlayCheckReturn_Params)
-  IPC_STRUCT_TRAITS_MEMBER(status)
-IPC_STRUCT_TRAITS_END()
-
 // clang-format on
 
 //------------------------------------------------------------------------------
@@ -170,10 +151,6 @@
                      std::vector<display::GammaRampRGBEntry>,  // Degamma lut
                      std::vector<display::GammaRampRGBEntry>)  // Gamma lut
 
-IPC_MESSAGE_CONTROL2(OzoneGpuMsg_CheckOverlayCapabilities,
-                     gfx::AcceleratedWidget /* widget */,
-                     std::vector<ui::OverlayCheck_Params> /* overlays */)
-
 //------------------------------------------------------------------------------
 // Browser Messages
 // These messages are from the GPU to the browser process.
@@ -203,10 +180,3 @@
 // Response to OzoneGpuMsg_RelinquishDisplayControl.
 IPC_MESSAGE_CONTROL1(OzoneHostMsg_DisplayControlRelinquished,
                      bool /* success */)
-
-// Response to OzoneGpuMsg_CheckOverlayCapabilities. Returns list of supported
-// params.
-IPC_MESSAGE_CONTROL3(OzoneHostMsg_OverlayCapabilitiesReceived,
-                     gfx::AcceleratedWidget /* widget */,
-                     std::vector<ui::OverlayCheck_Params> /* overlays */,
-                     std::vector<ui::OverlayCheckReturn_Params> /* returns */)
diff --git a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
index 349b610..d94cd66 100644
--- a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
+++ b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -91,7 +91,7 @@
 
 using GLImageScanoutTypeDisabled = testing::Types<
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT,
-                                    gfx::BufferFormat::RGBX_1010102>>;
+                                    gfx::BufferFormat::RGBA_1010102>>;
 
 // This test is disabled since we need mesa support for XR30/XB30 that is not
 // available on many boards yet.
@@ -111,7 +111,7 @@
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
                                     gfx::BufferFormat::BGRA_8888>,
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
-                                    gfx::BufferFormat::RGBX_1010102>,
+                                    gfx::BufferFormat::RGBA_1010102>,
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
                                     gfx::BufferFormat::R_8>,
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
diff --git a/ui/ozone/platform/cast/ozone_platform_cast.cc b/ui/ozone/platform/cast/ozone_platform_cast.cc
index b2e3baa7..ddf85e22 100644
--- a/ui/ozone/platform/cast/ozone_platform_cast.cc
+++ b/ui/ozone/platform/cast/ozone_platform_cast.cc
@@ -124,9 +124,6 @@
     cursor_factory_ = std::make_unique<CursorFactoryOzone>();
     gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
 
-    if (!params.viz_display_compositor)
-      overlay_manager_ = std::make_unique<OverlayManagerCast>();
-
     // Enable dummy software rendering support if GPU process disabled
     // or if we're an audio-only build.
     // Note: switch is kDisableGpu from content/public/common/content_switches.h
@@ -148,9 +145,7 @@
       surface_factory_ = std::make_unique<SurfaceFactoryCast>();
   }
   void InitializeGPU(const InitParams& params) override {
-    if (params.viz_display_compositor) {
-      overlay_manager_ = std::make_unique<OverlayManagerCast>();
-    }
+    overlay_manager_ = std::make_unique<OverlayManagerCast>();
     surface_factory_ =
         std::make_unique<SurfaceFactoryCast>(std::move(egl_platform_));
   }
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index 9766d60..a6e6f71 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -106,8 +106,6 @@
     "host/drm_gpu_platform_support_host.h",
     "host/drm_native_display_delegate.cc",
     "host/drm_native_display_delegate.h",
-    "host/drm_overlay_manager_host.cc",
-    "host/drm_overlay_manager_host.h",
     "host/drm_window_host.cc",
     "host/drm_window_host.h",
     "host/drm_window_host_manager.cc",
diff --git a/ui/ozone/platform/drm/common/drm_overlay_manager.h b/ui/ozone/platform/drm/common/drm_overlay_manager.h
index f748fe4..815d09f 100644
--- a/ui/ozone/platform/drm/common/drm_overlay_manager.h
+++ b/ui/ozone/platform/drm/common/drm_overlay_manager.h
@@ -21,6 +21,8 @@
 // Ozone DRM extension of the OverlayManagerOzone interface. It queries the
 // DrmDevice to see if an overlay configuration will work and keeps an MRU cache
 // of recent configurations.
+// TODO(crbug.com/936425): Move DrmOverlayManager to ui/ozone/platform/drm/gpu/
+// as it's not longer used from ui/ozone/platform/drm/host/.
 class DrmOverlayManager : public OverlayManagerOzone {
  public:
   DrmOverlayManager();
@@ -47,8 +49,8 @@
       gfx::AcceleratedWidget widget) = 0;
 
   // Perform basic validation to see if |candidate| is a valid request.
-  virtual bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
-                                  gfx::AcceleratedWidget widget) const;
+  bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
+                          gfx::AcceleratedWidget widget) const;
 
   // Updates the MRU cache for overlay configuration |candidates| with |status|.
   void UpdateCacheForOverlayCandidates(
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc
index c222c05..698bff9f 100644
--- a/ui/ozone/platform/drm/common/drm_util.cc
+++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -584,7 +584,7 @@
       return DRM_FORMAT_XRGB8888;
     case gfx::BufferFormat::BGRX_1010102:
       return DRM_FORMAT_XRGB2101010;
-    case gfx::BufferFormat::RGBX_1010102:
+    case gfx::BufferFormat::RGBA_1010102:
       return DRM_FORMAT_XBGR2101010;
     case gfx::BufferFormat::BGR_565:
       return DRM_FORMAT_RGB565;
@@ -598,54 +598,4 @@
   }
 }
 
-OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom(
-    const std::vector<OverlayCheck_Params>& params) {
-  OverlaySurfaceCandidateList candidates;
-  for (auto& p : params) {
-    OverlaySurfaceCandidate osc;
-    osc.transform = p.transform;
-    osc.buffer_size = p.buffer_size;
-    osc.format = p.format;
-    osc.display_rect = gfx::RectF(p.display_rect);
-    osc.crop_rect = p.crop_rect;
-    osc.is_opaque = p.is_opaque;
-    osc.plane_z_order = p.plane_z_order;
-    osc.overlay_handled = p.is_overlay_candidate;
-    candidates.push_back(osc);
-  }
-
-  return candidates;
-}
-
-std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate(
-    const OverlaySurfaceCandidateList& candidates) {
-  std::vector<OverlayCheck_Params> overlay_params;
-  for (auto& candidate : candidates) {
-    overlay_params.push_back(OverlayCheck_Params(candidate));
-  }
-
-  return overlay_params;
-}
-
-OverlayStatusList CreateOverlayStatusListFrom(
-    const std::vector<OverlayCheckReturn_Params>& params) {
-  OverlayStatusList returns;
-  for (auto& p : params) {
-    returns.push_back(p.status);
-  }
-
-  return returns;
-}
-
-std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList(
-    const OverlayStatusList& returns) {
-  std::vector<OverlayCheckReturn_Params> params;
-  for (auto& s : returns) {
-    OverlayCheckReturn_Params p;
-    p.status = s;
-    params.push_back(p);
-  }
-  return params;
-}
-
 }  // namespace ui
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h
index 71fb0e0e..4ee6307 100644
--- a/ui/ozone/platform/drm/common/drm_util.h
+++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -114,18 +114,6 @@
 
 bool ModeIsInterlaced(const drmModeModeInfo& mode);
 
-OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom(
-    const std::vector<OverlayCheck_Params>& params);
-
-std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate(
-    const OverlaySurfaceCandidateList& candidates);
-
-OverlayStatusList CreateOverlayStatusListFrom(
-    const std::vector<OverlayCheckReturn_Params>& params);
-
-std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList(
-    const OverlayStatusList& returns);
-
 }  // namespace ui
 
 #endif  // UI_OZONE_PLATFORM_DRM_COMMON_DRM_UTIL_H_
diff --git a/ui/ozone/platform/drm/common/drm_util_unittest.cc b/ui/ozone/platform/drm/common/drm_util_unittest.cc
index c0e59bb..b81f31f 100644
--- a/ui/ozone/platform/drm/common/drm_util_unittest.cc
+++ b/ui/ozone/platform/drm/common/drm_util_unittest.cc
@@ -180,48 +180,6 @@
   EXPECT_EQ(ep, roundtrip_params[2]);
 }
 
-TEST_F(DrmUtilTest, OverlaySurfaceCandidate) {
-  OverlaySurfaceCandidateList input;
-
-  OverlaySurfaceCandidate input_osc;
-  input_osc.transform = gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
-  input_osc.format = gfx::BufferFormat::YUV_420_BIPLANAR;
-  input_osc.buffer_size = gfx::Size(100, 50);
-  input_osc.display_rect = gfx::RectF(1., 2., 3., 4.);
-  input_osc.crop_rect = gfx::RectF(10., 20., 30., 40.);
-  input_osc.clip_rect = gfx::Rect(10, 20, 30, 40);
-  input_osc.is_clipped = true;
-  input_osc.plane_z_order = 42;
-  input_osc.overlay_handled = true;
-
-  input.push_back(input_osc);
-
-  // Roundtrip the conversions.
-  auto output = CreateOverlaySurfaceCandidateListFrom(
-      CreateParamsFromOverlaySurfaceCandidate(input));
-
-  EXPECT_EQ(input.size(), output.size());
-  OverlaySurfaceCandidate output_osc = output[0];
-
-  EXPECT_EQ(input_osc.transform, output_osc.transform);
-  EXPECT_EQ(input_osc.format, output_osc.format);
-  EXPECT_EQ(input_osc.buffer_size, output_osc.buffer_size);
-  EXPECT_EQ(input_osc.display_rect, output_osc.display_rect);
-  EXPECT_EQ(input_osc.crop_rect, output_osc.crop_rect);
-  EXPECT_EQ(input_osc.plane_z_order, output_osc.plane_z_order);
-  EXPECT_EQ(input_osc.overlay_handled, output_osc.overlay_handled);
-
-  EXPECT_FALSE(input < output);
-  EXPECT_FALSE(output < input);
-
-  std::map<OverlaySurfaceCandidateList, int> map;
-  map[input] = 42;
-  const auto& iter = map.find(output);
-
-  EXPECT_NE(map.end(), iter);
-  EXPECT_EQ(42, iter->second);
-}
-
 TEST_F(DrmUtilTest, TestDisplayModesExtraction) {
   // Initialize a list of display modes.
   constexpr size_t kNumModes = 5;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc
index 9f331b9..702d384 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -17,6 +17,7 @@
 #include "ui/display/types/display_mode.h"
 #include "ui/display/types/display_snapshot.h"
 #include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_defines.h"
 #include "ui/gfx/linux/gbm_device.h"
 #include "ui/gfx/presentation_feedback.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
@@ -296,9 +297,7 @@
 void DrmThread::CheckOverlayCapabilities(
     gfx::AcceleratedWidget widget,
     const OverlaySurfaceCandidateList& overlays,
-    base::OnceCallback<void(gfx::AcceleratedWidget,
-                            const OverlaySurfaceCandidateList&,
-                            const OverlayStatusList&)> callback) {
+    OverlayCapabilitiesCallback callback) {
   TRACE_EVENT0("drm,hwoverlays", "DrmThread::CheckOverlayCapabilities");
 
   std::move(callback).Run(
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h
index cb4268a..4fc49cb 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.h
+++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -25,6 +25,7 @@
 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
 #include "ui/ozone/public/mojom/device_cursor.mojom.h"
 #include "ui/ozone/public/mojom/drm_device.mojom.h"
+#include "ui/ozone/public/overlay_surface_candidate.h"
 #include "ui/ozone/public/swap_completion_callback.h"
 
 namespace base {
@@ -62,6 +63,11 @@
                   public ozone::mojom::DeviceCursor,
                   public ozone::mojom::DrmDevice {
  public:
+  using OverlayCapabilitiesCallback =
+      base::OnceCallback<void(gfx::AcceleratedWidget,
+                              const std::vector<OverlaySurfaceCandidate>&,
+                              const std::vector<OverlayStatus>&)>;
+
   DrmThread();
   ~DrmThread() override;
 
@@ -102,6 +108,14 @@
   void AddDrmDeviceReceiver(
       mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
 
+  // Verifies if the display controller can successfully scanout the given set
+  // of OverlaySurfaceCandidates and return the status associated with each
+  // candidate.
+  void CheckOverlayCapabilities(
+      gfx::AcceleratedWidget widget,
+      const std::vector<OverlaySurfaceCandidate>& candidates,
+      OverlayCapabilitiesCallback callback);
+
   // DrmWindowProxy (on GPU thread) is the client for these methods.
   void SchedulePageFlip(gfx::AcceleratedWidget widget,
                         std::vector<DrmOverlayPlane> planes,
@@ -143,12 +157,6 @@
       int64_t display_id,
       const std::vector<display::GammaRampRGBEntry>& degamma_lut,
       const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
-  void CheckOverlayCapabilities(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& overlays,
-      base::OnceCallback<void(gfx::AcceleratedWidget,
-                              const OverlaySurfaceCandidateList&,
-                              const OverlayStatusList&)> callback) override;
   void GetDeviceCursor(
       mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver)
       override;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
index d55cab5..ed27e48 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
@@ -58,8 +58,6 @@
     IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetHDCPState, OnSetHDCPState)
     IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetColorMatrix, OnSetColorMatrix)
     IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetGammaCorrection, OnSetGammaCorrection)
-    IPC_MESSAGE_HANDLER(OzoneGpuMsg_CheckOverlayCapabilities,
-                        OnCheckOverlayCapabilities)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -110,22 +108,6 @@
                      widget, location));
 }
 
-void DrmThreadMessageProxy::OnCheckOverlayCapabilities(
-    gfx::AcceleratedWidget widget,
-    const std::vector<OverlayCheck_Params>& param_overlays) {
-  DCHECK(drm_thread_->IsRunning());
-  auto overlays = CreateOverlaySurfaceCandidateListFrom(param_overlays);
-  auto callback =
-      base::BindOnce(&DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback,
-                     weak_ptr_factory_.GetWeakPtr());
-
-  auto safe_callback = CreateSafeOnceCallback(std::move(callback));
-  drm_thread_->task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&DrmThread::CheckOverlayCapabilities,
-                                base::Unretained(drm_thread_), widget, overlays,
-                                std::move(safe_callback)));
-}
-
 void DrmThreadMessageProxy::OnRefreshNativeDisplays() {
   DCHECK(drm_thread_->IsRunning());
   auto callback =
@@ -253,16 +235,6 @@
                                 degamma_lut, gamma_lut));
 }
 
-void DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback(
-    gfx::AcceleratedWidget widget,
-    const OverlaySurfaceCandidateList& candidates,
-    const OverlayStatusList& returns) const {
-  auto param_overlays = CreateParamsFromOverlaySurfaceCandidate(candidates);
-  auto param_returns = CreateParamsFromOverlayStatusList(returns);
-  sender_->Send(new OzoneHostMsg_OverlayCapabilitiesReceived(
-      widget, param_overlays, param_returns));
-}
-
 void DrmThreadMessageProxy::OnRefreshNativeDisplaysCallback(
     MovableDisplaySnapshots displays) const {
   sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
index b1bdf683..c37d20d9 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
+++ b/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
@@ -15,7 +15,6 @@
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/platform/drm/common/display_types.h"
 #include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
 
 namespace base {
 struct FileDescriptor;
@@ -30,7 +29,6 @@
 namespace ui {
 class DrmThread;
 struct DisplayMode_Params;
-struct OverlayCheck_Params;
 
 class DrmThreadMessageProxy : public IPC::MessageFilter,
                               public InterThreadMessagingProxy {
@@ -57,9 +55,6 @@
                    const gfx::Point& location,
                    int frame_delay_ms);
   void OnCursorMove(gfx::AcceleratedWidget widget, const gfx::Point& location);
-  void OnCheckOverlayCapabilities(
-      gfx::AcceleratedWidget widget,
-      const std::vector<OverlayCheck_Params>& overlays);
 
   // Display related IPC handlers.
   void OnRefreshNativeDisplays();
@@ -80,11 +75,6 @@
       int64_t display_id,
       const std::vector<display::GammaRampRGBEntry>& degamma_lut,
       const std::vector<display::GammaRampRGBEntry>& gamma_lut);
-
-  void OnCheckOverlayCapabilitiesCallback(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& overlays,
-      const OverlayStatusList& returns) const;
   void OnRefreshNativeDisplaysCallback(MovableDisplaySnapshots displays) const;
   void OnConfigureNativeDisplayCallback(int64_t display_id, bool success) const;
   void OnDisableNativeDisplayCallback(int64_t display_id, bool success) const;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
index 4bad08e..d7ffd00 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -150,7 +150,7 @@
 void DrmThreadProxy::CheckOverlayCapabilities(
     gfx::AcceleratedWidget widget,
     const std::vector<OverlaySurfaceCandidate>& candidates,
-    OverlayCapabilitiesCallback callback) {
+    DrmThread::OverlayCapabilitiesCallback callback) {
   DCHECK(drm_thread_.task_runner());
   base::OnceClosure task = base::BindOnce(
       &DrmThread::CheckOverlayCapabilities, base::Unretained(&drm_thread_),
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
index 1327102..f401d326 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
+++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
@@ -26,11 +26,6 @@
 // proxy objects then deal with safely posting the messages to the DRM thread.
 class DrmThreadProxy {
  public:
-  using OverlayCapabilitiesCallback =
-      base::OnceCallback<void(gfx::AcceleratedWidget,
-                              const std::vector<OverlaySurfaceCandidate>&,
-                              const std::vector<OverlayStatus>&)>;
-
   DrmThreadProxy();
   ~DrmThreadProxy();
 
@@ -77,7 +72,7 @@
   void CheckOverlayCapabilities(
       gfx::AcceleratedWidget widget,
       const std::vector<OverlaySurfaceCandidate>& candidates,
-      OverlayCapabilitiesCallback callback);
+      DrmThread::OverlayCapabilitiesCallback callback);
 
   void AddDrmDeviceReceiver(
       mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index b0c588e..78ab9b66 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -15,6 +15,7 @@
 #include "third_party/khronos/EGL/egl.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_defines.h"
 #include "ui/gfx/linux/scoped_gbm_device.h"
 #include "ui/gfx/native_pixmap.h"
 #include "ui/gl/gl_surface_egl.h"
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
index 360f06c..08e62c0 100644
--- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc
+++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -20,7 +20,6 @@
 #include "ui/display/types/display_snapshot.h"
 #include "ui/events/ozone/device/device_event.h"
 #include "ui/events/ozone/device/device_manager.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/host/drm_device_handle.h"
 #include "ui/ozone/platform/drm/host/drm_display_host.h"
@@ -112,11 +111,9 @@
     GpuThreadAdapter* proxy,
     DeviceManager* device_manager,
     OzonePlatform::InitializedHostProperties* host_properties,
-    DrmOverlayManager* overlay_manager,
     InputControllerEvdev* input_controller)
     : proxy_(proxy),
       device_manager_(device_manager),
-      overlay_manager_(overlay_manager),
       input_controller_(input_controller),
       primary_graphics_card_path_(GetPrimaryDisplayCardPath()) {
   {
@@ -400,9 +397,6 @@
   DrmDisplayHost* display = GetDisplay(display_id);
   if (display) {
     display->OnDisplayConfigured(status);
-
-    if (overlay_manager_)
-      overlay_manager_->ResetCache();
   } else {
     LOG(ERROR) << "Couldn't find display with id=" << display_id;
   }
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.h b/ui/ozone/platform/drm/host/drm_display_host_manager.h
index a126bd4..1ded8afe8 100644
--- a/ui/ozone/platform/drm/host/drm_display_host_manager.h
+++ b/ui/ozone/platform/drm/host/drm_display_host_manager.h
@@ -28,7 +28,6 @@
 class DrmDisplayHost;
 class DrmDisplayHostManager;
 class DrmNativeDisplayDelegate;
-class DrmOverlayManager;
 class GpuThreadAdapter;
 
 struct DisplaySnapshot_Params;
@@ -42,7 +41,6 @@
       GpuThreadAdapter* proxy,
       DeviceManager* device_manager,
       OzonePlatform::InitializedHostProperties* host_properties,
-      DrmOverlayManager* overlay_manager,
       InputControllerEvdev* input_controller);
   ~DrmDisplayHostManager() override;
 
@@ -102,8 +100,6 @@
 
   GpuThreadAdapter* const proxy_;                 // Not owned.
   DeviceManager* const device_manager_;           // Not owned.
-  // TODO(crbug.com/936425): Remove after VizDisplayCompositor feature launches.
-  DrmOverlayManager* const overlay_manager_;      // Not owned.
   InputControllerEvdev* const input_controller_;  // Not owned.
 
   DrmNativeDisplayDelegate* delegate_ = nullptr;  // Not owned.
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
index 5dcbf20..7f98586e 100644
--- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
+++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -18,7 +18,6 @@
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/host/drm_cursor.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/gpu_thread_observer.h"
 
 namespace ui {
@@ -167,15 +166,23 @@
 
 void DrmGpuPlatformSupportHost::OnMessageReceived(const IPC::Message& message) {
   DCHECK(ui_runner_);
-  if (ui_runner_->BelongsToCurrentThread()) {
-    if (OnMessageReceivedForDrmDisplayHostManager(message))
-      return;
-    OnMessageReceivedForDrmOverlayManager(message);
-  } else {
+  if (!ui_runner_->BelongsToCurrentThread()) {
     ui_runner_->PostTask(
         FROM_HERE, base::BindOnce(&DrmGpuPlatformSupportHost::OnMessageReceived,
                                   weak_ptr_, message));
+    return;
   }
+
+  IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays,
+                        OnUpdateNativeDisplays)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateReceived, OnHDCPStateReceived)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateUpdated, OnHDCPStateUpdated)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlTaken, OnTakeDisplayControl)
+    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlRelinquished,
+                        OnRelinquishDisplayControl)
+  IPC_END_MESSAGE_MAP()
 }
 
 bool DrmGpuPlatformSupportHost::Send(IPC::Message* message) {
@@ -213,25 +220,6 @@
       std::make_unique<CursorIPC>(send_runner_, send_callback_));
 }
 
-bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmDisplayHostManager(
-    const IPC::Message& message) {
-  bool handled = true;
-
-  IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays,
-                        OnUpdateNativeDisplays)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateReceived, OnHDCPStateReceived)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateUpdated, OnHDCPStateUpdated)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlTaken, OnTakeDisplayControl)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlRelinquished,
-                        OnRelinquishDisplayControl)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-
-  return handled;
-}
-
 void DrmGpuPlatformSupportHost::OnUpdateNativeDisplays(
     const std::vector<DisplaySnapshot_Params>& params) {
   display_manager_->GpuHasUpdatedNativeDisplays(params);
@@ -293,44 +281,6 @@
   return Send(new OzoneGpuMsg_RemoveGraphicsDevice(path));
 }
 
-// Overlays
-void DrmGpuPlatformSupportHost::RegisterHandlerForDrmOverlayManager(
-    DrmOverlayManagerHost* handler) {
-  overlay_manager_ = handler;
-}
-
-void DrmGpuPlatformSupportHost::UnRegisterHandlerForDrmOverlayManager() {
-  overlay_manager_ = nullptr;
-}
-
-bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmOverlayManager(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
-    IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived,
-                        OnOverlayResult)
-    // TODO(rjk): insert the extra
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void DrmGpuPlatformSupportHost::OnOverlayResult(
-    gfx::AcceleratedWidget widget,
-    const std::vector<OverlayCheck_Params>& params,
-    const std::vector<OverlayCheckReturn_Params>& param_returns) {
-  auto candidates = CreateOverlaySurfaceCandidateListFrom(params);
-  auto returns = CreateOverlayStatusListFrom(param_returns);
-  overlay_manager_->GpuSentOverlayResult(widget, candidates, returns);
-}
-
-bool DrmGpuPlatformSupportHost::GpuCheckOverlayCapabilities(
-    gfx::AcceleratedWidget widget,
-    const OverlaySurfaceCandidateList& candidates) {
-  auto params = CreateParamsFromOverlaySurfaceCandidate(candidates);
-  return Send(new OzoneGpuMsg_CheckOverlayCapabilities(widget, params));
-}
-
 // DrmDisplayHost
 bool DrmGpuPlatformSupportHost::GpuConfigureNativeDisplay(
     int64_t display_id,
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
index 4b07ff5..3f58f691 100644
--- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
+++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -24,7 +24,6 @@
 
 class DrmCursor;
 class DrmDisplayHostMananger;
-class DrmOverlayManagerHost;
 class GpuThreadObserver;
 
 class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
@@ -73,17 +72,6 @@
                                       base::ScopedFD fd) override;
   bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
 
-  // Methods needed for DrmOverlayManagerHost.
-  // Methods for DrmOverlayManagerHost.
-  void RegisterHandlerForDrmOverlayManager(
-      DrmOverlayManagerHost* handler) override;
-  void UnRegisterHandlerForDrmOverlayManager() override;
-
-  // Services needed by DrmOverlayManagerHost
-  bool GpuCheckOverlayCapabilities(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& new_params) override;
-
   // Services needed by DrmDisplayHost
   bool GpuConfigureNativeDisplay(int64_t display_id,
                                  const ui::DisplayMode_Params& display_mode,
@@ -107,7 +95,6 @@
 
  private:
   void OnChannelEstablished();
-  bool OnMessageReceivedForDrmDisplayHostManager(const IPC::Message& message);
   void OnUpdateNativeDisplays(
       const std::vector<DisplaySnapshot_Params>& displays);
   void OnDisplayConfigured(int64_t display_id, bool status);
@@ -118,11 +105,6 @@
   void OnTakeDisplayControl(bool status);
   void OnRelinquishDisplayControl(bool status);
 
-  bool OnMessageReceivedForDrmOverlayManager(const IPC::Message& message);
-  void OnOverlayResult(gfx::AcceleratedWidget widget,
-                       const std::vector<OverlayCheck_Params>& params,
-                       const std::vector<OverlayCheckReturn_Params>& returns);
-
   int host_id_ = -1;
   bool channel_established_ = false;
 
@@ -131,7 +113,6 @@
   base::RepeatingCallback<void(IPC::Message*)> send_callback_;
 
   DrmDisplayHostManager* display_manager_;  // Not owned.
-  DrmOverlayManagerHost* overlay_manager_;  // Not owned.
 
   DrmCursor* const cursor_;  // Not owned.
   base::ObserverList<GpuThreadObserver>::Unchecked gpu_thread_observers_;
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc b/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
deleted file mode 100644
index b08f2c9b..0000000
--- a/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
-
-#include <stddef.h>
-
-#include "base/trace_event/trace_event.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/ozone/platform/drm/host/drm_window_host.h"
-#include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace ui {
-
-DrmOverlayManagerHost::DrmOverlayManagerHost(
-    GpuThreadAdapter* proxy,
-    DrmWindowHostManager* window_manager)
-    : proxy_(proxy), window_manager_(window_manager) {
-  proxy_->RegisterHandlerForDrmOverlayManager(this);
-}
-
-DrmOverlayManagerHost::~DrmOverlayManagerHost() {
-  proxy_->UnRegisterHandlerForDrmOverlayManager();
-}
-
-void DrmOverlayManagerHost::GpuSentOverlayResult(
-    gfx::AcceleratedWidget widget,
-    const OverlaySurfaceCandidateList& candidates,
-    const OverlayStatusList& returns) {
-  TRACE_EVENT_ASYNC_END0("hwoverlays",
-                         "DrmOverlayManagerHost::SendOverlayValidationRequest",
-                         this);
-  UpdateCacheForOverlayCandidates(candidates, widget, returns);
-}
-
-void DrmOverlayManagerHost::SendOverlayValidationRequest(
-    const OverlaySurfaceCandidateList& candidates,
-    gfx::AcceleratedWidget widget) {
-  if (!proxy_->IsConnected())
-    return;
-  TRACE_EVENT_ASYNC_BEGIN0(
-      "hwoverlays", "DrmOverlayManagerHost::SendOverlayValidationRequest",
-      this);
-  proxy_->GpuCheckOverlayCapabilities(widget, candidates);
-}
-
-bool DrmOverlayManagerHost::CanHandleCandidate(
-    const OverlaySurfaceCandidate& candidate,
-    gfx::AcceleratedWidget widget) const {
-  if (!DrmOverlayManager::CanHandleCandidate(candidate, widget))
-    return false;
-
-  if (candidate.plane_z_order != 0) {
-    // It is possible that the cc rect we get actually falls off the edge of
-    // the screen. Usually this is prevented via things like status bars
-    // blocking overlaying or cc clipping it, but in case it wasn't properly
-    // clipped (since GL will render this situation fine) just ignore it
-    // here. This should be an extremely rare occurrence.
-    DrmWindowHost* window = window_manager_->GetWindow(widget);
-    if (!window->GetBounds().Contains(
-            gfx::ToNearestRect(candidate.display_rect))) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-}  // namespace ui
diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager_host.h b/ui/ozone/platform/drm/host/drm_overlay_manager_host.h
deleted file mode 100644
index afc35419..0000000
--- a/ui/ozone/platform/drm/host/drm_overlay_manager_host.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
-#define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/macros.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
-#include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
-
-namespace ui {
-class DrmWindowHostManager;
-class OverlaySurfaceCandidate;
-
-// This is an implementation of DrmOverlayManager where the driver is asked
-// about overlay capabilities via IPC. We have no way of querying abstract
-// capabilities, only if a particular configuration is supported or not.
-// Each time we we are asked if a particular configuration is supported, if we
-// have not seen that configuration before, it is IPCed to the GPU via
-// OzoneGpuMsg_CheckOverlayCapabilities, a test commit is then performed and
-// the result is returned in OzoneHostMsg_OverlayCapabilitiesReceived. Testing
-// is asynchronous, until the reply arrives that configuration will be failed.
-//
-// All widgets share a single cache of tested configurations stored in the
-// overlay manager.
-class DrmOverlayManagerHost : public DrmOverlayManager {
- public:
-  DrmOverlayManagerHost(GpuThreadAdapter* proxy,
-                        DrmWindowHostManager* window_manager);
-  ~DrmOverlayManagerHost() override;
-
-  // Communication-free implementations of actions performed in response to
-  // messages from the GPU thread.
-  void GpuSentOverlayResult(gfx::AcceleratedWidget widget,
-                            const OverlaySurfaceCandidateList& params,
-                            const OverlayStatusList& returns);
-
- private:
-  // DrmOverlayManager:
-  void SendOverlayValidationRequest(
-      const OverlaySurfaceCandidateList& candidates,
-      gfx::AcceleratedWidget widget) override;
-  bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
-                          gfx::AcceleratedWidget widget) const override;
-
-  GpuThreadAdapter* const proxy_;               // Not owned.
-  DrmWindowHostManager* const window_manager_;  // Not owned.
-
-  DISALLOW_COPY_AND_ASSIGN(DrmOverlayManagerHost);
-};
-
-}  // namespace ui
-
-#endif  // UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
diff --git a/ui/ozone/platform/drm/host/gpu_thread_adapter.h b/ui/ozone/platform/drm/host/gpu_thread_adapter.h
index 074b826..72d90e0 100644
--- a/ui/ozone/platform/drm/host/gpu_thread_adapter.h
+++ b/ui/ozone/platform/drm/host/gpu_thread_adapter.h
@@ -8,14 +8,13 @@
 #include "base/file_descriptor_posix.h"
 #include "ui/display/types/display_constants.h"
 #include "ui/display/types/gamma_ramp_rgb_entry.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
 
 namespace ui {
 
 class DrmDisplayHostManager;
-class DrmOverlayManagerHost;
 class GpuThreadObserver;
 
 // Provides the services that the various host components need
@@ -43,16 +42,6 @@
                                               base::ScopedFD fd) = 0;
   virtual bool GpuRemoveGraphicsDevice(const base::FilePath& path) = 0;
 
-  // Methods for DrmOverlayManagerHost.
-  virtual void RegisterHandlerForDrmOverlayManager(
-      DrmOverlayManagerHost* handler) = 0;
-  virtual void UnRegisterHandlerForDrmOverlayManager() = 0;
-
-  // Services needed by DrmOverlayManagerHost
-  virtual bool GpuCheckOverlayCapabilities(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& overlays) = 0;
-
   // Services needed by DrmDisplayHost
   virtual bool GpuConfigureNativeDisplay(
       int64_t display_id,
diff --git a/ui/ozone/platform/drm/host/host_drm_device.cc b/ui/ozone/platform/drm/host/host_drm_device.cc
index aaf88ca..58f9008 100644
--- a/ui/ozone/platform/drm/host/host_drm_device.cc
+++ b/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -19,7 +19,6 @@
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/host/drm_device_connector.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/host_cursor_proxy.h"
 
 namespace ui {
@@ -51,10 +50,8 @@
   // DRM thread is broken.
 }
 
-void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager,
-                                    DrmOverlayManagerHost* overlay_manager) {
+void HostDrmDevice::SetDisplayManager(DrmDisplayHostManager* display_manager) {
   display_manager_ = display_manager;
-  overlay_manager_ = overlay_manager;
 }
 
 void HostDrmDevice::AddGpuThreadObserver(GpuThreadObserver* observer) {
@@ -119,35 +116,6 @@
   return true;
 }
 
-// Services needed for DrmOverlayManagerHost.
-void HostDrmDevice::RegisterHandlerForDrmOverlayManager(
-    DrmOverlayManagerHost* handler) {
-  // TODO(rjkroege): Permit overlay manager to run in Viz when the display
-  // compositor runs in Viz.
-  DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
-  overlay_manager_ = handler;
-}
-
-void HostDrmDevice::UnRegisterHandlerForDrmOverlayManager() {
-  DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
-  overlay_manager_ = nullptr;
-}
-
-bool HostDrmDevice::GpuCheckOverlayCapabilities(
-    gfx::AcceleratedWidget widget,
-    const OverlaySurfaceCandidateList& overlays) {
-  DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
-  if (!IsConnected())
-    return false;
-
-  auto callback =
-      base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback, this);
-
-  drm_device_->CheckOverlayCapabilities(widget, overlays, std::move(callback));
-
-  return true;
-}
-
 bool HostDrmDevice::GpuRefreshNativeDisplays() {
   DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
   if (!IsConnected())
@@ -289,13 +257,6 @@
   return true;
 }
 
-void HostDrmDevice::GpuCheckOverlayCapabilitiesCallback(
-    gfx::AcceleratedWidget widget,
-    const OverlaySurfaceCandidateList& overlays,
-    const OverlayStatusList& returns) const {
-  DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
-  overlay_manager_->GpuSentOverlayResult(widget, overlays, returns);
-}
 
 void HostDrmDevice::GpuConfigureNativeDisplayCallback(int64_t display_id,
                                                       bool success) const {
diff --git a/ui/ozone/platform/drm/host/host_drm_device.h b/ui/ozone/platform/drm/host/host_drm_device.h
index 7c8c636..39044532 100644
--- a/ui/ozone/platform/drm/host/host_drm_device.h
+++ b/ui/ozone/platform/drm/host/host_drm_device.h
@@ -28,7 +28,6 @@
 
 namespace ui {
 class DrmDisplayHostManager;
-class DrmOverlayManagerHost;
 class GpuThreadObserver;
 class DrmDeviceConnector;
 class HostCursorProxy;
@@ -40,8 +39,7 @@
  public:
   explicit HostDrmDevice(DrmCursor* cursor);
 
-  void ProvideManagers(DrmDisplayHostManager* display_manager,
-                       DrmOverlayManagerHost* overlay_manager);
+  void SetDisplayManager(DrmDisplayHostManager* display_manager);
 
   void OnGpuServiceLaunchedOnIOThread(
       mojo::PendingRemote<ui::ozone::mojom::DrmDevice> drm_device,
@@ -69,14 +67,6 @@
                                       base::ScopedFD fd) override;
   bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
 
-  // Services needed for DrmOverlayManagerHost.
-  void RegisterHandlerForDrmOverlayManager(
-      DrmOverlayManagerHost* handler) override;
-  void UnRegisterHandlerForDrmOverlayManager() override;
-  bool GpuCheckOverlayCapabilities(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& new_params) override;
-
   // Services needed by DrmDisplayHost
   bool GpuConfigureNativeDisplay(int64_t display_id,
                                  const ui::DisplayMode_Params& display_mode,
@@ -109,11 +99,6 @@
   // TODO(rjkroege): Get rid of the need for this method in a subsequent CL.
   void PollForSingleThreadReady(int previous_delay);
 
-  void GpuCheckOverlayCapabilitiesCallback(
-      gfx::AcceleratedWidget widget,
-      const OverlaySurfaceCandidateList& overlays,
-      const OverlayStatusList& returns) const;
-
   void GpuConfigureNativeDisplayCallback(int64_t display_id,
                                          bool success) const;
 
@@ -135,7 +120,6 @@
   mojo::Remote<ui::ozone::mojom::DrmDevice> drm_device_on_io_thread_;
 
   DrmDisplayHostManager* display_manager_;  // Not owned.
-  DrmOverlayManagerHost* overlay_manager_;  // Not owned.
   DrmCursor* const cursor_;                 // Not owned.
 
   std::unique_ptr<HostCursorProxy> cursor_proxy_;
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc
index 70a1a61a..03f7f08c 100644
--- a/ui/ozone/platform/drm/ozone_platform_gbm.cc
+++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -40,7 +40,6 @@
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
 #include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host.h"
 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
 #include "ui/ozone/platform/drm/host/host_drm_device.h"
@@ -227,23 +226,13 @@
       adapter = gpu_platform_support_host_.get();
     }
 
-    std::unique_ptr<DrmOverlayManagerHost> overlay_manager_host;
-    if (!args.viz_display_compositor) {
-      overlay_manager_host = std::make_unique<DrmOverlayManagerHost>(
-          adapter, window_manager_.get());
-    }
-
     display_manager_ = std::make_unique<DrmDisplayHostManager>(
         adapter, device_manager_.get(), &host_properties_,
-        overlay_manager_host.get(), event_factory_ozone_->input_controller());
+        event_factory_ozone_->input_controller());
     cursor_factory_ozone_ = std::make_unique<BitmapCursorFactoryOzone>();
 
-    if (using_mojo_) {
-      host_drm_device_->ProvideManagers(display_manager_.get(),
-                                        overlay_manager_host.get());
-    }
-
-    overlay_manager_ = std::move(overlay_manager_host);
+    if (using_mojo_)
+      host_drm_device_->SetDisplayManager(display_manager_.get());
   }
 
   void InitializeGPU(const InitParams& args) override {
@@ -268,10 +257,8 @@
       drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp);
     }
 
-    if (args.viz_display_compositor) {
-      overlay_manager_ =
-          std::make_unique<DrmOverlayManagerGpu>(drm_thread_proxy_.get());
-    }
+    overlay_manager_ =
+        std::make_unique<DrmOverlayManagerGpu>(drm_thread_proxy_.get());
 
     // If gpu is in a separate process, rest of the initialization happens after
     // entering the sandbox.
diff --git a/ui/ozone/public/mojom/BUILD.gn b/ui/ozone/public/mojom/BUILD.gn
index 947b207..61637fc 100644
--- a/ui/ozone/public/mojom/BUILD.gn
+++ b/ui/ozone/public/mojom/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [
     "device_cursor.mojom",
     "drm_device.mojom",
-    "overlay_surface_candidate.mojom",
     "scenic_gpu_host.mojom",
     "scenic_gpu_service.mojom",
   ]
@@ -31,33 +30,3 @@
     "//mojo/public/mojom/base",
   ]
 }
-
-source_set("mojom_traits") {
-  sources = [
-    "overlay_surface_candidate_mojom_traits.h",
-  ]
-  deps = [
-    "//ui/gfx/geometry/mojom",
-    "//ui/gfx/mojom",
-  ]
-  public_deps = [
-    ":mojom",
-    ":mojom_shared_cpp_sources",
-    "//mojo/public/cpp/bindings",
-  ]
-}
-
-source_set("mojom_trait_unit_test") {
-  testonly = true
-
-  sources = [
-    "overlay_surface_candidate_mojom_traits_unittest.cc",
-  ]
-
-  deps = [
-    ":mojom",
-    ":mojom_traits",
-    "//testing/gtest",
-    "//ui/gfx/geometry",
-  ]
-}
diff --git a/ui/ozone/public/mojom/drm_device.mojom b/ui/ozone/public/mojom/drm_device.mojom
index 56fdb1d..46a06e8 100644
--- a/ui/ozone/public/mojom/drm_device.mojom
+++ b/ui/ozone/public/mojom/drm_device.mojom
@@ -13,8 +13,6 @@
 import "ui/gfx/geometry/mojom/geometry.mojom";
 import "ui/gfx/mojom/accelerated_widget.mojom";
 import "ui/ozone/public/mojom/device_cursor.mojom";
-import "ui/ozone/public/mojom/overlay_surface_candidate.mojom";
-
 
 // The viz process on CrOS implements the DrmDevice
 // service to let the viz host and clients manage DRM displays.
@@ -78,18 +76,8 @@
                      array<display.mojom.GammaRampRGBEntry> degamma_lut,
                      array<display.mojom.GammaRampRGBEntry> gamma_lut);
 
-  // Verifies if the display controller can successfully scanout the given set
-  // of OverlaySurfaceCandidates and return the status associated with each
-  // candidate.
-  CheckOverlayCapabilities(gfx.mojom.AcceleratedWidget widget,
-      array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates) =>
-          (gfx.mojom.AcceleratedWidget widget,
-          array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates,
-          array<ui.ozone.mojom.OverlayStatus> status);
-
   // Provides a DeviceCursor interface. The provided interface needs to be
   // associated because the AcceleratedWidgets referenced by its methods are
   // registered via CreateWindow() in this interface.
   GetDeviceCursor(pending_associated_receiver<DeviceCursor> cursor);
 };
-
diff --git a/ui/ozone/public/mojom/overlay_surface_candidate.mojom b/ui/ozone/public/mojom/overlay_surface_candidate.mojom
deleted file mode 100644
index 8dd6b7e..0000000
--- a/ui/ozone/public/mojom/overlay_surface_candidate.mojom
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ui.ozone.mojom;
-
-import "ui/gfx/geometry/mojom/geometry.mojom";
-import "ui/gfx/mojom/buffer_types.mojom";
-import "ui/gfx/mojom/overlay_transform.mojom";
-
-// ui::OverlayStatus
-enum OverlayStatus {
-  OVERLAY_STATUS_PENDING,
-  OVERLAY_STATUS_ABLE,
-  OVERLAY_STATUS_NOT,
-};
-
-struct OverlaySurfaceCandidate {
-  // Transformation to apply to layer during composition.
-  gfx.mojom.OverlayTransform transform;
-  // Format of the buffer to composite.
-  gfx.mojom.BufferFormat format;
-  // Size of the buffer, in pixels.
-  gfx.mojom.Size buffer_size;
-  // Rect on the display to position the overlay to. Input rectangle may
-  // not have integer coordinates, but when accepting for overlay, must
-  // be modified by CheckOverlaySupport to output integer values.
-  gfx.mojom.RectF display_rect;
-  // Crop within the buffer to be placed inside |display_rect|.
-  gfx.mojom.RectF crop_rect;
-  // Clip rect in the target content space after composition.
-  gfx.mojom.Rect clip_rect;
-  // If the quad is clipped after composition.
-  bool is_clipped;
-  // If the quad doesn't require blending.
-  bool is_opaque;
-  // Stacking order of the overlay plane relative to the main surface,
-  // which is 0. Signed to allow for "underlays".
- int32 plane_z_order = 0;
-
-  // To be modified by the implementer if this candidate can go into
-  // an overlay.
-  bool overlay_handled;
-};
diff --git a/ui/ozone/public/mojom/overlay_surface_candidate.typemap b/ui/ozone/public/mojom/overlay_surface_candidate.typemap
deleted file mode 100644
index 10d6f6d0..0000000
--- a/ui/ozone/public/mojom/overlay_surface_candidate.typemap
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//ui/ozone/public/mojom/overlay_surface_candidate.mojom"
-public_headers = [ "//ui/ozone/public/overlay_surface_candidate.h" ]
-public_deps = [
-  "//ui/gfx/geometry/mojom:mojom_traits",
-  "//ui/ozone:ozone_base",
-]
-traits_headers =
-    [ "//ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h" ]
-type_mappings = [
-  "ui.ozone.mojom.OverlaySurfaceCandidate=::ui::OverlaySurfaceCandidate",
-  "ui.ozone.mojom.OverlayStatus=::ui::OverlayStatus",
-]
diff --git a/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h b/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h
deleted file mode 100644
index 26fb4334..0000000
--- a/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
-#define UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
-
-#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
-#include "ui/gfx/mojom/buffer_types_mojom_traits.h"
-#include "ui/gfx/mojom/overlay_transform_mojom_traits.h"
-#include "ui/ozone/public/mojom/overlay_surface_candidate.mojom.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<ui::ozone::mojom::OverlayStatus, ui::OverlayStatus> {
-  static ui::ozone::mojom::OverlayStatus ToMojom(ui::OverlayStatus format) {
-    switch (format) {
-      case ui::OverlayStatus::OVERLAY_STATUS_PENDING:
-        return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_PENDING;
-      case ui::OverlayStatus::OVERLAY_STATUS_ABLE:
-        return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_ABLE;
-      case ui::OverlayStatus::OVERLAY_STATUS_NOT:
-        return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT;
-    }
-    NOTREACHED();
-    return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT;
-  }
-
-  static bool FromMojom(ui::ozone::mojom::OverlayStatus input,
-                        ui::OverlayStatus* out) {
-    switch (input) {
-      case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_PENDING:
-        *out = ui::OverlayStatus::OVERLAY_STATUS_PENDING;
-        return true;
-      case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_ABLE:
-        *out = ui::OverlayStatus::OVERLAY_STATUS_ABLE;
-        return true;
-      case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT:
-        *out = ui::OverlayStatus::OVERLAY_STATUS_NOT;
-        return true;
-    }
-    NOTREACHED();
-    return false;
-  }
-};
-
-template <>
-struct StructTraits<ui::ozone::mojom::OverlaySurfaceCandidateDataView,
-                    ui::OverlaySurfaceCandidate> {
-  static const gfx::OverlayTransform& transform(
-      const ui::OverlaySurfaceCandidate& osc) {
-    return osc.transform;
-  }
-
-  static const gfx::BufferFormat& format(
-      const ui::OverlaySurfaceCandidate& osc) {
-    return osc.format;
-  }
-
-  static const gfx::Size& buffer_size(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.buffer_size;
-  }
-
-  static const gfx::RectF& display_rect(
-      const ui::OverlaySurfaceCandidate& osc) {
-    return osc.display_rect;
-  }
-
-  static const gfx::RectF& crop_rect(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.crop_rect;
-  }
-
-  static const gfx::Rect& clip_rect(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.clip_rect;
-  }
-
-  static bool is_clipped(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.is_clipped;
-  }
-
-  static bool is_opaque(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.is_opaque;
-  }
-
-  static int plane_z_order(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.plane_z_order;
-  }
-
-  static bool overlay_handled(const ui::OverlaySurfaceCandidate& osc) {
-    return osc.overlay_handled;
-  }
-
-  static bool Read(ui::ozone::mojom::OverlaySurfaceCandidateDataView data,
-                   ui::OverlaySurfaceCandidate* out) {
-    out->is_clipped = data.is_clipped();
-    out->is_opaque = data.is_opaque();
-    out->plane_z_order = data.plane_z_order();
-    out->overlay_handled = data.overlay_handled();
-    return data.ReadTransform(&out->transform) &&
-           data.ReadFormat(&out->format) &&
-           data.ReadBufferSize(&out->buffer_size) &&
-           data.ReadDisplayRect(&out->display_rect) &&
-           data.ReadCropRect(&out->crop_rect) &&
-           data.ReadClipRect(&out->clip_rect);
-  }
-};
-
-}  // namespace mojo
-
-#endif  // UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
diff --git a/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc b/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc
deleted file mode 100644
index 823a4e5..0000000
--- a/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h"
-
-#include <utility>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/ozone/public/mojom/overlay_surface_candidate.mojom.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace ui {
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, FieldsEqual) {
-  ui::OverlaySurfaceCandidate input;
-
-  input.transform = gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
-  input.format = gfx::BufferFormat::YUV_420_BIPLANAR;
-  input.buffer_size = gfx::Size(6, 7);
-  input.display_rect = gfx::RectF(1., 2., 3., 4.);
-  input.crop_rect = gfx::RectF(10., 20., 30., 40.);
-  input.clip_rect = gfx::Rect(11, 21, 31, 41);
-  input.is_clipped = true;
-  input.is_opaque = true;
-  input.plane_z_order = 42;
-  input.overlay_handled = true;
-
-  ui::OverlaySurfaceCandidate output;
-
-  bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize(
-      ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output);
-
-  EXPECT_TRUE(success);
-
-  EXPECT_EQ(input.transform, output.transform);
-  EXPECT_EQ(input.format, output.format);
-  EXPECT_EQ(input.buffer_size, output.buffer_size);
-  EXPECT_EQ(input.display_rect, output.display_rect);
-  EXPECT_EQ(input.crop_rect, output.crop_rect);
-  EXPECT_EQ(input.clip_rect, output.clip_rect);
-  EXPECT_EQ(input.is_clipped, output.is_clipped);
-  EXPECT_EQ(input.is_opaque, output.is_opaque);
-  EXPECT_EQ(input.plane_z_order, output.plane_z_order);
-  EXPECT_EQ(input.overlay_handled, output.overlay_handled);
-}
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, FalseBools) {
-  ui::OverlaySurfaceCandidate input;
-
-  input.is_clipped = false;
-  input.is_opaque = false;
-  input.overlay_handled = false;
-
-  ui::OverlaySurfaceCandidate output;
-
-  bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize(
-      ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output);
-
-  EXPECT_TRUE(success);
-  EXPECT_EQ(input.is_clipped, output.is_clipped);
-  EXPECT_EQ(input.is_opaque, output.is_opaque);
-  EXPECT_EQ(input.overlay_handled, output.overlay_handled);
-}
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, OverlayStatus) {
-  using OverlayStatusTraits =
-      mojo::EnumTraits<ui::ozone::mojom::OverlayStatus, ui::OverlayStatus>;
-
-  std::vector<OverlayStatus> tests = {OVERLAY_STATUS_PENDING,
-                                      OVERLAY_STATUS_ABLE, OVERLAY_STATUS_NOT};
-
-  for (const OverlayStatus& input : tests) {
-    ui::OverlayStatus output;
-    bool success = OverlayStatusTraits::FromMojom(
-        OverlayStatusTraits::ToMojom(input), &output);
-
-    EXPECT_TRUE(success);
-    EXPECT_EQ(input, output);
-  }
-}
-
-}  // namespace ui
diff --git a/ui/ozone/public/mojom/typemaps.gni b/ui/ozone/public/mojom/typemaps.gni
deleted file mode 100644
index beff1f5..0000000
--- a/ui/ozone/public/mojom/typemaps.gni
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-typemaps = [ "//ui/ozone/public/mojom/overlay_surface_candidate.typemap" ]
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h
index 8024569..cf1e86f6 100644
--- a/ui/ozone/public/ozone_platform.h
+++ b/ui/ozone/public/ozone_platform.h
@@ -78,13 +78,7 @@
     // TODO(crbug.com/806092): Remove after legacy IPC-based Ozone is removed.
     bool using_mojo = false;
 
-    // Setting this to true indicates the display compositor will run in the GPU
-    // process (as part of the viz service). Note this param is currently only
-    // checked in Ozone DRM for overlay support. Other Ozone platforms either
-    // don't need to change anything or assume that VizDisplayCompositor is
-    // always enabled.
-    // TODO(crbug.com/936425): Remove after VizDisplayCompositor feature
-    // launches.
+    // TODO(crbug.com/936425): Not checked, delete when no longer set.
     bool viz_display_compositor = false;
   };
 
diff --git a/ui/strings/translations/ui_strings_hi.xtb b/ui/strings/translations/ui_strings_hi.xtb
index 4ea3d87..2839560 100644
--- a/ui/strings/translations/ui_strings_hi.xtb
+++ b/ui/strings/translations/ui_strings_hi.xtb
@@ -80,7 +80,7 @@
 <translation id="3068711042108640621">शेल्फ़ बाईं ओर है</translation>
 <translation id="3087734570205094154">नीचे</translation>
 <translation id="3126026824346185272">Ctrl</translation>
-<translation id="3157931365184549694">पुनर्स्थापित करें</translation>
+<translation id="3157931365184549694">वापस लाएं</translation>
 <translation id="3183922693828471536">यहां तक स्क्रोल करें</translation>
 <translation id="3234408098842461169">नीचे तीर</translation>
 <translation id="3291688615589870984">{DAYS,plural, =1{1 दिन}one{# दिन}other{# दिन}}</translation>
diff --git a/ui/views/controls/prefix_selector.cc b/ui/views/controls/prefix_selector.cc
index 4d9cde2..44493bec 100644
--- a/ui/views/controls/prefix_selector.cc
+++ b/ui/views/controls/prefix_selector.cc
@@ -177,6 +177,11 @@
     const gfx::Range& range,
     const base::string16& active_composition_text,
     bool is_composition_committed) {}
+
+bool PrefixSelector::GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                                gfx::Rect* selection_bounds) {
+  return false;
+}
 #endif
 
 void PrefixSelector::OnTextInput(const base::string16& text) {
diff --git a/ui/views/controls/prefix_selector.h b/ui/views/controls/prefix_selector.h
index 9f08b202..208fee1 100644
--- a/ui/views/controls/prefix_selector.h
+++ b/ui/views/controls/prefix_selector.h
@@ -83,6 +83,8 @@
 #endif
 
 #if defined(OS_WIN)
+  bool GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                  gfx::Rect* selection_bounds) override;
   void SetActiveCompositionForAccessibility(
       const gfx::Range& range,
       const base::string16& active_composition_text,
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index b3e0046..647f4b5e 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -1820,6 +1820,10 @@
 #endif
 
 #if defined(OS_WIN)
+bool Textfield::GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                           gfx::Rect* selection_bounds) {
+  return false;
+}
 // TODO(https://crbug.com/952355): Implement this method once TSF supports reconversion
 // features on native text fields.
 void Textfield::SetActiveCompositionForAccessibility(
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index 8357ff7..af4ce2d 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -377,6 +377,8 @@
 #endif
 
 #if defined(OS_WIN)
+  bool GetEditContextLayoutBounds(gfx::Rect* control_bounds,
+                                  gfx::Rect* selection_bounds) override;
   void SetActiveCompositionForAccessibility(
       const gfx::Range& range,
       const base::string16& active_composition_text,
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.js
index 782b14c..3b07db4 100644
--- a/ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.js
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.js
@@ -19,7 +19,8 @@
     /** @override */
     getMojoServiceRemote() {
       if (!this.remote_) {
-        this.remote_ = chromeos.cellularSetup.mojom.CellularSetup.getRemote();
+        this.remote_ = chromeos.cellularSetup.mojom.CellularSetup.getRemote(
+            /*useBrowserInterfaceBroker=*/ true);
       }
 
       return this.remote_;
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js
index d8ff3530..8cfa482 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js
@@ -200,14 +200,15 @@
      */
     onWindowContentUpdate_: function() {
       // (scrollHeight - scrollTop) represents the visible height of the
-      // contents, not including scrollbars. Math.ceil() is used to round this
-      // value, since it can be fractional depending on browser zoom and/or
-      // display density.
-      const visibleHeight = Math.ceil(this.scrollHeight - this.scrollTop);
+      // contents, not including scrollbars.
+      const visibleHeight = this.scrollHeight - this.scrollTop;
 
       // If these two heights are equal, the contents are scrolled to the
-      // bottom.
-      this.isScrolledToBottom_ = this.clientHeight === visibleHeight;
+      // bottom. Instead of using equality, we check that the difference is
+      // sufficiently small to account for fractional values due to browser
+      // zoom and/or display density.
+      this.isScrolledToBottom_ =
+          Math.abs(this.clientHeight - visibleHeight) < 1;
     },
 
     /** @private */
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html
index 5d3fc1c9..9c1ffe9 100644
--- a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html
+++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html
@@ -10,22 +10,21 @@
   <template>
     <style include="cr-radio-button-style cr-hidden-style"></style>
 
-    <div
-        aria-checked$="[[getAriaChecked_(checked)]]"
+    <div aria-checked$="[[getAriaChecked_(checked)]]"
         aria-describedby="slotted-content"
         aria-disabled$="[[getAriaDisabled_(disabled)]]"
         aria-labelledby="label"
         class="disc-wrapper"
         id="button"
         role="radio"
-        tabindex="0"
+        tabindex$="[[buttonTabIndex_]]"
         on-keydown="onInputKeydown_">
       <div class="disc-border"></div>
       <div class="disc"></div>
     </div>
 
     <div id="labelWrapper">
-      <span id="label" hidden$="[[!label]]">[[label]]</span>
+      <span id="label" hidden$="[[!label]]" aria-hidden="true">[[label]]</span>
       <span id="slotted-content">
         <slot></slot>
       </span>
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js
index 9cb515f4..9cd2bba 100644
--- a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js
+++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js
@@ -26,6 +26,17 @@
       notify: true,
     },
 
+    /**
+     * Whether the radio button should be focusable or not. Toggling this
+     * property sets the corresponding tabindex of the button itself as well
+     * as any links in the button description.
+     */
+    focusable: {
+      type: Boolean,
+      value: false,
+      observer: 'onFocusableChanged_',
+    },
+
     label: {
       type: String,
       value: '',  // Allows the hidden$= binding to run without being set.
@@ -36,6 +47,15 @@
       notify: true,
       reflectToAttribute: true,
     },
+
+    /**
+     * Holds the tabIndex for the radio button.
+     * @private {number}
+     */
+    buttonTabIndex_: {
+      type: Number,
+      computed: 'getTabIndex_(focusable)',
+    },
   },
 
   listeners: {
@@ -44,10 +64,23 @@
     up: 'hideRipple_',
   },
 
+  focus: function() {
+    this.$.button.focus();
+  },
+
+  /** @private */
+  onFocusableChanged_: function() {
+    const links = this.querySelectorAll('a');
+    links.forEach((link) => {
+      // Remove the tab stop on any links when the row is unchecked. Since the
+      // row is not tabbable, any links within the row should not be either.
+      link.tabIndex = this.checked ? 0 : -1;
+    });
+  },
+
   /** @private */
   onFocus_: function() {
     this.getRipple().showAndHoldDown();
-    this.$.button.focus();
   },
 
   /** @private */
@@ -55,17 +88,31 @@
     this.getRipple().clear();
   },
 
-  /** @private */
+  /**
+   * @return {string}
+   * @private
+   */
   getAriaChecked_: function() {
     return this.checked ? 'true' : 'false';
   },
 
-  /** @private */
+  /**
+   * @return {string}
+   * @private
+   */
   getAriaDisabled_: function() {
     return this.disabled ? 'true' : 'false';
   },
 
   /**
+   * @return {number}
+   * @private
+   */
+  getTabIndex_: function() {
+    return this.focusable ? 0 : -1;
+  },
+
+  /**
    * When shift-tab is pressed, first bring the focus to the host element.
    * This accomplishes 2 things:
    * 1) Host doesn't get focused when the browser moves the focus backward.
diff --git a/ui/webui/resources/cr_elements/cr_radio_group/BUILD.gn b/ui/webui/resources/cr_elements/cr_radio_group/BUILD.gn
index d79a84c..2148e7f 100644
--- a/ui/webui/resources/cr_elements/cr_radio_group/BUILD.gn
+++ b/ui/webui/resources/cr_elements/cr_radio_group/BUILD.gn
@@ -13,6 +13,7 @@
 
 js_library("cr_radio_group") {
   deps = [
+    "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button",
     "//ui/webui/resources/js:event_tracker",
   ]
 }
@@ -43,6 +44,7 @@
   ]
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m",
     "//ui/webui/resources/js:event_tracker.m",
   ]
   extra_deps = [ ":cr_radio_group_module" ]
diff --git a/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.html b/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.html
index 28215247..0e4996e4 100644
--- a/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.html
+++ b/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.html
@@ -1,6 +1,7 @@
 <link rel="import" href="../../html/polymer.html">
 
 <link rel="import" href="../../html/event_tracker.html">
+<link rel="import" href="../cr_radio_button/cr_radio_button.html">
 <link rel="import" href="../shared_vars_css.html">
 
 <dom-module id="cr-radio-group">
diff --git a/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.js b/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.js
index cafed95..dde7691 100644
--- a/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.js
+++ b/ui/webui/resources/cr_elements/cr_radio_group/cr_radio_group.js
@@ -55,7 +55,7 @@
       role: 'radiogroup',
     },
 
-    /** @private {Array<!Element>} */
+    /** @private {Array<!CrRadioButtonElement>} */
     buttons_: null,
 
     /** @private {EventTracker} */
@@ -118,7 +118,7 @@
       }
 
       const radio =
-          this.buttons_.find(radio => radio.getAttribute('tabindex') == '0');
+          this.buttons_.find(radio => this.isButtonEnabledAndSelected_(radio));
       if (radio) {
         radio.focus();
       }
@@ -137,14 +137,14 @@
         return;
       }
 
-      const targetElement = /** @type {!Element} */ (event.target);
+      const targetElement = /** @type {!CrRadioButtonElement} */ (event.target);
       if (!this.buttons_.includes(targetElement)) {
         return;
       }
 
       if (event.key == ' ' || event.key == 'Enter') {
         event.preventDefault();
-        this.select_(/** @type {!Element} */ (event.target));
+        this.select_(/** @type {!CrRadioButtonElement} */ (event.target));
         return;
       }
 
@@ -201,10 +201,10 @@
       if (path.some(target => /^a$/i.test(target.tagName))) {
         return;
       }
-      const target = /** @type {!Element} */ (
+      const target = /** @type {!CrRadioButtonElement} */ (
           path.find(n => this.selectableRegExp_.test(n.tagName)));
       if (target && this.buttons_.includes(target)) {
-        this.select_(/** @type {!Element} */ (target));
+        this.select_(/** @type {!CrRadioButtonElement} */ (target));
       }
     },
 
@@ -228,7 +228,7 @@
     },
 
     /**
-     * @param {!Element} button
+     * @param {!CrRadioButtonElement} button
      * @private
      */
     select_: function(button) {
@@ -242,6 +242,15 @@
       }
     },
 
+    /**
+     * @param {!Element} button
+     * @return {boolean}
+     * @private
+     */
+    isButtonEnabledAndSelected_: function(button) {
+      return !this.disabled && button.checked && isEnabled(button);
+    },
+
     /** @private */
     update_: function() {
       if (!this.buttons_) {
@@ -253,15 +262,19 @@
             radio.name == this.selected;
         const disabled = this.disabled || !isEnabled(radio);
         const canBeFocused = radio.checked && !disabled;
-        noneMadeFocusable &= !canBeFocused;
-        radio.setAttribute('tabindex', canBeFocused ? '0' : '-1');
+        if (canBeFocused) {
+          radio.focusable = true;
+          noneMadeFocusable = false;
+        } else {
+          radio.focusable = false;
+        }
         radio.setAttribute('aria-disabled', `${disabled}`);
       });
       this.setAttribute('aria-disabled', `${this.disabled}`);
       if (noneMadeFocusable && !this.disabled) {
-        const focusable = this.buttons_.find(isEnabled);
-        if (focusable) {
-          focusable.setAttribute('tabindex', '0');
+        const radio = this.buttons_.find(isEnabled);
+        if (radio) {
+          radio.focusable = true;
         }
       }
     },
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn
index 9496d84..af2ee49 100644
--- a/weblayer/BUILD.gn
+++ b/weblayer/BUILD.gn
@@ -184,6 +184,7 @@
     "//cc",
     "//components/crash/content/app",
     "//components/crash/content/browser",
+    "//components/embedder_support:switches",
     "//components/prefs",
     "//components/security_interstitials/content:security_interstitial_page",
     "//components/security_interstitials/content/renderer:security_interstitial_page_controller",
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index 4729a01..13677944 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -12,6 +12,7 @@
 #include "base/path_service.h"
 #include "base/stl_util.h"
 #include "build/build_config.h"
+#include "components/embedder_support/switches.h"
 #include "components/security_interstitials/content/ssl_cert_reporter.h"
 #include "components/security_interstitials/content/ssl_error_navigation_throttle.h"
 #include "components/version_info/version_info.h"
@@ -285,6 +286,11 @@
     return false;
   }
 
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          embedder_support::kDisablePopupBlocking)) {
+    return true;
+  }
+
   // WindowOpenDisposition has a *ton* of types, but the following are really
   // the only ones that should be hit for this code path.
   switch (disposition) {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
index b165c91e..f295b03 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -56,7 +56,10 @@
     // TODO: should there be one tag for all this code?
     private static final String TAG = "WebLayer";
     private static final String PRIVATE_DIRECTORY_SUFFIX = "weblayer";
-    // TODO: Configure this from the client.
+    // Command line flags are only read in debug builds.
+    // WARNING: this file is written to by testing code in chrome (see
+    // "//chrome/test/chromedriver/chrome/device_manager.cc"). If you change this variable, update
+    // "device_manager.cc" too.
     private static final String COMMAND_LINE_FILE = "/data/local/tmp/weblayer-command-line";
 
     private final ProfileManager mProfileManager = new ProfileManager();
@@ -158,11 +161,13 @@
                 "org.chromium.weblayer.ChildProcessService$Sandboxed");
 
         if (!CommandLine.isInitialized()) {
-            // This disk read in the critical path is for development purposes only.
-            // TODO: Move it to debug-only (similar to WebView), or allow clients to configure the
-            // command line.
-            try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
-                CommandLine.initFromFile(COMMAND_LINE_FILE);
+            if (BuildInfo.isDebugAndroid()) {
+                // This disk read in the critical path is for development purposes only.
+                try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
+                    CommandLine.initFromFile(COMMAND_LINE_FILE);
+                }
+            } else {
+                CommandLine.init(null);
             }
         }
 
diff --git a/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
new file mode 100644
index 0000000..ad6db6e
--- /dev/null
+++ b/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
@@ -0,0 +1,158 @@
+// 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 <map>
+
+#include "base/task/post_task.h"
+#include "components/safe_browsing/android/safe_browsing_api_handler.h"
+#include "components/safe_browsing/base_blocking_page.h"
+#include "components/safe_browsing/db/v4_protocol_manager_util.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/interstitial_page.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/tab_impl.h"
+#include "weblayer/public/navigation.h"
+#include "weblayer/public/navigation_controller.h"
+#include "weblayer/public/tab.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/load_completion_observer.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace weblayer {
+
+namespace {
+
+void RunCallbackOnIOThread(
+    std::unique_ptr<safe_browsing::SafeBrowsingApiHandler::URLCheckCallbackMeta>
+        callback,
+    safe_browsing::SBThreatType threat_type,
+    const safe_browsing::ThreatMetadata& metadata) {
+  base::PostTask(FROM_HERE, {content::BrowserThread::IO},
+                 base::BindOnce(std::move(*callback), threat_type, metadata));
+}
+
+}  // namespace
+
+class FakeSafeBrowsingApiHandler
+    : public safe_browsing::SafeBrowsingApiHandler {
+ public:
+  // SafeBrowsingApiHandler
+  std::string GetSafetyNetId() override { return ""; }
+  void StartURLCheck(
+      std::unique_ptr<URLCheckCallbackMeta> callback,
+      const GURL& url,
+      const safe_browsing::SBThreatTypeSet& threat_types) override {
+    RunCallbackOnIOThread(std::move(callback), GetSafeBrowsingRestriction(url),
+                          safe_browsing::ThreatMetadata());
+  }
+  bool StartCSDAllowlistCheck(const GURL& url) override { return false; }
+  bool StartHighConfidenceAllowlistCheck(const GURL& url) override {
+    return false;
+  }
+
+  void AddRestriction(const GURL& url,
+                      const safe_browsing::SBThreatType& threat_type) {
+    restrictions_[url] = threat_type;
+  }
+
+ private:
+  safe_browsing::SBThreatType GetSafeBrowsingRestriction(const GURL& url) {
+    auto restrictions_iter = restrictions_.find(url);
+    if (restrictions_iter == restrictions_.end()) {
+      // if the url is not in restrictions assume it's safe.
+      return safe_browsing::SB_THREAT_TYPE_SAFE;
+    }
+    return restrictions_iter->second;
+  }
+
+  std::map<GURL, safe_browsing::SBThreatType> restrictions_;
+};
+
+class SafeBrowsingBrowserTest : public WebLayerBrowserTest {
+ public:
+  SafeBrowsingBrowserTest() : fake_handler_(new FakeSafeBrowsingApiHandler()) {}
+  ~SafeBrowsingBrowserTest() override = default;
+
+  // WebLayerBrowserTest:
+  void PreRunTestOnMainThread() override {
+    WebLayerBrowserTest::PreRunTestOnMainThread();
+    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");
+  }
+
+  void NavigateWithThreatType(const safe_browsing::SBThreatType& threatType,
+                              bool expect_interstitial) {
+    fake_handler_->AddRestriction(url_, threatType);
+    Navigate(url_, expect_interstitial);
+  }
+
+  void Navigate(const GURL& url, bool expect_interstitial) {
+    LoadCompletionObserver load_observer(shell());
+    shell()->tab()->GetNavigationController()->Navigate(url);
+    load_observer.Wait();
+    EXPECT_EQ(expect_interstitial, HasInterstitial());
+    if (expect_interstitial) {
+      EXPECT_TRUE(GetBaseBlockingPage()->GetHTMLContents().length() > 0);
+    }
+  }
+
+ protected:
+  content::WebContents* GetWebContents() {
+    Tab* tab = shell()->tab();
+    TabImpl* tab_impl = static_cast<TabImpl*>(tab);
+    return tab_impl->web_contents();
+  }
+
+  content::InterstitialPage* GetInterstitialPage() {
+    return GetWebContents()->GetInterstitialPage();
+  }
+
+  safe_browsing::BaseBlockingPage* GetBaseBlockingPage() {
+    return static_cast<safe_browsing::BaseBlockingPage*>(
+        content::InterstitialPage::GetInterstitialPage(GetWebContents())
+            ->GetDelegateForTesting());
+  }
+
+  bool HasInterstitial() { return GetInterstitialPage() != nullptr; }
+  bool HasBaseBlockingPage() { return GetBaseBlockingPage() != nullptr; }
+
+  std::unique_ptr<FakeSafeBrowsingApiHandler> fake_handler_;
+  GURL url_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+                       DoesNotShowInterstitial_NoRestriction) {
+  Navigate(url_, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, DoesNotShowInterstitial_Safe) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Malware) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, true);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, true);
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Billing) {
+  NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, true);
+}
+
+}  // namespace weblayer
\ No newline at end of file
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn
index a80c5ed2..b7dbec3 100644
--- a/weblayer/shell/android/BUILD.gn
+++ b/weblayer/shell/android/BUILD.gn
@@ -159,7 +159,7 @@
     ":weblayer_support_manifest",
     "//android_webview:locale_pak_assets",
     "//android_webview:pak_file_assets",
-    "//android_webview:weblayer_webview_assets",
+    "//android_webview:standalone_webview_assets",
     "//base:base_java",
     "//weblayer:locale_pak_assets",
     "//weblayer/browser/java",
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn
index 4ed2b6d..3e285735 100644
--- a/weblayer/test/BUILD.gn
+++ b/weblayer/test/BUILD.gn
@@ -110,6 +110,7 @@
 
   if (is_android) {
     sources += [
+      "../browser/safe_browsing/safe_browsing_browsertest.cc",
       "../shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc",
     ]
     deps += [
@@ -118,6 +119,8 @@
       "//android_webview:generate_aw_strings_grit",
       "//android_webview:locale_pak_assets",
       "//android_webview:pak_file_assets",
+      "//components/safe_browsing",
+      "//components/safe_browsing/android:safe_browsing_api_handler",
       "//components/viz/service:service_java",
       "//content/public/test/android:android_test_message_pump_support_java",
       "//content/test:android_test_message_pump_support",